Merge "Change storage size before starting test" am: 960a21867c am: ab4ae8b8fb
am: 097af7adc2

Change-Id: Ia2e34139140dec3a5795438db35f795cac075e40
diff --git a/Android.mk b/Android.mk
index 1c4369c..8e1cbf4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,36 +1,41 @@
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := optional
-LOCAL_PRIVILEGED_MODULE := true
+########################
+# Complete DocumentsUI app:
+include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES += guava
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
-        android-support-v4 \
-        android-support-v7-appcompat \
-        android-support-v13 \
-        android-support-design \
-        android-support-transition \
-        android-support-v7-recyclerview
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_JACK_FLAGS := \
-  -D jack.optimization.inner-class.accessors=true
-
-# Only enable asserts on userdebug/eng builds
-ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
-LOCAL_JACK_FLAGS += -D jack.assert.policy=always
-endif
-
 LOCAL_PACKAGE_NAME := DocumentsUI
-LOCAL_CERTIFICATE := platform
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_FULL_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml
 
-include $(BUILD_PACKAGE)
+include $(LOCAL_PATH)/build_apk.mk
+
+########################
+# Minimal DocumentsUI app (supports Scoped Directory Access only):
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+        src/com/android/documentsui/ScopedAccessActivity.java \
+        src/com/android/documentsui/ScopedAccessPackageReceiver.java \
+        src/com/android/documentsui/ScopedAccessProvider.java \
+        src/com/android/documentsui/ScopedAccessMetrics.java \
+        src/com/android/documentsui/archives/Archive.java \
+        src/com/android/documentsui/archives/ArchiveId.java \
+        src/com/android/documentsui/archives/ArchivesProvider.java \
+        src/com/android/documentsui/archives/Loader.java \
+        src/com/android/documentsui/archives/Proxy.java \
+        src/com/android/documentsui/archives/ReadableArchive.java \
+        src/com/android/documentsui/archives/WriteableArchive.java \
+        src/com/android/documentsui/base/Providers.java \
+        src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
+
+LOCAL_PACKAGE_NAME := DocumentsUIMinimal
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/minimal/res
+LOCAL_FULL_MANIFEST_FILE := $(LOCAL_PATH)/minimal/AndroidManifest.xml
+
+include $(LOCAL_PATH)/build_apk.mk
+
+# Include makefiles for tests and libraries under the current path
 include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 716e611..f594660 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,3 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2007-2017 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.
+ */
+-->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.documentsui">
 
@@ -59,7 +77,7 @@
 
         <activity
             android:name=".inspector.InspectorActivity"
-            android:label="@string/menu_inspector"
+            android:label="@string/menu_inspect"
             android:icon="@drawable/launcher_icon"
             android:theme="@style/DocumentsTheme">
         </activity>
@@ -107,7 +125,7 @@
         </activity-alias>
 
         <activity
-            android:name=".OpenExternalDirectoryActivity"
+            android:name=".ScopedAccessActivity"
             android:theme="@android:style/Theme.Translucent.NoTitleBar">
             <intent-filter>
                 <action android:name="android.os.storage.action.OPEN_EXTERNAL_DIRECTORY" />
@@ -116,6 +134,13 @@
         </activity>
 
         <provider
+            android:name=".ScopedAccessProvider"
+            android:authorities="com.android.documentsui.scopedAccess"
+            android:permission="android.permission.MANAGE_SCOPED_ACCESS_DIRECTORY_PERMISSIONS"
+            android:exported="true">
+        </provider>
+
+        <provider
             android:name=".picker.LastAccessedProvider"
             android:authorities="com.android.documentsui.lastAccessed"
             android:exported="false"/>
@@ -153,5 +178,15 @@
             android:exported="false"
             android:process=":com.android.documentsui.services">
         </service>
+
+        <activity
+            android:name=".selection.demo.SelectionDemoActivity"
+            android:label="Selection Demo"
+            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
     </application>
 </manifest>
diff --git a/app-perf-tests/Android.mk b/app-perf-tests/Android.mk
index 3f6dd97..4db20a7 100644
--- a/app-perf-tests/Android.mk
+++ b/app-perf-tests/Android.mk
@@ -6,12 +6,11 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_STATIC_ANDROID_LIBRARIES := android-support-v4
 LOCAL_STATIC_JAVA_LIBRARIES := \
     mockito-target \
-    ub-uiautomator \
-    legacy-android-test
+    ub-uiautomator
 
 LOCAL_USE_AAPT2 := true
 LOCAL_PACKAGE_NAME := DocumentsUIAppPerfTests
diff --git a/build_apk.mk b/build_apk.mk
new file mode 100644
index 0000000..c09517f
--- /dev/null
+++ b/build_apk.mk
@@ -0,0 +1,28 @@
+LOCAL_MODULE_TAGS := optional
+LOCAL_PRIVILEGED_MODULE := true
+
+LOCAL_STATIC_JAVA_LIBRARIES += guava
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+        android-support-core-ui \
+        android-support-v4 \
+        android-support-v7-appcompat \
+        android-support-v13 \
+        android-support-design \
+        android-support-transition \
+        android-support-v7-recyclerview
+
+LOCAL_USE_AAPT2 := true
+
+LOCAL_JACK_FLAGS := \
+  -D jack.optimization.inner-class.accessors=true
+
+# Only enable asserts on userdebug/eng builds
+ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
+LOCAL_JACK_FLAGS += -D jack.assert.policy=always
+endif
+
+LOCAL_CERTIFICATE := platform
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
diff --git a/minimal/AndroidManifest.xml b/minimal/AndroidManifest.xml
new file mode 100644
index 0000000..fd12939
--- /dev/null
+++ b/minimal/AndroidManifest.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2007-2017 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.documentsui">
+
+    <uses-permission android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS" />
+    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
+    <uses-permission android:name="android.permission.CACHE_CONTENT" />
+
+    <!-- This is a minimal version of the DocumentsUI app supporting ScopedDirectoryAccess
+         only. It is part of the Android TV build. -->
+    <application
+        android:label="@string/app_label"
+        android:icon="@drawable/app_icon"
+        android:supportsRtl="true"
+        android:allowBackup="false"
+        android:fullBackupOnly="false">
+
+        <activity
+            android:name=".ScopedAccessActivity"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.os.storage.action.OPEN_EXTERNAL_DIRECTORY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <receiver android:name=".ScopedAccessPackageReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
+                <action android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
+                <data android:scheme="package" />
+            </intent-filter>
+        </receiver>
+
+        <provider
+            android:name=".ScopedAccessProvider"
+            android:authorities="com.android.documentsui.scopedAccess"
+            android:permission="android.permission.MANAGE_SCOPED_ACCESS_DIRECTORY_PERMISSIONS"
+            android:exported="true">
+        </provider>
+
+    </application>
+</manifest>
diff --git a/minimal/res/layout/dialog_open_scoped_directory.xml b/minimal/res/layout/dialog_open_scoped_directory.xml
new file mode 100644
index 0000000..cb39206
--- /dev/null
+++ b/minimal/res/layout/dialog_open_scoped_directory.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:theme="@style/Theme.AppCompat.Light.Dialog.Alert"
+    android:orientation="vertical"
+    android:paddingEnd="24dp"
+    android:paddingStart="24dp" >
+
+    <TextView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/message"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingEnd="24dp"
+        android:paddingStart="32dp"
+        android:paddingTop="24dp">
+    </TextView>
+
+    <CheckBox
+        android:id="@+id/do_not_ask_checkbox"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dip"
+        android:text="@string/never_ask_again"
+        android:textColor="?android:attr/textColorSecondary"
+        android:visibility="gone" />
+</LinearLayout>
diff --git a/minimal/res/mipmap-anydpi/ic_app_icon.xml b/minimal/res/mipmap-anydpi/ic_app_icon.xml
new file mode 100644
index 0000000..cd4fa58
--- /dev/null
+++ b/minimal/res/mipmap-anydpi/ic_app_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/app_icon_background"/>
+    <foreground android:drawable="@mipmap/ic_launcher_icon_foreground"/>
+</adaptive-icon>
diff --git a/minimal/res/mipmap-hdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-hdpi/ic_launcher_icon_foreground.png
new file mode 100644
index 0000000..992c44e
--- /dev/null
+++ b/minimal/res/mipmap-hdpi/ic_launcher_icon_foreground.png
Binary files differ
diff --git a/minimal/res/mipmap-mdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-mdpi/ic_launcher_icon_foreground.png
new file mode 100644
index 0000000..4639ff0
--- /dev/null
+++ b/minimal/res/mipmap-mdpi/ic_launcher_icon_foreground.png
Binary files differ
diff --git a/minimal/res/mipmap-xhdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-xhdpi/ic_launcher_icon_foreground.png
new file mode 100644
index 0000000..b992944
--- /dev/null
+++ b/minimal/res/mipmap-xhdpi/ic_launcher_icon_foreground.png
Binary files differ
diff --git a/minimal/res/mipmap-xxhdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-xxhdpi/ic_launcher_icon_foreground.png
new file mode 100644
index 0000000..ae44b2f
--- /dev/null
+++ b/minimal/res/mipmap-xxhdpi/ic_launcher_icon_foreground.png
Binary files differ
diff --git a/minimal/res/mipmap-xxxhdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-xxxhdpi/ic_launcher_icon_foreground.png
new file mode 100644
index 0000000..85150eb
--- /dev/null
+++ b/minimal/res/mipmap-xxxhdpi/ic_launcher_icon_foreground.png
Binary files differ
diff --git a/minimal/res/values/colors.xml b/minimal/res/values/colors.xml
new file mode 100644
index 0000000..61a8150
--- /dev/null
+++ b/minimal/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<resources>
+    <color name="app_icon_background">#ff4688f2</color>
+</resources>
diff --git a/minimal/res/values/drawables.xml b/minimal/res/values/drawables.xml
new file mode 100644
index 0000000..2e5e77d
--- /dev/null
+++ b/minimal/res/values/drawables.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<resources>
+    <item name="app_icon" type="drawable">@mipmap/ic_app_icon</item>
+    <item name="launcher_icon" type="drawable">@mipmap/ic_app_icon</item>
+</resources>
diff --git a/minimal/res/values/strings.xml b/minimal/res/values/strings.xml
new file mode 100644
index 0000000..bcffd6b
--- /dev/null
+++ b/minimal/res/values/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Title of the Files application [CHAR LIMIT=32] -->
+    <string name="files_label">Files</string>
+
+    <!-- Title of the documents application [CHAR LIMIT=32] -->
+    <string name="app_label">@string/files_label</string>
+
+    <!-- Title of the documents application [CHAR LIMIT=32] -->
+    <string name="launcher_label">@string/files_label</string>
+
+    <!-- Text in an alert dialog asking user to grant app access to a given directory in an external storage volume -->
+    <string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
+        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory on
+        <xliff:g id="storage" example="SD Card"><i>^3</i></xliff:g>?</string>
+    <!-- Text in an alert dialog asking user to grant app access to a given directory in the internal storage -->
+    <string name="open_external_dialog_request_primary_volume">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
+        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory?</string>
+    <!-- Text in an alert dialog asking user to grant app access to all data in an external storage volume -->
+    <string name="open_external_dialog_root_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
+        access to your data, including photos and videos, on <xliff:g id="storage" example="SD Card"><i>^2</i></xliff:g>?</string>
+    <!-- Checkbox that allows user to not be questioned about the directory access request again -->
+    <string name="never_ask_again">Don\'t ask again</string>
+    <!-- Text in the button asking user to allow access to a given directory. -->
+    <string name="allow">Allow</string>
+    <!-- Text in the button asking user to deny access to a given directory. -->
+    <string name="deny">Deny</string>
+
+    <!-- Error message shown when an archive fails to load -->
+    <string name="archive_loading_failed">Unable to open archive for browsing. File is either corrupt, or an unsupported format.</string>
+
+</resources>
diff --git a/perf-tests/Android.mk b/perf-tests/Android.mk
index ac5537a..0f46966 100644
--- a/perf-tests/Android.mk
+++ b/perf-tests/Android.mk
@@ -8,14 +8,13 @@
     $(call all-java-files-under, ../tests/common/com/android/documentsui) \
     ../tests/functional/com/android/documentsui/ActivityTest.java
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 LOCAL_STATIC_ANDROID_LIBRARIES := android-support-v4
 LOCAL_STATIC_JAVA_LIBRARIES := \
     mockito-target \
     ub-uiautomator \
     ub-janktesthelper \
-    espresso-core \
-    legacy-android-test
+    espresso-core
 
 LOCAL_USE_AAPT2 := true
 LOCAL_PACKAGE_NAME := DocumentsUIPerfTests
diff --git a/res/color/selection_demo_item_selector.xml b/res/color/selection_demo_item_selector.xml
new file mode 100644
index 0000000..bd87b4c
--- /dev/null
+++ b/res/color/selection_demo_item_selector.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_activated="true"
+        android:color="?android:attr/colorForeground"
+        />
+    <item
+        android:state_activated="false"
+        android:color="?android:attr/colorForeground"
+        android:alpha=".3"
+        />
+</selector>
diff --git a/res/drawable-hdpi/ic_menu_share_alpha.png b/res/drawable-hdpi/ic_menu_share_am_alpha.png
similarity index 100%
rename from res/drawable-hdpi/ic_menu_share_alpha.png
rename to res/drawable-hdpi/ic_menu_share_am_alpha.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_share_alpha.png b/res/drawable-mdpi/ic_menu_share_am_alpha.png
similarity index 100%
rename from res/drawable-mdpi/ic_menu_share_alpha.png
rename to res/drawable-mdpi/ic_menu_share_am_alpha.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_share_alpha.png b/res/drawable-xhdpi/ic_menu_share_am_alpha.png
similarity index 100%
rename from res/drawable-xhdpi/ic_menu_share_alpha.png
rename to res/drawable-xhdpi/ic_menu_share_am_alpha.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_share_alpha.png b/res/drawable-xxhdpi/ic_menu_share_am_alpha.png
similarity index 100%
rename from res/drawable-xxhdpi/ic_menu_share_alpha.png
rename to res/drawable-xxhdpi/ic_menu_share_am_alpha.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_share_alpha.png b/res/drawable-xxxhdpi/ic_menu_share_am_alpha.png
similarity index 100%
rename from res/drawable-xxxhdpi/ic_menu_share_alpha.png
rename to res/drawable-xxxhdpi/ic_menu_share_am_alpha.png
Binary files differ
diff --git a/res/drawable/ic_menu_share.xml b/res/drawable/ic_menu_share.xml
index 927e7d3..d4a92c5 100644
--- a/res/drawable/ic_menu_share.xml
+++ b/res/drawable/ic_menu_share.xml
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_share_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+    android:src="@drawable/ic_menu_share_am_alpha"
+    android:tint="?android:attr/colorControlNormal"
+    android:autoMirrored="true" />
diff --git a/res/drawable/inspector_separator.xml b/res/drawable/inspector_separator.xml
new file mode 100644
index 0000000..6a35283
--- /dev/null
+++ b/res/drawable/inspector_separator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetTop="10dp"
+    android:insetBottom="10dp" >
+    <shape xmlns:android="http://schemas.android.com/apk/res/android">
+        <size android:height="1dp"/>
+        <solid android:color="@color/inspector_section_divider"/>
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/res/drawable/selection_demo_band_overlay.xml b/res/drawable/selection_demo_band_overlay.xml
new file mode 100644
index 0000000..adf2b27
--- /dev/null
+++ b/res/drawable/selection_demo_band_overlay.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+    <solid android:color="#339999ff" />
+    <stroke android:width="1dp" android:color="#44000000" />
+</shape>
diff --git a/res/drawable/selection_demo_item_background.xml b/res/drawable/selection_demo_item_background.xml
new file mode 100644
index 0000000..de5c142
--- /dev/null
+++ b/res/drawable/selection_demo_item_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_activated="true">
+        <color android:color="?android:attr/colorControlHighlight"></color>
+    </item>
+</selector>
diff --git a/res/layout/inspector_action_view.xml b/res/layout/inspector_action_view.xml
index 91418ae..4226383 100644
--- a/res/layout/inspector_action_view.xml
+++ b/res/layout/inspector_action_view.xml
@@ -23,8 +23,8 @@
 
     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/default_app_info"
-	    android:paddingLeft="16dp"
-	    android:paddingRight="16dp"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:paddingBottom="10dp"
@@ -33,12 +33,13 @@
         <ImageView
             android:id="@+id/app_icon"
             android:paddingLeft="5dp"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
+            android:layout_width="50dp"
+            android:layout_height="50dp" />
 
         <TextView
             android:id="@+id/app_name"
             android:paddingLeft="16dp"
+            android:paddingBottom="10dp"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_toRightOf="@id/app_icon"
@@ -46,8 +47,8 @@
 
         <ImageButton
             android:id="@+id/inspector_action_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="50dp"
+            android:layout_height="50dp"
             android:layout_alignParentRight="true"
             android:layout_centerVertical="true"
             android:background="@null"/>
diff --git a/res/layout/document_inspector_activity.xml b/res/layout/inspector_activity.xml
similarity index 96%
rename from res/layout/document_inspector_activity.xml
rename to res/layout/inspector_activity.xml
index 65361de..f48bc92 100644
--- a/res/layout/document_inspector_activity.xml
+++ b/res/layout/inspector_activity.xml
@@ -21,7 +21,7 @@
 
     <Toolbar
         android:id="@+id/toolbar"
-        android:title="Properties"
+        android:title="@string/inspector_title"
         android:layout_width="match_parent"
         android:layout_height="?android:attr/actionBarSize"
         android:background="?android:attr/colorPrimary"
diff --git a/res/layout/document_inspector_fragment.xml b/res/layout/inspector_fragment.xml
similarity index 89%
rename from res/layout/document_inspector_fragment.xml
rename to res/layout/inspector_fragment.xml
index 5edb5e0..24f0fdb 100644
--- a/res/layout/document_inspector_fragment.xml
+++ b/res/layout/inspector_fragment.xml
@@ -37,8 +37,13 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>
 
+        <com.android.documentsui.inspector.MediaView
+            android:id="@+id/inspector_media_view"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
         <com.android.documentsui.inspector.actions.ActionView
-            android:paddingTop="10dp"
             android:id="@+id/inspector_show_in_provider_view"
             android:orientation="vertical"
             android:layout_width="match_parent"
@@ -46,7 +51,6 @@
             android:visibility="gone"/>
 
         <com.android.documentsui.inspector.actions.ActionView
-            android:paddingTop="10dp"
             android:id="@+id/inspector_app_defaults_view"
             android:orientation="vertical"
             android:layout_width="match_parent"
@@ -58,6 +62,8 @@
             android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:paddingTop="20dp"
             android:visibility="gone" />
+
     </LinearLayout>
 </ScrollView>
diff --git a/res/layout/inspector_header.xml b/res/layout/inspector_header.xml
index e293c12..d621801 100644
--- a/res/layout/inspector_header.xml
+++ b/res/layout/inspector_header.xml
@@ -23,15 +23,22 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:alpha="0.0"
-        android:background="@android:color/black" />
+        android:background="@android:color/white" />
 
     <TextView
         android:id="@+id/inspector_file_title"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:textSize="20dp"
-        android:layout_alignBottom="@+id/inspector_thumbnail"
-        android:paddingBottom="20dp"
-        android:paddingLeft="18dp"
-        android:textColor="@android:color/white" />
-</RelativeLayout>
\ No newline at end of file
+        android:textSize="20sp"
+        android:paddingTop="5dp"
+        android:paddingBottom="5dp"
+        android:paddingStart="16dp"
+        android:paddingEnd="16dp"
+        android:textColor="@android:color/white"
+        android:layout_gravity="center_vertical"
+        android:background="@color/inspector_title_background"
+        android:textIsSelectable="true"
+        android:textAlignment="viewStart"
+        android:layout_alignBottom="@+id/inspector_thumbnail" />
+
+</RelativeLayout>
diff --git a/res/layout/inspector_section_title.xml b/res/layout/inspector_section_title.xml
index 2804811..33889a8 100644
--- a/res/layout/inspector_section_title.xml
+++ b/res/layout/inspector_section_title.xml
@@ -14,16 +14,26 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:paddingTop="10dp"
-    android:paddingBottom="10dp"
-    android:paddingLeft="16dp"
-    android:layout_gravity="center_vertical"
-    android:fontFamily="sans-serif-medium"
-    android:textSize="14sp"
-    android:textColor="@color/inspector_section_title">
+    android:orientation="vertical"
+    android:divider="@drawable/inspector_separator"
+    android:showDividers="beginning"
+    android:paddingStart="10dp"
+    android:paddingEnd="10dp">
 
-</TextView>
+    <TextView
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:id="@+id/inspector_header_title"
+        android:paddingStart="6dp"
+        android:paddingEnd="6dp"
+        android:paddingTop="5dp"
+        android:paddingBottom="5dp"
+        android:layout_gravity="center_vertical"
+        android:fontFamily="sans-serif-medium"
+        android:textSize="15sp"
+        android:textAlignment="viewStart"
+        android:textColor="@color/inspector_section_title"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/selection_demo_layout.xml b/res/layout/selection_demo_layout.xml
new file mode 100644
index 0000000..c4ed360
--- /dev/null
+++ b/res/layout/selection_demo_layout.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+       android:layout_width="match_parent"
+       android:layout_height="match_parent"
+       android:orientation="vertical">
+
+  <android.support.v7.widget.Toolbar
+     android:id="@+id/toolbar"
+     android:layout_width="match_parent"
+     android:layout_height="?attr/actionBarSize"
+     android:background="?attr/colorPrimary"
+     android:elevation="4dp"
+     android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
+     />
+
+  <android.support.v7.widget.RecyclerView
+      android:id="@+id/list"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:paddingStart="0dp"
+      android:paddingEnd="0dp"
+      android:paddingTop="5dp"
+      android:paddingBottom="5dp"
+      android:clipToPadding="false"
+      android:scrollbars="none"
+      android:drawSelectorOnTop="true"
+      />
+
+</LinearLayout>
diff --git a/res/layout/selection_demo_list_item.xml b/res/layout/selection_demo_list_item.xml
new file mode 100644
index 0000000..0d4b718
--- /dev/null
+++ b/res/layout/selection_demo_list_item.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:paddingStart="10dp"
+    android:paddingEnd="10dp"
+    android:paddingTop="5dp"
+    android:paddingBottom="5dp"
+    android:layout_height="50dp">
+  <LinearLayout
+      android:id="@+id/container"
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:layout_height="match_parent"
+      android:layout_width="match_parent"
+      android:background="@drawable/selection_demo_item_background">
+      <TextView
+          android:id="@+id/selector"
+          android:textSize="20sp"
+          android:textStyle="bold"
+          android:gravity="center"
+          android:layout_height="match_parent"
+          android:layout_width="40dp"
+          android:textColor="@color/selection_demo_item_selector"
+          android:pointerIcon="hand"
+          android:text="✕">
+      </TextView>
+      <TextView
+          android:id="@+id/label"
+          android:textSize="20sp"
+          android:textStyle="bold"
+          android:gravity="center_vertical"
+          android:paddingStart="10dp"
+          android:paddingEnd="10dp"
+          android:layout_height="match_parent"
+          android:layout_width="match_parent">
+      </TextView>
+  </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/table_key_value_row.xml b/res/layout/table_key_value_row.xml
index 2bc8cf6..b45cda4 100644
--- a/res/layout/table_key_value_row.xml
+++ b/res/layout/table_key_value_row.xml
@@ -21,15 +21,18 @@
     android:layout_height="match_parent"
     android:paddingTop="10dp"
     android:paddingBottom="10dp"
-    android:paddingLeft="16dp">
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp">
 
     <TextView
         android:id="@+id/table_row_key"
         android:layout_height="wrap_content"
         android:layout_width="0dp"
         android:layout_weight="1"
+        android:paddingEnd="5dp"
         android:textColor="@android:color/black"
-        android:textSize="14dp">
+        android:textSize="14sp"
+        android:textAlignment="viewStart">
     </TextView>
 
     <TextView
@@ -38,7 +41,9 @@
         android:layout_width="0dp"
         android:layout_weight="1"
         android:textColor="@color/inspector_value"
-        android:textSize="14dp">
+        android:textSize="14sp"
+        android:textIsSelectable="true"
+        android:textAlignment="viewStart">
     </TextView>
 
 </com.android.documentsui.inspector.KeyValueRow>
diff --git a/res/menu/action_mode_menu.xml b/res/menu/action_mode_menu.xml
index ba23816..1952285 100644
--- a/res/menu/action_mode_menu.xml
+++ b/res/menu/action_mode_menu.xml
@@ -63,8 +63,8 @@
         android:showAsAction="never"
         android:visible="false" />
     <item
-        android:id="@+id/action_menu_inspector"
-        android:title="@string/menu_inspector"
+        android:id="@+id/action_menu_inspect"
+        android:title="@string/menu_inspect"
         android:showAsAction="never"
         android:visible="false" />
     <item
diff --git a/res/menu/activity.xml b/res/menu/activity.xml
index ce51e75..0c1e68c 100644
--- a/res/menu/activity.xml
+++ b/res/menu/activity.xml
@@ -77,5 +77,10 @@
             android:title="@string/menu_settings"
             android:showAsAction="never"
             android:visible="false" />
+       <item
+           android:id="@+id/option_menu_inspect"
+           android:title="@string/menu_inspect"
+           android:showAsAction="never"
+           android:visible="false" />
     </group>
 </menu>
diff --git a/res/menu/container_context_menu.xml b/res/menu/container_context_menu.xml
index 08b0de8..2f70d82 100644
--- a/res/menu/container_context_menu.xml
+++ b/res/menu/container_context_menu.xml
@@ -35,4 +35,10 @@
             android:id="@+id/dir_menu_select_all"
             android:title="@string/menu_select_all" />
     </group>
+    <group
+        android:id="@+id/menu_extras_group">
+        <item
+            android:id="@+id/dir_menu_inspect"
+            android:title="@string/menu_inspect" />
+    </group>
 </menu>
\ No newline at end of file
diff --git a/res/menu/dir_context_menu.xml b/res/menu/dir_context_menu.xml
index 2950b53..383841a 100644
--- a/res/menu/dir_context_menu.xml
+++ b/res/menu/dir_context_menu.xml
@@ -47,4 +47,10 @@
             android:id="@+id/dir_menu_delete"
             android:title="@string/menu_delete" />
     </group>
+    <group
+        android:id="@+id/menu_extras_group">
+        <item
+            android:id="@+id/dir_menu_inspect"
+            android:title="@string/menu_inspect" />
+    </group>
 </menu>
diff --git a/res/menu/file_context_menu.xml b/res/menu/file_context_menu.xml
index 325bed9..9e786f1 100644
--- a/res/menu/file_context_menu.xml
+++ b/res/menu/file_context_menu.xml
@@ -50,7 +50,10 @@
             android:title="@string/menu_delete" />
     </group>
     <group
-        android:id="@+id/menu_settings_group">
+        android:id="@+id/menu_extras_group">
+        <item
+            android:id="@+id/dir_menu_inspect"
+            android:title="@string/menu_inspect" />
         <item
             android:id="@+id/dir_menu_view_in_owner"
             android:title="@string/menu_view_in_owner" />
diff --git a/res/menu/mixed_context_menu.xml b/res/menu/mixed_context_menu.xml
index aa6d7f5..cb6b4fd 100644
--- a/res/menu/mixed_context_menu.xml
+++ b/res/menu/mixed_context_menu.xml
@@ -34,4 +34,10 @@
             android:id="@+id/dir_menu_delete"
             android:title="@string/menu_delete" />
     </group>
+    <group
+        android:id="@+id/menu_extras_group">
+        <item
+            android:id="@+id/dir_menu_inspect"
+            android:title="@string/menu_inspect" />
+    </group>
 </menu>
\ No newline at end of file
diff --git a/res/menu/selection_demo_actions.xml b/res/menu/selection_demo_actions.xml
new file mode 100644
index 0000000..e07c06b
--- /dev/null
+++ b/res/menu/selection_demo_actions.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+   <item
+       android:id="@+id/option_menu_add_column"
+       android:title="Add column"
+       android:showAsAction="always" />
+   <item
+       android:id="@+id/option_menu_remove_column"
+       android:title="Remove column"
+       android:showAsAction="always" />
+</menu>
diff --git a/res/values-af/inspector_strings.xml b/res/values-af/inspector_strings.xml
new file mode 100644
index 0000000..24dcc70
--- /dev/null
+++ b/res/values-af/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Inligting"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Lêerinligting kon nie gelaai word nie"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Ontfoutinligting (net ontwikkeling)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Onverwerkte metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Mediabesonderhede"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Hierdie soort lêer maak oop met"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Hierdie lêer word voorsien deur"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nie gekies nie"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Onbekend"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Afmetings"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koördinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Hoogte bo seespieël"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Lensopening"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Sluiterspoed"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Tydsduur"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Geneem op"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fokuslengte"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-ekwivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Kunstenaar"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komponis"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Ligging"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stroomtipes"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Onverwerkte grootte (grepe)"</string>
+</resources>
diff --git a/res/values-af/mimes.xml b/res/values-af/mimes.xml
new file mode 100644
index 0000000..851e97b
--- /dev/null
+++ b/res/values-af/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-lêer"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Lêer"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Prent"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-prent"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Oudio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-oudio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-argief"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-program"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Skoonteks"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-aanbieding"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-sigblad"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-sigblad"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-aanbieding"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-skets"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-tabel"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-vorm"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-kaart"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-werf"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Vouer"</string>
+</resources>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 9dab308..4eb5f41 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Pers saam"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Onttrek na …"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Hernoem"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Eienskappe"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Kry inligting"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Bekyk in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nuwe venster"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Sny"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Skuif"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Maak toe"</string>
     <string name="button_retry" msgid="4011461781916631389">"Probeer weer"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Vee uit"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Wys in verskaffer"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nie gerangskik nie"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Naam"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Opsomming"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipe"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Grootte"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Gewysig"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Aantal kinders"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Aantal items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stygend"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Dalend"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Wys wortels"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Kan lêer nie oopmaak nie"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Kan nie lêers in argiewe oopmaak nie"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Kan sommige dokumente nie uitvee nie"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Eienskappe kon nie gelaai word nie"</string>
     <string name="share_via" msgid="8725082736005677161">"Deel via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopieer tans lêers"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Pers tans lêers saam"</string>
diff --git a/res/values-am/inspector_strings.xml b/res/values-am/inspector_strings.xml
new file mode 100644
index 0000000..423b6da
--- /dev/null
+++ b/res/values-am/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"መረጃ"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"የፋይል መረጃ ሊጫን አልቻለም"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"የማረሚያ መረጃ (ለገንቢ ብቻ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ጥሬ ዲበ ውሂብ፦ <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"የሚዲያ ዝርዝሮች"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"እንዲህ ዓይነቱ ፋይል በዚህ ይከፈታል፦"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ይህ ፋይል የቀረበው በ"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"አልተመረጠም"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"ያልታወቀ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ልኬቶች"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> ሜፒ"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"መጋጠሚያዎች"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>፣ <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ከፍታ"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ካሜራ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"የካሜራ ሌንስ መከለያ"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"የካሜራ ሌንስ መከለያ ፍጥነት"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"የቆይታ ጊዜ"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"የተነሳበት ቀን"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"የትክተት ርቀት"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> ሚሜ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"የአይኤስኦ እኩያ"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"አይኤስኦ <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"አርቲስት"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"የሙዚቃ ደራሲ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"አልበም"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"አካባቢ"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"የዥረት አይነቶች"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"የጥሬ መጠን (ባይት)"</string>
+</resources>
diff --git a/res/values-am/mimes.xml b/res/values-am/mimes.xml
new file mode 100644
index 0000000..a508032
--- /dev/null
+++ b/res/values-am/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"የ<xliff:g id="EXTENSION">%1$s</xliff:g> ፋይል"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ፋይል"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ምስል"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"የ<xliff:g id="FILETYPE">%1$s</xliff:g> ምስል"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ኦዲዮ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"የ<xliff:g id="FILETYPE">%1$s</xliff:g> ኦዲዮ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ቪዲዮ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"የ<xliff:g id="FILETYPE">%1$s</xliff:g> ቪዲዮ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"የ<xliff:g id="FILETYPE">%1$s</xliff:g> ማህደር"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"የAndroid መተግበሪያ"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ስነጣ አልባ ጽሑፍ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"የኤችቲኤምኤል ሰነድ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"የፒዲኤፍ ሰነድ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"የWord ሰነድ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"የPowerPoint ዝግጅት አቀራረብ"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"የExcel ተመን ሉህ"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"የGoogle ሰነድ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"የGoogle ተመን ሉህ"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"የGoogle ዝግጅት አቀራረብ"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"የGoogle ስዕል"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"የGoogle ሠንጠረዥ"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"የGoogle ቅጽ"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"የGoogle ካርታ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"የGoogle ጣቢያ"</string>
+    <string name="directory_type" msgid="2702987727566226354">"አቃፊ"</string>
+</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index d52aa92..1cffb23 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"ጭመቅ"</string>
     <string name="menu_extract" msgid="8171946945982532262">"አውጣ ወደ…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"ዳግም ሰይም"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"ባህሪያት"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"መረጃ አግኝ"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"በ<xliff:g id="SOURCE">%1$s</xliff:g> ይመልከቱ"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"አዲሰ መስኮት"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ቁረጥ"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ውሰድ"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"አሰናብት"</string>
     <string name="button_retry" msgid="4011461781916631389">"እንደገና ይሞክሩ"</string>
+    <string name="button_clear" msgid="5412304437764369441">"አጽዳ"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"በአቅራቢ ውስጥ አሳይ"</string>
     <string name="not_sorted" msgid="7813496644889115530">"አልተደረደረም"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"ስም"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"ማጠቃለያ"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ዓይነት"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"መጠን"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"የተቀየረበት ጊዜ"</string>
-    <string name="directory_children" msgid="8115290268549503262">"የሕፃናት ብዛት"</string>
+    <string name="directory_items" msgid="6645621978998614003">"የንጥሎች ብዛት"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ሽቅብታ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"አቆልቋይ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ስሮችን አሳይ"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ፋይሉን መክፈት አይቻልም"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"በማህደሮች ውስጥ ያሉ ፋይሎችን መክፈት አይቻልም"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"ባህሪዎቹ ሊጫኑ አልቻሉም"</string>
     <string name="share_via" msgid="8725082736005677161">"በዚህ በኩል ያጋሩ፦"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ፋይሎችን በመቅዳት ላይ"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ፋይሎችን በመጭመቅ ላይ"</string>
diff --git a/res/values-ar/inspector_strings.xml b/res/values-ar/inspector_strings.xml
new file mode 100644
index 0000000..ffae9de
--- /dev/null
+++ b/res/values-ar/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"المعلومات"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"تعذّر تحميل معلومات الملف"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"معلومات تصحيح الأخطاء (المطوّر فقط)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"البيانات الوصفية الأولية: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"تفاصيل الوسائط"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"يتم فتح هذا النوع من الملفات باستخدام"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"تم تقديم هذا الملف من خلال"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"غير محدّد"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"غير معروف"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"الأبعاد"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> × <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> ميغا بكسل"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"إحداثيات"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>، <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"الارتفاع"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"الكاميرا"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"فتحة العدسة"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"سرعة مصراع الكاميرا"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"المدة"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"تم الالتقاط في"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"البعد البؤري"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> ملليمتر"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‏مكافئ ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"‏سرعة ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"الفنان"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"الملحّن"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"الألبوم"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"الموقع الجغرافي"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"أنواع سلسلة البطاقات"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"الحجم الأولي (بالبايت)"</string>
+</resources>
diff --git a/res/values-ar/mimes.xml b/res/values-ar/mimes.xml
new file mode 100644
index 0000000..7f5b0ac
--- /dev/null
+++ b/res/values-ar/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"ملف <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ملف"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"صورة"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"صورة <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"صوت"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"صوت <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"فيديو"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"فيديو <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"أرشيف <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"‏تطبيق Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"نص عادي"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"‏مستند HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"‏مستند PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"‏مستند Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"‏عرض تقديمي في PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"‏جدول بيانات Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"‏مستند Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"‏جدول بيانات Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"‏عرض تقديمي على Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"‏رسم Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"‏جدول Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"‏نموذج Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"‏خريطة Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"‏موقع مصمم في مواقع Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"مجلد"</string>
+</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 3f3a334..4199682 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"ضغط"</string>
     <string name="menu_extract" msgid="8171946945982532262">"الاستخراج إلى…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"إعادة تسمية"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"الخصائص"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"الحصول على المعلومات"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"العرض في <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"نافذة جديدة"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"قص"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"نقل"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"تجاهل"</string>
     <string name="button_retry" msgid="4011461781916631389">"إعادة المحاولة"</string>
+    <string name="button_clear" msgid="5412304437764369441">"محو"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"عرض في مقدم الخدمة"</string>
     <string name="not_sorted" msgid="7813496644889115530">"بدون ترتيب"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"الاسم"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"الملخص"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"النوع"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"الحجم"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"آخر تعديل"</string>
-    <string name="directory_children" msgid="8115290268549503262">"عدد الأطفال"</string>
+    <string name="directory_items" msgid="6645621978998614003">"عدد العناصر"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"تصاعدي"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"تنازلي"</string>
     <string name="drawer_open" msgid="8071673398187261741">"عرض الجذور"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"يتعذر فتح الملف"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"يتعذر فتح الملفات في الأرشيف"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"تعذر حذف بعض المستندات"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"تعذَّر تحميل الخصائص"</string>
     <string name="share_via" msgid="8725082736005677161">"مشاركة عبر"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"جارٍ نسخ الملفات"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ضغط الملفات"</string>
@@ -228,8 +229,8 @@
       <item quantity="one">تم نسخ ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>) إلى الحافظة.</item>
     </plurals>
     <string name="file_operation_rejected" msgid="4301554203329008794">"معالجة الملف غير متوافقة."</string>
-    <string name="file_operation_error" msgid="2234357335716533795">"أخفقت معالجة الملف."</string>
-    <string name="rename_error" msgid="6700093173508118635">"أخفقت إعادة تسمية المستند."</string>
+    <string name="file_operation_error" msgid="2234357335716533795">"تعذّرت معالجة الملف."</string>
+    <string name="rename_error" msgid="6700093173508118635">"تعذّرت إعادة تسمية المستند."</string>
     <string name="menu_eject_root" msgid="9215040039374893613">"إخراج"</string>
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"تم تحويل بعض الملفات"</string>
     <string name="open_external_dialog_request" msgid="8173558471322861268">"هل تريد منح التطبيق <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى الدليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> على <xliff:g id="STORAGE"><i>^3</i></xliff:g>؟"</string>
diff --git a/res/values-az/inspector_strings.xml b/res/values-az/inspector_strings.xml
new file mode 100644
index 0000000..2ae8084
--- /dev/null
+++ b/res/values-az/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Məlumat"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Fayl məlumatını yükləmək mümkün olmadı"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Sazlama haqqında məlumat (yalnız dev)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Sətir metadatası: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Media haqqında məlumat"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Bu fayl növü bele açılmalıdır"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Bu fayl təmin edilib"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Seçilməyib"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Naməlum"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Ölçülər"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinatlar"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Yüksəklik"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Dəlik"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Sürgü sürəti"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Müddət:"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Şəkil çəkilib"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fokal uzunluq"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalenti"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"İfaçı"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Bəstəkar"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albom"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Məkan"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Axın növləri"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Sətir ölçüsü (bayt)"</string>
+</resources>
diff --git a/res/values-az/mimes.xml b/res/values-az/mimes.xml
new file mode 100644
index 0000000..7eeb0d3
--- /dev/null
+++ b/res/values-az/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> fayl"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fayl"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Şəkil"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> şəkli"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arxiv faylı"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android tətbiqi"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Adi mətn"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML sənədi"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF sənədi"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word sənədi"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint təqdimatı"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel cədvəli"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google sənədi"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google cədvəli"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google təqdimatı"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google rəsm faylı"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google cədvəli"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google forması"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google xəritəsi"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google saytı"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Qovluq"</string>
+</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 851717e..c9046d7 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Sıxışdırın"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Çıxarın…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Adını dəyişdirin"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Xüsusiyyətlər"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Məlumat əldə edin"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> mənbəsində baxın"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Yeni pəncərə"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Kəsin"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Köçürün"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Yığışdırın"</string>
     <string name="button_retry" msgid="4011461781916631389">"Yenidən cəhd edin"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Silin"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Provayderdə göstərin"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sıralanmayıb"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Ad"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Yekun"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Növ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Ölçü"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Dəyişmiş"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Uşaqların Sayı"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Elementlərin sayı"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Artan sıra ilə"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Azalan sıra ilə"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Kökləri göstərin"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Fayl açılmır"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Arxivdəki faylları açmaq olmur"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Bəzi sənədləri silə bilmir"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Xüsusiyyətləri yükləmək mümkün olmadı"</string>
     <string name="share_via" msgid="8725082736005677161">"Bunun vasitəsilə paylaş:"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Fayllar kopyalanır"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Faylların sıxılması"</string>
diff --git a/res/values-b+sr+Latn/inspector_strings.xml b/res/values-b+sr+Latn/inspector_strings.xml
new file mode 100644
index 0000000..133f533
--- /dev/null
+++ b/res/values-b+sr+Latn/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informacije"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Učitavanje podataka o datoteci nije uspelo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Podaci o otklanjanju grešaka (samo za programere)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metapodaci RAW datoteke: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalji o medijima"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ova vrsta datoteke se otvara pomoću:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Ovu datoteku pruža"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nije izabrano"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Nepoznato"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimenzije"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g>×<xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> megapiksela"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Nadmorska visina"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Otvor blende"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Brzina zatvarača"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Trajanje"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Snimljeno"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Žižna daljina"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Izvođač"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Kompozitor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokacija"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipovi strimova"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Veličina RAW datoteke (u bajtovima)"</string>
+</resources>
diff --git a/res/values-b+sr+Latn/mimes.xml b/res/values-b+sr+Latn/mimes.xml
new file mode 100644
index 0000000..a4e7bda
--- /dev/null
+++ b/res/values-b+sr+Latn/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> datoteka"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Datoteka"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Slika"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> slika"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arhiva"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android aplikacija"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Običan tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint prezentacija"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel tabela"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google tabela"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google prezentacija"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google crtež"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google tabela"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google upitnik"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google mapa"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google sajt"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Direktorijum"</string>
+</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index f6b43e2..01d74db 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Komprimuj"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Izdvoj u…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Preimenuj"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Svojstva"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Prikaži informacije"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Prikaži u: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Novi prozor"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Iseci"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Premesti"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Odbaci"</string>
     <string name="button_retry" msgid="4011461781916631389">"Probaj ponovo"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Obriši"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Prikaži u aplikaciji dobavljača"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nisu sortirani"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Naziv"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Rezime"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tip"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veličina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmenjeno"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Broj dece"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Broj stavki"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Rastuće"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Opadajuće"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Prikaži osnovne direktorijume"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Otvaranje datoteke nije uspelo"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Ne možete da otvarate datoteke u arhivama"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nije moguće izbrisati neke dokumente"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Učitavanje svojstava nije uspelo"</string>
     <string name="share_via" msgid="8725082736005677161">"Deljenje preko"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiramo datoteke"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Datoteke se komprimuju"</string>
diff --git a/res/values-be/inspector_strings.xml b/res/values-be/inspector_strings.xml
new file mode 100644
index 0000000..79cd4f2
--- /dev/null
+++ b/res/values-be/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Інфармацыя"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Не атрымалася загрузіць звесткі пра файл"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Адладачная інф-цыя (толькі для распрацоўшчыкаў)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Неапрацаваныя метаданыя: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Падрабязная інфармацыя пра мультымедыя"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Такія файлы адкрываюцца з дапамогай"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Гэты файл паходзіць з:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Не выбрана"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Невядома"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Памеры"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Мп"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Каардынаты"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Вышыня"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Апертура"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Хуткасць затвора"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Працягласць"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Знята"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокусная адлегласць"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Эквівалент ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Выканаўца"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Кампазітар"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Альбом"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Месцазнаходжанне"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Тыпы плыні"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Памер файла RAW (у байтах)"</string>
+</resources>
diff --git a/res/values-be/mimes.xml b/res/values-be/mimes.xml
new file mode 100644
index 0000000..42495bb
--- /dev/null
+++ b/res/values-be/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Файл <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Відарыс"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Відарыс <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аўдыя"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Аўдыя <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Відэа"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Відэа <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Архіў <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Праграма Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Просты тэкст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Дакумент HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Дакумент PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Дакумент Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Прэзентацыя PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Электр. табліца Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Дакумент Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Электр. табліца Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Прэзентацыя Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Рысунак Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Табліца Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Форма Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Карта Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Сайт Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Папка"</string>
+</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 9b13fce..d059b4b 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Сціснуць"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Выняць у…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Перайменаваць"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Уласцівасці"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Атрымаць інфармацыю"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Праглядзець тут: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Новае акно"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Выразаць"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Перамясціць"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Адхіліць"</string>
     <string name="button_retry" msgid="4011461781916631389">"Паўтарыць спробу"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Выдаліць"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Паказаць у Правадніку"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Не адсартаваны"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Назва"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Кароткае апісанне"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тып"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Памер"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Зменены"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Колькасць дзяцей"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Колькасць элементаў"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Па ўзрастанні"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Па ўбыванні"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Паказаць каранёвыя папкі"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Немагчыма адкрыць файл"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Немагчыма адкрыць файлы ў архівах"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Немагчыма выдаліць некаторыя дакументы"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Не атрымалася загрузіць уласцівасці"</string>
     <string name="share_via" msgid="8725082736005677161">"Абагуліць праз"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Капіраванне файлаў"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Ідзе сцісканне файлаў"</string>
diff --git a/res/values-bg/inspector_strings.xml b/res/values-bg/inspector_strings.xml
new file mode 100644
index 0000000..9e6b1e6
--- /dev/null
+++ b/res/values-bg/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Информация"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Информацията за файла не можа да се зареди"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Инф. за отстр. на грешки (само за програмисти)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Необработени метаданни: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Подробности за мултимедията"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Този тип файл се отваря с/ъс"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Този файл е предоставен от"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Не е избрано"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Неизвестно"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Размери"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> мегапиксела"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координати"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Надморска височина"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MODEL">%2$s</xliff:g> от <xliff:g id="MAKE">%1$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Бленда"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Скорост на затвора"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Продължителност"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Заснето на"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Дължина на фокуса"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Еквивалент на ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO: <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Изпълнител"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Албум"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Местоположение"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Типове поточно предаване"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Необработен размер (байтове)"</string>
+</resources>
diff --git a/res/values-bg/mimes.xml b/res/values-bg/mimes.xml
new file mode 100644
index 0000000..e4633f5
--- /dev/null
+++ b/res/values-bg/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> файл"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Изображение"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> изображение"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудио"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> аудиофайл"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Видео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> видеоклип"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> архив"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Приложение за Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Неформатиран текст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML документ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF документ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Документ в Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Презентация в PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Ел. таблица в Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Документ в Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Ел. таблица в Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Презентация в Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Чертеж в Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Таблица в Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Формуляр в Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Карта в Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Сайт в Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Папка"</string>
+</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index f1f9b4b..14bc483 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Компресиране"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Извличане в/ъв…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Преименуване"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Свойства"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Получаване на информация"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Преглед в/ъв <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Нов прозорец"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Изрязване"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Преместване"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Отхвърляне"</string>
     <string name="button_retry" msgid="4011461781916631389">"Нов опит"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Изчистване"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Показване чрез доставчик"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Несортирани"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Име"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Обобщена информация"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Размер"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Променено"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Брой деца"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Брой елементи"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Възходящ ред"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Низходящ ред"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Показване на основните елементи"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Файлът не може да се отвори"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Файловете в архиви не могат да се отварят"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Някои документи не могат да бъдат изтрити"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Свойствата не можаха да се заредят"</string>
     <string name="share_via" msgid="8725082736005677161">"Споделяне чрез"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Копиране на файлове"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Файловете се компресират"</string>
diff --git a/res/values-bn/inspector_strings.xml b/res/values-bn/inspector_strings.xml
new file mode 100644
index 0000000..a9d1049
--- /dev/null
+++ b/res/values-bn/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"তথ্য"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ফাইলের তথ্য লোড করা যায়নি"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ত্রুটি সারানোর তথ্য (শুধুমাত্র ডেভেলপারের জন্য)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW মেটাডেটা: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"মিডিয়ার বিশদ বিবরণ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"এই ধরনের ফাইল এই অ্যাপ দিয়ে খোলা যায়"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"এই ফাইলের সরবরাহকারী"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"বেছে নেওয়া হয়নি"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"অজানা"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"দৈর্ঘ্য-প্রস্থ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"স্থানাঙ্ক"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"সমুদ্রপৃষ্ঠ থেকে উচ্চতা"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ক্যামেরা"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"অ্যাপারচার"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"শাটার স্পিড"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"সময়কাল"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"তোলার তারিখ"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ফোকাল লেংথ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ইকুইভ্যালেন্ট"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"শিল্পী"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"সুরকার"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"অ্যালবাম"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"লোকেশন"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"স্ট্রিমের ধরন"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW এর সাইজ (বাইট)"</string>
+</resources>
diff --git a/res/values-bn/mimes.xml b/res/values-bn/mimes.xml
new file mode 100644
index 0000000..4cbc245
--- /dev/null
+++ b/res/values-bn/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ফাইল"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ফাইল"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ছবি"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> ছবি"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"অডিও"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> অডিও"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ভিডিও"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ভিডিও"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> আর্কাইভ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android অ্যাপ্লিকেশান"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"সাধারণ টেক্সট"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ডকুমেন্ট"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ডকুমেন্ট"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ডকুমেন্ট"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint উপস্থাপনা"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel স্প্রেডশিট"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ডকুমেন্ট"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google স্প্রেডশিট"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google উপস্থাপনা"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google অঙ্কন"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google সারণী"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ফর্ম"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google ম্যাপ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google সাইট"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ফোল্ডার"</string>
+</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 9bc8df1..a804b73 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -23,33 +23,33 @@
     <!-- no translation found for launcher_label (799410258349837668) -->
     <skip />
     <string name="title_open" msgid="3165686459158020921">"এখান থেকে খুলুন"</string>
-    <string name="title_save" msgid="4384490653102710025">"এতে সংরক্ষণ করুন"</string>
+    <string name="title_save" msgid="4384490653102710025">"এতে সেভ করুন"</string>
     <string name="menu_create_dir" msgid="2413624798689091042">"নতুন ফোল্ডার"</string>
     <string name="menu_grid" msgid="1453636521731880680">"গ্রিড দৃশ্য"</string>
     <string name="menu_list" msgid="6714267452146410402">"তালিকা দৃশ্য"</string>
-    <string name="menu_search" msgid="1876699106790719849">"অনুসন্ধান করুন"</string>
+    <string name="menu_search" msgid="1876699106790719849">"খুঁজুন"</string>
     <string name="menu_settings" msgid="6520844520117939047">"সঞ্চয়স্থানের সেটিংস"</string>
     <string name="menu_open" msgid="9092138100049759315">"খুলুন"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"এর মাধ্যমে খুলুন"</string>
     <string name="menu_open_in_new_window" msgid="6686563636123311276">"নতুন উইন্ডোতে খুলুন"</string>
-    <string name="menu_save" msgid="5195367497138965168">"সংরক্ষণ করুন"</string>
+    <string name="menu_save" msgid="5195367497138965168">"সেভ করুন"</string>
     <string name="menu_share" msgid="4307140947108068356">"শেয়ার করুন"</string>
     <string name="menu_delete" msgid="1022254131543256626">"মুছুন"</string>
-    <string name="menu_select_all" msgid="7600576812185570403">"সবগুলি নির্বাচন করুন"</string>
+    <string name="menu_select_all" msgid="7600576812185570403">"সবগুলি বেছে নিন"</string>
     <string name="menu_copy" msgid="7404820171352314754">"এতে কপি করুন…"</string>
     <string name="menu_move" msgid="2310760789561129882">"এতে সরান…"</string>
     <string name="menu_compress" msgid="37539111904724188">"সঙ্কুচিত করুন"</string>
     <string name="menu_extract" msgid="8171946945982532262">"এখানে রাখুন…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"পুনঃনামকরণ"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"বৈশিষ্ট্য"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"তথ্য পান"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> এ দেখুন"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"নতুন উইন্ডো"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"কাট করুন"</string>
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"কপি করুন"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"পেস্ট করুন"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"ফোল্ডারে পেস্ট করুন"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"অভ্যন্তরীণ সঞ্চয়স্থান দেখান"</string>
-    <string name="menu_advanced_hide" msgid="6488381508009246334">"অভ্যন্তরীণ সঞ্চয়স্থান লুকান"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"ইন্টারনাল স্টোরেজ দেখান"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"ইন্টারনাল স্টোরেজ লুকান"</string>
     <string name="button_select" msgid="240863497069321364">"বেছে নিন"</string>
     <string name="button_copy" msgid="8219059853840996027">"কপি করুন"</string>
     <string name="button_compress" msgid="8951561310857223966">"সঙ্কুচিত করুন"</string>
@@ -57,32 +57,33 @@
     <string name="button_move" msgid="8596460499325291272">"সরান"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"খারিজ করুন"</string>
     <string name="button_retry" msgid="4011461781916631389">"আবার চেষ্টা করুন"</string>
+    <string name="button_clear" msgid="5412304437764369441">"সাফ করুন"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"প্রদানকারীতে দেখুন"</string>
     <string name="not_sorted" msgid="7813496644889115530">"সাজানো নেই"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"নাম"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"সারাংশ"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ধরণ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"আকার"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"শেষ সংশোধিত"</string>
-    <string name="directory_children" msgid="8115290268549503262">"শিশুদের সংখ্যা"</string>
+    <string name="directory_items" msgid="6645621978998614003">"আইটেমের সংখ্যা"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ঊর্ধ্বক্রম"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"নিম্নক্রম"</string>
     <string name="drawer_open" msgid="8071673398187261741">"রুটগুলি দেখান"</string>
     <string name="drawer_close" msgid="4263880768630848848">"রুটগুলি লুকান"</string>
     <string name="save_error" msgid="8631128801982095782">"দস্তাবেজ সংরক্ষণ করা গেল না"</string>
     <string name="create_error" msgid="3092144450044861994">"ফোল্ডার তৈরি করা গেল না"</string>
-    <string name="query_error" msgid="6625421453613879336">"এই মুহূর্তে সামগ্রী লোড করা যাবে না"</string>
+    <string name="query_error" msgid="6625421453613879336">"এই মুহূর্তে কন্টেন্ট লোড করা যাবে না"</string>
     <string name="root_recent" msgid="1080156975424341623">"সাম্প্রতিক"</string>
     <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> খালি আছে"</string>
     <string name="root_type_service" msgid="6521366147466512289">"সঞ্চয়স্থানের পরিষেবা"</string>
     <string name="root_type_shortcut" msgid="6059343175525442279">"শর্টকাট"</string>
     <string name="root_type_device" msgid="1713604128005476585">"ডিভাইস"</string>
-    <string name="root_type_apps" msgid="8646073235029886342">"আরো অ্যাপ্স"</string>
+    <string name="root_type_apps" msgid="8646073235029886342">"আরও অ্যাপ্স"</string>
     <string name="empty" msgid="5300254272613103004">"কোনো আইটেম নেই"</string>
     <string name="no_results" msgid="2371026325236359209">"%1$s এ কোনো মিল নেই"</string>
     <string name="toast_no_application" msgid="7555319548595113121">"ফাইল খোলা যাবে না"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"আর্কাইভের ফাইলগুলি খোলা যাচ্ছে না"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"কিছু দস্তাবেজ মোছা গেল না"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"বৈশিষ্ট্যগুলি লোড করা যায়নি"</string>
     <string name="share_via" msgid="8725082736005677161">"এর মাধ্যমে শেয়ার করুন"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ফাইলগুলি কপি করা হচ্ছে"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ফাইলগুলি"</string>
@@ -189,19 +190,19 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মুছবেন?</item>
     </plurals>
     <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফোল্ডার এবং সেগুলির সামগ্রী মুছবেন?</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফোল্ডার এবং সেগুলির সামগ্রী মুছবেন?</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফোল্ডার এবং সেগুলির কন্টেন্ট মুছবেন?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফোল্ডার এবং সেগুলির কন্টেন্ট মুছবেন?</item>
     </plurals>
     <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম মুছবেন?</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম মুছবেন?</item>
     </plurals>
-    <string name="images_shortcut_label" msgid="2545168016070493574">"চিত্রগুলি"</string>
-    <string name="archive_loading_failed" msgid="7243436722828766996">"ব্রাউজ করার জন্য সংরক্ষণাগার খোলা গেল না৷ হয় ফাইলটি ক্ষতিগ্রস্ত বা কোনো অসমর্থিত বিন্যাসে রয়েছে৷"</string>
+    <string name="images_shortcut_label" msgid="2545168016070493574">"ছবিগুলি"</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"ব্রাউজ করার জন্য আর্কাইভ খোলা গেল না৷ হয় ফাইলটি ক্ষতিগ্রস্ত বা কোনো অসমর্থিত বিন্যাসে রয়েছে৷"</string>
     <string name="name_conflict" msgid="28407269328862986">"এই নামে আগেই আর একটি ফাইল আছে।"</string>
-    <string name="authentication_required" msgid="8030880723643436099">"এই সংগ্রহটি দেখার জন্য <xliff:g id="NAME">%1$s</xliff:g> এ প্রবেশ করুন"</string>
-    <string name="cant_display_content" msgid="8633226333229417237">"সামগ্রীগুলি প্রদর্শন করা যাচ্ছে না"</string>
-    <string name="sign_in" msgid="6253762676723505592">"প্রবেশ করুন"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"এই সংগ্রহটি দেখার জন্য <xliff:g id="NAME">%1$s</xliff:g> এ সাইন-ইন করুন"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"কন্টেন্ট প্রদর্শন করা যাচ্ছে না"</string>
+    <string name="sign_in" msgid="6253762676723505592">"সাইন-ইন করুন"</string>
     <string name="new_archive_file_name" msgid="1604650338077249838">"সংরক্ষণ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ওভাররাইট করবেন?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"পটভূমিতে চালিয়ে যান"</string>
diff --git a/res/values-bs/inspector_strings.xml b/res/values-bs/inspector_strings.xml
new file mode 100644
index 0000000..503216b
--- /dev/null
+++ b/res/values-bs/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informacije"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Informacije o fajlu nisu učitane"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informacije o otklanjanju grešaka (samo dev)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw metapodaci: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalji o medijima"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ovu vrstu datoteka otvara aplikacija"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Fajl pruža"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nije odabrano"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Nepoznato"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimenzije"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Visina"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Blenda"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Brzina zatvarača"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Trajanje"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Vrijeme snimanja"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Žižna daljina"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Umjetnik"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Kompozitor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokacija"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Vrste prijenosa"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw veličina (bajta)"</string>
+</resources>
diff --git a/res/values-bs/mimes.xml b/res/values-bs/mimes.xml
new file mode 100644
index 0000000..ab0aecf
--- /dev/null
+++ b/res/values-bs/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> fajl"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fajl"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Slika"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> slika"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Zvuk"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Videozapis"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> videozapis"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arhiva"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android aplikacija"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Obični tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint prezentacija"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Tabela u Excelu"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google tabela"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google prezentacija"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google crtež"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google tabela"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google obrazac"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google Mapa"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google web lokacija"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index de60404..e15712c 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -33,15 +33,15 @@
     <string name="menu_open_with" msgid="5507647065467520229">"Otvori koristeći"</string>
     <string name="menu_open_in_new_window" msgid="6686563636123311276">"Otvori u novom prozoru"</string>
     <string name="menu_save" msgid="5195367497138965168">"Sačuvaj"</string>
-    <string name="menu_share" msgid="4307140947108068356">"Podijeli"</string>
+    <string name="menu_share" msgid="4307140947108068356">"Dijeli"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Izbriši"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Odaberi sve"</string>
-    <string name="menu_copy" msgid="7404820171352314754">"Kopiraj na…"</string>
+    <string name="menu_copy" msgid="7404820171352314754">"Kopiraj u…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Premjesti u…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Kompresiraj"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Izdvoji u…"</string>
-    <string name="menu_rename" msgid="1883113442688817554">"Preimenuj"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Svojstva"</string>
+    <string name="menu_rename" msgid="1883113442688817554">"Promijeni naziv"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Prikaži informacije"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Prikaži u usluzi <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Novi prozor"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Izreži"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Premjesti"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Odbaci"</string>
     <string name="button_retry" msgid="4011461781916631389">"Pokušajte ponovo"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Obriši"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Prikaži u pružaocu"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nije poredano"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Ime"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Sažetak"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Vrsta"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veličina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmijenjeno"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Broj djece"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Broj stavki"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Rastuće"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Opadajuće"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Prikaži korijenske fordere"</string>
@@ -82,8 +84,7 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Nije moguće otvoriti fajl"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Nije moguće otvoriti fajlove u arhivama"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nije moguće izbrisati neke dokumente"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Svojstva nisu učitana"</string>
-    <string name="share_via" msgid="8725082736005677161">"Podijeli koristeći aplikaciju"</string>
+    <string name="share_via" msgid="8725082736005677161">"Dijeli koristeći aplikaciju"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiraju se fajlovi"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Kompresovanje fajlova"</string>
     <string name="extract_notification_title" msgid="5067393961754430469">"Izdvajanje fajlova"</string>
@@ -116,7 +117,7 @@
       <item quantity="other">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> stavki.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Opozovi radnju"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Priprema se kopiranje…"</string>
+    <string name="copy_preparing" msgid="5326063807006898223">"Priprema za kopiranje…"</string>
     <string name="compress_preparing" msgid="6650018601382062672">"Priprema za kompresiranje…"</string>
     <string name="extract_preparing" msgid="58266275455027829">"Priprema za izdvajanje…"</string>
     <string name="move_preparing" msgid="8742573245485449429">"Priprema za premještanje…"</string>
@@ -181,7 +182,7 @@
     </plurals>
     <string name="file_operation_rejected" msgid="4301554203329008794">"Nije podržana operacija za fajl."</string>
     <string name="file_operation_error" msgid="2234357335716533795">"Operacija za fajl nije uspjela."</string>
-    <string name="rename_error" msgid="6700093173508118635">"Dokument nije preimenovan"</string>
+    <string name="rename_error" msgid="6700093173508118635">"Promjena naziva dokumenta nije uspjela"</string>
     <string name="menu_eject_root" msgid="9215040039374893613">"Izbaci"</string>
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"Neki fajlovi su pretvoreni u drugi format"</string>
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na pohrani <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
diff --git a/res/values-ca/inspector_strings.xml b/res/values-ca/inspector_strings.xml
new file mode 100644
index 0000000..329f950
--- /dev/null
+++ b/res/values-ca/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informació"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"No s\'ha pogut carregar la informació del fitxer"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informació de depuració (per a desenvolupadors)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadades sense processar: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Dades multimèdia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Aquest tipus de fitxer s\'obre amb"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Aquest fitxer prové de:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"No s\'ha seleccionat"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Desconeguda"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>: <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Mpx"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenades"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitud"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Càmera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Obertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocitat de l\'obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Durada"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Data de la foto:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distància focal"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalent d\'ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Àlbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Ubicació"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipus de fluxos"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Mida sense processar (bytes)"</string>
+</resources>
diff --git a/res/values-ca/mimes.xml b/res/values-ca/mimes.xml
new file mode 100644
index 0000000..ab35d69
--- /dev/null
+++ b/res/values-ca/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Fitxer <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fitxer"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imatge"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imatge <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Àudio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Àudio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vídeo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vídeo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arxiu <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicació per a Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Text sense format"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Document HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Document PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Document de Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Presentació de PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Full de càlcul d\'Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Document de Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Full de càlcul de Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentació de Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Dibuix de Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Taula de Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulari de Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa de Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Lloc web de Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Carpeta"</string>
+</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 4d2ffdc..97789d7 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimeix"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extreu a…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Canvia el nom"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propietats"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obtén informació"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Mostra a <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Finestra nova"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Retalla"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mou"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ignora"</string>
     <string name="button_retry" msgid="4011461781916631389">"Torna-ho a provar"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Esborra"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostra al proveïdor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sense ordenar"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nom"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resum"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipus"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Mida"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificat"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Nombre de nens"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Nombre d\'elements"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendent"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendent"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostra les arrels"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"No es pot obrir el fitxer"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"No es poden obrir els fitxers dels arxius"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"No es poden suprimir alguns documents"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"No s\'han pogut carregar les propietats"</string>
     <string name="share_via" msgid="8725082736005677161">"Comparteix mitjançant"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"S\'estan copiant fitxers"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Comprimint els fitxers"</string>
diff --git a/res/values-cs/inspector_strings.xml b/res/values-cs/inspector_strings.xml
new file mode 100644
index 0000000..95705e1
--- /dev/null
+++ b/res/values-cs/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informace"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Informace o souboru nelze načíst"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informace o ladění (pouze vývojáři)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadata souboru RAW: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Podrobnosti o mediálním obsahu"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Tento typ souborů se otevírá pomocí aplikace"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Poskytovatel souboru:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nevybráno"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Neznámé"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Rozměry"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> × <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Mpx"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Souřadnice"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Výška"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fotoaparát"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Clona"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Rychlost závěrky"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Doba trvání"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Pořízeno"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Ohnisková vzdálenost"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Ekvivalent ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Interpret"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Skladatel"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Místo"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Typy streamů"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Velikost souboru RAW (bajty)"</string>
+</resources>
diff --git a/res/values-cs/mimes.xml b/res/values-cs/mimes.xml
new file mode 100644
index 0000000..c92f8cc
--- /dev/null
+++ b/res/values-cs/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Soubor <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Soubor"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Obrázek"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Obrázek <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Zvuk"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Zvuk <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archiv <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikace Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Prostý text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokument HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokument PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokument Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Prezentace PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Tabulka Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokument Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Tabulka Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Prezentace Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Nákres Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabulka Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulář Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Web Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Složka"</string>
+</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 701aab9..f768b2d 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Zkomprimovat"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Rozbalit do…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Přejmenovat"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Vlastnosti"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Zobrazit informace"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Zobrazit ve službě <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nové okno"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Vyjmout"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Přesunout"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Zavřít"</string>
     <string name="button_retry" msgid="4011461781916631389">"Zkusit znovu"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Vymazat"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Zobrazit u poskytovatele"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Neřazeno"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Název"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Souhrn"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Typ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Velikost"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Změněno"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Počet dětí"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Počet položek"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Vzestupně"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Sestupně"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Zobrazit kořeny"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Soubor nelze otevřít"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Soubory v archivu nelze otevírat"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Některé dokumenty nelze smazat"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Vlastnosti nelze načíst"</string>
     <string name="share_via" msgid="8725082736005677161">"Sdílet pomocí"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopírování souborů"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Komprimace souborů"</string>
diff --git a/res/values-da/inspector_strings.xml b/res/values-da/inspector_strings.xml
new file mode 100644
index 0000000..582e9d1
--- /dev/null
+++ b/res/values-da/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Oplysninger"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Filoplysningerne kunne ikke indlæses"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Oplysninger om fejlretning (kun på enheden)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW-metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Medieoplysninger"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Denne filtype åbnes med"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Denne fil leveres af"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ikke valgt"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Ukendt"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Mål"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinater"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Højde"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Blænde"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Lukkertid"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Varighed"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Taget den"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fokuslængde"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Tilsvarende ISO-hastighed"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Musiker"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komponist"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Placering"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Streamingtyper"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW-størrelse (i bytes)"</string>
+</resources>
diff --git a/res/values-da/mimes.xml b/res/values-da/mimes.xml
new file mode 100644
index 0000000..f6be5b7
--- /dev/null
+++ b/res/values-da/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-fil"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fil"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Billede"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-billede"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Lyd"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-lyd"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-arkiv"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-applikation"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Almindelig tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-præsentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-regneark"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-regneark"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-præsentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-tegning"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-tabel"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-formular"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-kort"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-website"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mappe"</string>
+</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index fe3dae3..20da773 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Komprimer"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Pak ud i…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Omdøb"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Egenskaber"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Få oplysninger"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Se i <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nyt vindue"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Klip"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Flyt"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Afvis"</string>
     <string name="button_retry" msgid="4011461781916631389">"Prøv igen"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Ryd"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Vis i udbyders tjeneste"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ikke sorteret"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Navn"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Oversigt"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Størrelse"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ændret"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Antal børn"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Antal elementer"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stigende rækkefølge"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Faldende rækkefølge"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Vis rødder"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Filen kan ikke åbnes"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Filer i arkiver kan ikke åbnes"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nogle dokumenter kan ikke slettes"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Ejendommene kunne ikke indlæses"</string>
     <string name="share_via" msgid="8725082736005677161">"Del via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopierer filer"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Komprimerer filer"</string>
@@ -175,8 +176,8 @@
     <string name="allow" msgid="1275746941353040309">"Tillad"</string>
     <string name="deny" msgid="5127201668078153379">"Afvis"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
-      <item quantity="one">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> er markeret</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er markeret</item>
     </plurals>
     <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
diff --git a/res/values-de/inspector_strings.xml b/res/values-de/inspector_strings.xml
new file mode 100644
index 0000000..9a8356d
--- /dev/null
+++ b/res/values-de/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informationen"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Dateiinformationen konnten nicht geladen werden"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Infos zur Fehlersuche (nur für Entwickler)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Unkomprimierte Metadaten: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Mediendetails"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Dieser Dateityp wird mit der folgenden App geöffnet:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Diese Datei wird bereitgestellt von"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nicht ausgewählt"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Unbekannt"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Abmessungen"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinaten"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Höhe"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Blende"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Belichtungszeit"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Dauer"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Aufgenommen am"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Brennweite"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-Äquivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Interpret"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komponist"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Standort"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Streamingtypen"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Unkomprimierte Größe (Byte)"</string>
+</resources>
diff --git a/res/values-de/mimes.xml b/res/values-de/mimes.xml
new file mode 100644
index 0000000..6772c95
--- /dev/null
+++ b/res/values-de/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-Datei"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Datei"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Bild"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-Bild"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-Audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-Video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-Archiv"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-App"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Nur Text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-Dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-Dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-Dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-Präsentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-Tabelle"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-Dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-Tabelle"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-Präsentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-Zeichnung"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-Tabelle"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-Formular"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-Karte"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-Website"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Ordner"</string>
+</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c29e631..703b791 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Komprimieren"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extrahieren nach…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Umbenennen"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Eigenschaften"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Weitere Informationen"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"In <xliff:g id="SOURCE">%1$s</xliff:g> ansehen"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Neues Fenster"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Ausschneiden"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Verschieben"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Schließen"</string>
     <string name="button_retry" msgid="4011461781916631389">"Wiederholen"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Löschen"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"In App des Anbieters anzeigen"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nicht sortiert"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Name"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Zusammenfassung"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Dateityp"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Größe"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Geändert"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Anzahl der Kinder"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Anzahl der Elemente"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Aufsteigend"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Absteigend"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Root-Verzeichnis anzeigen"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Datei kann nicht geöffnet werden"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Dateien in Archiven können nicht geöffnet werden"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Einige Dokumente konnten nicht gelöscht werden"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Eigenschaften konnten nicht geladen werden"</string>
     <string name="share_via" msgid="8725082736005677161">"Teilen über"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Dateien werden kopiert"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Dateien werden komprimiert"</string>
diff --git a/res/values-el/inspector_strings.xml b/res/values-el/inspector_strings.xml
new file mode 100644
index 0000000..7731009
--- /dev/null
+++ b/res/values-el/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Πληροφορίες"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Δεν ήταν δυνατή η φόρτωση των πληροφοριών αρχείου"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Πληροφορίες εντοπισμού σφαλμάτων (μόνο προγρ.)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Μη επεξεργασμένα μεταδεδομένα: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Λεπτομέρειες μέσων"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Αυτός ο τύπος αρχείου ανοίγει με"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Αυτό το αρχείο παρέχεται από"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Δεν έχει επιλεγεί"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Άγνωστη"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Διαστάσεις"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Συντεταγμένες"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Υψόμετρο"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Κάμερα"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Διάφραγμα"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Ταχύτητα κλείστρου"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Διάρκεια"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Λήψη στις"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Εστιακό μήκος"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> χλστ."</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Ισοδύναμο ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Καλλιτέχνης"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Συνθέτης"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Άλμπουμ"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Τοποθεσία"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Τύποι ροής"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Μη επεξεργασμένο μέγεθος (byte)"</string>
+</resources>
diff --git a/res/values-el/mimes.xml b/res/values-el/mimes.xml
new file mode 100644
index 0000000..b94d035
--- /dev/null
+++ b/res/values-el/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Αρχείο <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Αρχείο"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Εικόνα"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Εικόνα <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Ήχος"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Ήχος <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Βίντεο"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Βίντεο <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Αρχείο <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Εφαρμογή Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Απλό κείμενο"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Έγγραφο HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Έγγραφο PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Έγγραφο Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Παρουσίαση PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Υπολογιστικό φύλλο Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Έγγραφο Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Υπολογιστικό φύλλο Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Παρουσίαση Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Σχέδιο Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Πίνακας Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Φόρμα Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Χάρτης Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Ιστότοπος Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Φάκελος"</string>
+</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 5a51875..003ef4c 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Συμπίεση"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Εξαγωγή σε…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Μετονομασία"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Ιδιότητες"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Λήψη πληροφοριών"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Προβολή σε <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Νέο παράθυρο"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Αποκοπή"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Μετακίνηση"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Παράβλεψη"</string>
     <string name="button_retry" msgid="4011461781916631389">"Δοκιμάστε ξανά"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Διαγραφή"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Εμφάνιση στον πάροχο"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Χωρίς ταξινόμηση"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Όνομα"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Σύνοψη"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Τύπος"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Μέγεθος"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Τροποποιημένα"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Αριθμός παιδιών"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Αριθμός στοιχείων"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Αύξουσα"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Φθίνουσα"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Εμφάνιση ριζών"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Αδύνατο άνοιγμα αρχείων σε αρχειοθήκες"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Η φόρτωση των ιδιοτήτων δεν ήταν δυνατή"</string>
     <string name="share_via" msgid="8725082736005677161">"Κοινοποίηση μέσω"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Αντιγραφή αρχείων"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Συμπίεση αρχείων"</string>
diff --git a/res/values-en-rAU/inspector_strings.xml b/res/values-en-rAU/inspector_strings.xml
new file mode 100644
index 0000000..89d9e75
--- /dev/null
+++ b/res/values-en-rAU/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Info"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"File info could not be loaded"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Debug info (dev only)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Media details"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"This kind of file opens with"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"This file is supplied by"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Not selected"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Unknown"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordinates"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aperture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Shutter speed"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duration"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Taken on"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Focal length"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO equivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Composer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Location"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stream types"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw size (bytes)"</string>
+</resources>
diff --git a/res/values-en-rAU/mimes.xml b/res/values-en-rAU/mimes.xml
new file mode 100644
index 0000000..7b10dd4
--- /dev/null
+++ b/res/values-en-rAU/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> file"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Image"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> image"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> archive"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android application"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Plain text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML document"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF document"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word document"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint presentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel spreadsheet"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google document"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google spreadsheet"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google presentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google drawing"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google table"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google form"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google map"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 6c5d10f..8ffcdbc 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Rename"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Properties"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"View in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"New window"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cut"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Move"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Dismiss"</string>
     <string name="button_retry" msgid="4011461781916631389">"Try again"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Clear"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Show in provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Not sorted"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Name"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Summary"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Number of Children"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Can’t open file"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Cannot open files in archives"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Unable to delete some documents"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Properties could not be loaded"</string>
     <string name="share_via" msgid="8725082736005677161">"Share via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copying files"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compressing files"</string>
diff --git a/res/values-en-rCA/inspector_strings.xml b/res/values-en-rCA/inspector_strings.xml
new file mode 100644
index 0000000..89d9e75
--- /dev/null
+++ b/res/values-en-rCA/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Info"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"File info could not be loaded"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Debug info (dev only)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Media details"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"This kind of file opens with"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"This file is supplied by"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Not selected"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Unknown"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordinates"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aperture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Shutter speed"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duration"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Taken on"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Focal length"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO equivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Composer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Location"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stream types"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw size (bytes)"</string>
+</resources>
diff --git a/res/values-en-rCA/mimes.xml b/res/values-en-rCA/mimes.xml
new file mode 100644
index 0000000..7b10dd4
--- /dev/null
+++ b/res/values-en-rCA/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> file"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Image"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> image"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> archive"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android application"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Plain text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML document"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF document"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word document"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint presentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel spreadsheet"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google document"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google spreadsheet"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google presentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google drawing"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google table"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google form"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google map"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..8ffcdbc
--- /dev/null
+++ b/res/values-en-rCA/strings.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="files_label" msgid="771781190045103748">"Files"</string>
+    <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string>
+    <!-- no translation found for app_label (8089292432455111409) -->
+    <skip />
+    <!-- no translation found for launcher_label (799410258349837668) -->
+    <skip />
+    <string name="title_open" msgid="3165686459158020921">"Open from"</string>
+    <string name="title_save" msgid="4384490653102710025">"Save to"</string>
+    <string name="menu_create_dir" msgid="2413624798689091042">"New folder"</string>
+    <string name="menu_grid" msgid="1453636521731880680">"Grid view"</string>
+    <string name="menu_list" msgid="6714267452146410402">"List View"</string>
+    <string name="menu_search" msgid="1876699106790719849">"Search"</string>
+    <string name="menu_settings" msgid="6520844520117939047">"Storage settings"</string>
+    <string name="menu_open" msgid="9092138100049759315">"Open"</string>
+    <string name="menu_open_with" msgid="5507647065467520229">"Open with"</string>
+    <string name="menu_open_in_new_window" msgid="6686563636123311276">"Open in new window"</string>
+    <string name="menu_save" msgid="5195367497138965168">"Save"</string>
+    <string name="menu_share" msgid="4307140947108068356">"Shared"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"Delete"</string>
+    <string name="menu_select_all" msgid="7600576812185570403">"Select all"</string>
+    <string name="menu_copy" msgid="7404820171352314754">"Copy to…"</string>
+    <string name="menu_move" msgid="2310760789561129882">"Move to…"</string>
+    <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
+    <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string>
+    <string name="menu_rename" msgid="1883113442688817554">"Rename"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string>
+    <string name="menu_view_in_owner" msgid="7228948660557554770">"View in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
+    <string name="menu_new_window" msgid="2947837751796109126">"New window"</string>
+    <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cut"</string>
+    <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Copy"</string>
+    <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Paste"</string>
+    <string name="menu_paste_into_folder" msgid="8000644546983240101">"Paste into folder"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Show internal storage"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"Hide internal storage"</string>
+    <string name="button_select" msgid="240863497069321364">"Select"</string>
+    <string name="button_copy" msgid="8219059853840996027">"Copy"</string>
+    <string name="button_compress" msgid="8951561310857223966">"Compress"</string>
+    <string name="button_extract" msgid="1038674453689912247">"Extract"</string>
+    <string name="button_move" msgid="8596460499325291272">"Move"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"Dismiss"</string>
+    <string name="button_retry" msgid="4011461781916631389">"Try again"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Clear"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Show in provider"</string>
+    <string name="not_sorted" msgid="7813496644889115530">"Not sorted"</string>
+    <string name="sort_dimension_name" msgid="6325591541414177579">"Name"</string>
+    <string name="sort_dimension_summary" msgid="7724534446881397860">"Summary"</string>
+    <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
+    <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
+    <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
+    <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
+    <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
+    <string name="drawer_close" msgid="4263880768630848848">"Hide roots"</string>
+    <string name="save_error" msgid="8631128801982095782">"Failed to save document"</string>
+    <string name="create_error" msgid="3092144450044861994">"Failed to create folder"</string>
+    <string name="query_error" msgid="6625421453613879336">"Can’t load content at the moment"</string>
+    <string name="root_recent" msgid="1080156975424341623">"Recent"</string>
+    <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
+    <string name="root_type_service" msgid="6521366147466512289">"Storage services"</string>
+    <string name="root_type_shortcut" msgid="6059343175525442279">"Shortcuts"</string>
+    <string name="root_type_device" msgid="1713604128005476585">"Devices"</string>
+    <string name="root_type_apps" msgid="8646073235029886342">"More apps"</string>
+    <string name="empty" msgid="5300254272613103004">"No items"</string>
+    <string name="no_results" msgid="2371026325236359209">"No matches in %1$s"</string>
+    <string name="toast_no_application" msgid="7555319548595113121">"Can’t open file"</string>
+    <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Cannot open files in archives"</string>
+    <string name="toast_failed_delete" msgid="3453846588205817591">"Unable to delete some documents"</string>
+    <string name="share_via" msgid="8725082736005677161">"Share via"</string>
+    <string name="copy_notification_title" msgid="52256435625098456">"Copying files"</string>
+    <string name="compress_notification_title" msgid="6830195148113751021">"Compressing files"</string>
+    <string name="extract_notification_title" msgid="5067393961754430469">"Extracting files"</string>
+    <string name="move_notification_title" msgid="3173424987049347605">"Moving files"</string>
+    <string name="delete_notification_title" msgid="2512757431856830792">"Deleting files"</string>
+    <string name="copy_remaining" msgid="5390517377265177727">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
+    <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
+      <item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> items.</item>
+      <item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
+    </plurals>
+    <plurals name="compress_begin" formatted="false" msgid="3534158317098678895">
+      <item quantity="other">Compressing <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Compressing <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <plurals name="extract_begin" formatted="false" msgid="1006380679562903749">
+      <item quantity="other">Extracting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Extracting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
+      <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> items.</item>
+      <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
+    </plurals>
+    <plurals name="deleting" formatted="false" msgid="1729138001178158901">
+      <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> items.</item>
+      <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
+    </plurals>
+    <string name="undo" msgid="2902438994196400565">"Undo"</string>
+    <string name="copy_preparing" msgid="5326063807006898223">"Preparing for copy…"</string>
+    <string name="compress_preparing" msgid="6650018601382062672">"Preparing for compress…"</string>
+    <string name="extract_preparing" msgid="58266275455027829">"Preparing for extract…"</string>
+    <string name="move_preparing" msgid="8742573245485449429">"Preparing for move…"</string>
+    <string name="delete_preparing" msgid="6513863752916028147">"Preparing to delete…"</string>
+    <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+    <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
+      <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+      <item quantity="one">Couldn’t copy <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+    </plurals>
+    <plurals name="compress_error_notification_title" formatted="false" msgid="3043630066678213644">
+      <item quantity="other">Couldn’t compress <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+      <item quantity="one">Couldn’t compress <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2185736082411854754">
+      <item quantity="other">Couldn’t move <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+      <item quantity="one">Couldn’t move <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7568122018481625267">
+      <item quantity="other">Couldn’t delete <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+      <item quantity="one">Couldn’t delete <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"Tap to view details"</string>
+    <string name="close" msgid="905969391788869975">"Close"</string>
+    <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
+      <item quantity="other">These files weren’t copied: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">This file wasn’t copied: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="compress_failure_alert_content" formatted="false" msgid="5760632881868842400">
+      <item quantity="other">These files weren’t compressed: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">This file wasn’t compressed: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="extract_failure_alert_content" formatted="false" msgid="7572748127571720803">
+      <item quantity="other">These files weren’t extracted: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">This file wasn’t extracted: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="move_failure_alert_content" formatted="false" msgid="2747390342670799196">
+      <item quantity="other">These files weren’t moved: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">This file wasn’t moved: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="delete_failure_alert_content" formatted="false" msgid="6122372614839711711">
+      <item quantity="other">These files weren’t deleted: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">This file wasn’t deleted: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
+      <item quantity="other">These files were converted to another format: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">This file was converted to another format: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
+      <item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> items to clipboard.</item>
+      <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> item to clipboard.</item>
+    </plurals>
+    <string name="file_operation_rejected" msgid="4301554203329008794">"File operation is not supported."</string>
+    <string name="file_operation_error" msgid="2234357335716533795">"File operation failed."</string>
+    <string name="rename_error" msgid="6700093173508118635">"Failed to rename document"</string>
+    <string name="menu_eject_root" msgid="9215040039374893613">"Eject"</string>
+    <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"Some files were converted"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+    <string name="never_ask_again" msgid="525908236522201138">"Don\'t ask again"</string>
+    <string name="allow" msgid="1275746941353040309">"Allow"</string>
+    <string name="deny" msgid="5127201668078153379">"Deny"</string>
+    <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+    </plurals>
+    <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+    </plurals>
+    <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+    <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
+    <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
+      <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item>
+      <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item>
+    </plurals>
+    <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
+      <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> folders and their contents?</item>
+      <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> folder and its contents?</item>
+    </plurals>
+    <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
+      <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> items?</item>
+      <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+    </plurals>
+    <string name="images_shortcut_label" msgid="2545168016070493574">"Images"</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"Unable to open archive for browsing. File is either corrupt or an unsupported format."</string>
+    <string name="name_conflict" msgid="28407269328862986">"A file with this name already exists."</string>
+    <string name="authentication_required" msgid="8030880723643436099">"To view this directory, sign in to <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"Can’t display contents"</string>
+    <string name="sign_in" msgid="6253762676723505592">"Sign in"</string>
+    <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
+    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Overwrite <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+    <string name="continue_in_background" msgid="1974214559047793331">"Continue in background"</string>
+</resources>
diff --git a/res/values-en-rGB/inspector_strings.xml b/res/values-en-rGB/inspector_strings.xml
new file mode 100644
index 0000000..89d9e75
--- /dev/null
+++ b/res/values-en-rGB/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Info"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"File info could not be loaded"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Debug info (dev only)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Media details"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"This kind of file opens with"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"This file is supplied by"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Not selected"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Unknown"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordinates"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aperture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Shutter speed"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duration"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Taken on"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Focal length"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO equivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Composer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Location"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stream types"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw size (bytes)"</string>
+</resources>
diff --git a/res/values-en-rGB/mimes.xml b/res/values-en-rGB/mimes.xml
new file mode 100644
index 0000000..7b10dd4
--- /dev/null
+++ b/res/values-en-rGB/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> file"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Image"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> image"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> archive"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android application"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Plain text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML document"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF document"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word document"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint presentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel spreadsheet"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google document"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google spreadsheet"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google presentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google drawing"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google table"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google form"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google map"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 6c5d10f..8ffcdbc 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Rename"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Properties"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"View in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"New window"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cut"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Move"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Dismiss"</string>
     <string name="button_retry" msgid="4011461781916631389">"Try again"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Clear"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Show in provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Not sorted"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Name"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Summary"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Number of Children"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Can’t open file"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Cannot open files in archives"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Unable to delete some documents"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Properties could not be loaded"</string>
     <string name="share_via" msgid="8725082736005677161">"Share via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copying files"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compressing files"</string>
diff --git a/res/values-en-rIN/inspector_strings.xml b/res/values-en-rIN/inspector_strings.xml
new file mode 100644
index 0000000..89d9e75
--- /dev/null
+++ b/res/values-en-rIN/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Info"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"File info could not be loaded"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Debug info (dev only)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Media details"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"This kind of file opens with"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"This file is supplied by"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Not selected"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Unknown"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordinates"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aperture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Shutter speed"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duration"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Taken on"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Focal length"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO equivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Composer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Location"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stream types"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw size (bytes)"</string>
+</resources>
diff --git a/res/values-en-rIN/mimes.xml b/res/values-en-rIN/mimes.xml
new file mode 100644
index 0000000..7b10dd4
--- /dev/null
+++ b/res/values-en-rIN/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> file"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Image"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> image"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> archive"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android application"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Plain text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML document"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF document"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word document"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint presentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel spreadsheet"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google document"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google spreadsheet"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google presentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google drawing"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google table"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google form"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google map"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 6c5d10f..8ffcdbc 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Rename"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Properties"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"View in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"New window"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cut"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Move"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Dismiss"</string>
     <string name="button_retry" msgid="4011461781916631389">"Try again"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Clear"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Show in provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Not sorted"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Name"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Summary"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Number of Children"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Can’t open file"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Cannot open files in archives"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Unable to delete some documents"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Properties could not be loaded"</string>
     <string name="share_via" msgid="8725082736005677161">"Share via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copying files"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compressing files"</string>
diff --git a/res/values-en-rXC/inspector_strings.xml b/res/values-en-rXC/inspector_strings.xml
new file mode 100644
index 0000000..ace8d48
--- /dev/null
+++ b/res/values-en-rXC/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎Info‎‏‎‎‏‎"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎File info could not be loaded‎‏‎‎‏‎"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎Debug info (dev only)‎‏‎‎‏‎"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎Raw metadata: ‎‏‎‎‏‏‎<xliff:g id="METADATATYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎Media details‎‏‎‎‏‎"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎This kind of file opens with‎‏‎‎‏‎"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎This file is supplied by‎‏‎‎‏‎"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎Not selected‎‏‎‎‏‎"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎Unknown‎‏‎‎‏‎"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎Dimensions‎‏‎‎‏‎"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="WIDTH">%1$d</xliff:g>‎‏‎‎‏‏‏‎ x ‎‏‎‎‏‏‎<xliff:g id="HEIGHT">%2$d</xliff:g>‎‏‎‎‏‏‏‎ - ‎‏‎‎‏‏‎<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>‎‏‎‎‏‏‏‎MP‎‏‎‎‏‎"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎Coordinates‎‏‎‎‏‎"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="LATITUDE">%1$,.3f</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="LONGITUDE">%2$,.3f</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎Altitude‎‏‎‎‏‎"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎Camera‎‏‎‎‏‎"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="MAKE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎<xliff:g id="MODEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎Aperture‎‏‎‎‏‎"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎Shutter speed‎‏‎‎‏‎"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎Duration‎‏‎‎‏‎"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎Taken on‎‏‎‎‏‎"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎Focal length‎‏‎‎‏‎"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="LENGTH">%1$.2f </xliff:g>‎‏‎‎‏‏‏‎mm‎‏‎‎‏‎"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎ISO equivalent‎‏‎‎‏‎"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎ISO ‎‏‎‎‏‏‎<xliff:g id="ISO_SPEED">%1$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎Artist‎‏‎‎‏‎"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎Composer‎‏‎‎‏‎"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎Album‎‏‎‎‏‎"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎Location‎‏‎‎‏‎"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎Stream types‎‏‎‎‏‎"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎Raw size (bytes)‎‏‎‎‏‎"</string>
+</resources>
diff --git a/res/values-en-rXC/mimes.xml b/res/values-en-rXC/mimes.xml
new file mode 100644
index 0000000..43489a9
--- /dev/null
+++ b/res/values-en-rXC/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="EXTENSION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ file‎‏‎‎‏‎"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎File‎‏‎‎‏‎"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎Image‎‏‎‎‏‎"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ image‎‏‎‎‏‎"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎Audio‎‏‎‎‏‎"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ audio‎‏‎‎‏‎"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎Video‎‏‎‎‏‎"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ video‎‏‎‎‏‎"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ archive‎‏‎‎‏‎"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎Android application‎‏‎‎‏‎"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎Plain text‎‏‎‎‏‎"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎HTML document‎‏‎‎‏‎"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎PDF document‎‏‎‎‏‎"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎Word document‎‏‎‎‏‎"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎PowerPoint presentation‎‏‎‎‏‎"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎Excel spreadsheet‎‏‎‎‏‎"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎Google document‎‏‎‎‏‎"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎Google spreadsheet‎‏‎‎‏‎"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎Google presentation‎‏‎‎‏‎"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎Google drawing‎‏‎‎‏‎"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎Google table‎‏‎‎‏‎"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎Google form‎‏‎‎‏‎"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎Google map‎‏‎‎‏‎"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎Google site‎‏‎‎‏‎"</string>
+    <string name="directory_type" msgid="2702987727566226354">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‎Folder‎‏‎‎‏‎"</string>
+</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..9e727f9
--- /dev/null
+++ b/res/values-en-rXC/strings.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="files_label" msgid="771781190045103748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎Files‎‏‎‎‏‎"</string>
+    <string name="downloads_label" msgid="5462789470049501103">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎Downloads‎‏‎‎‏‎"</string>
+    <!-- no translation found for app_label (8089292432455111409) -->
+    <skip />
+    <!-- no translation found for launcher_label (799410258349837668) -->
+    <skip />
+    <string name="title_open" msgid="3165686459158020921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎Open from‎‏‎‎‏‎"</string>
+    <string name="title_save" msgid="4384490653102710025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‎Save to‎‏‎‎‏‎"</string>
+    <string name="menu_create_dir" msgid="2413624798689091042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎New folder‎‏‎‎‏‎"</string>
+    <string name="menu_grid" msgid="1453636521731880680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎Grid view‎‏‎‎‏‎"</string>
+    <string name="menu_list" msgid="6714267452146410402">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎List view‎‏‎‎‏‎"</string>
+    <string name="menu_search" msgid="1876699106790719849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎Search‎‏‎‎‏‎"</string>
+    <string name="menu_settings" msgid="6520844520117939047">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎Storage settings‎‏‎‎‏‎"</string>
+    <string name="menu_open" msgid="9092138100049759315">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎Open‎‏‎‎‏‎"</string>
+    <string name="menu_open_with" msgid="5507647065467520229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎Open with‎‏‎‎‏‎"</string>
+    <string name="menu_open_in_new_window" msgid="6686563636123311276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎Open in new window‎‏‎‎‏‎"</string>
+    <string name="menu_save" msgid="5195367497138965168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎Save‎‏‎‎‏‎"</string>
+    <string name="menu_share" msgid="4307140947108068356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎Share‎‏‎‎‏‎"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎Delete‎‏‎‎‏‎"</string>
+    <string name="menu_select_all" msgid="7600576812185570403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎Select all‎‏‎‎‏‎"</string>
+    <string name="menu_copy" msgid="7404820171352314754">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎Copy to…‎‏‎‎‏‎"</string>
+    <string name="menu_move" msgid="2310760789561129882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎Move to…‎‏‎‎‏‎"</string>
+    <string name="menu_compress" msgid="37539111904724188">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎Compress‎‏‎‎‏‎"</string>
+    <string name="menu_extract" msgid="8171946945982532262">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎Extract to…‎‏‎‎‏‎"</string>
+    <string name="menu_rename" msgid="1883113442688817554">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎Rename‎‏‎‎‏‎"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎Get info‎‏‎‎‏‎"</string>
+    <string name="menu_view_in_owner" msgid="7228948660557554770">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎View in ‎‏‎‎‏‏‎<xliff:g id="SOURCE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="menu_new_window" msgid="2947837751796109126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎New window‎‏‎‎‏‎"</string>
+    <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎Cut‎‏‎‎‏‎"</string>
+    <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎Copy‎‏‎‎‏‎"</string>
+    <string name="menu_paste_from_clipboard" msgid="360947260414135827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎Paste‎‏‎‎‏‎"</string>
+    <string name="menu_paste_into_folder" msgid="8000644546983240101">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎Paste into folder‎‏‎‎‏‎"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎Show internal storage‎‏‎‎‏‎"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎Hide internal storage‎‏‎‎‏‎"</string>
+    <string name="button_select" msgid="240863497069321364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎Select‎‏‎‎‏‎"</string>
+    <string name="button_copy" msgid="8219059853840996027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎Copy‎‏‎‎‏‎"</string>
+    <string name="button_compress" msgid="8951561310857223966">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎Compress‎‏‎‎‏‎"</string>
+    <string name="button_extract" msgid="1038674453689912247">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎Extract‎‏‎‎‏‎"</string>
+    <string name="button_move" msgid="8596460499325291272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎Move‎‏‎‎‏‎"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎Dismiss‎‏‎‎‏‎"</string>
+    <string name="button_retry" msgid="4011461781916631389">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‎Try Again‎‏‎‎‏‎"</string>
+    <string name="button_clear" msgid="5412304437764369441">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎Clear‎‏‎‎‏‎"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎Show in provider‎‏‎‎‏‎"</string>
+    <string name="not_sorted" msgid="7813496644889115530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎Not sorted‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_name" msgid="6325591541414177579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎Name‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_summary" msgid="7724534446881397860">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎Summary‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_file_type" msgid="5779709622922085381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎Type‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_size" msgid="2190547351159472884">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎Size‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎Modified‎‏‎‎‏‎"</string>
+    <string name="directory_items" msgid="6645621978998614003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎Number of items‎‏‎‎‏‎"</string>
+    <string name="sort_direction_ascending" msgid="5882787683763248102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎Ascending‎‏‎‎‏‎"</string>
+    <string name="sort_direction_descending" msgid="1729187589765894076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎Descending‎‏‎‎‏‎"</string>
+    <string name="drawer_open" msgid="8071673398187261741">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎Show roots‎‏‎‎‏‎"</string>
+    <string name="drawer_close" msgid="4263880768630848848">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎Hide roots‎‏‎‎‏‎"</string>
+    <string name="save_error" msgid="8631128801982095782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‎‎Failed to save document‎‏‎‎‏‎"</string>
+    <string name="create_error" msgid="3092144450044861994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎Failed to create folder‎‏‎‎‏‎"</string>
+    <string name="query_error" msgid="6625421453613879336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎Can’t load content at the moment‎‏‎‎‏‎"</string>
+    <string name="root_recent" msgid="1080156975424341623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎Recent‎‏‎‎‏‎"</string>
+    <string name="root_available_bytes" msgid="8269870862691408864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SIZE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ free‎‏‎‎‏‎"</string>
+    <string name="root_type_service" msgid="6521366147466512289">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎Storage services‎‏‎‎‏‎"</string>
+    <string name="root_type_shortcut" msgid="6059343175525442279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎Shortcuts‎‏‎‎‏‎"</string>
+    <string name="root_type_device" msgid="1713604128005476585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎Devices‎‏‎‎‏‎"</string>
+    <string name="root_type_apps" msgid="8646073235029886342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎More apps‎‏‎‎‏‎"</string>
+    <string name="empty" msgid="5300254272613103004">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎No items‎‏‎‎‏‎"</string>
+    <string name="no_results" msgid="2371026325236359209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎No matches in %1$s‎‏‎‎‏‎"</string>
+    <string name="toast_no_application" msgid="7555319548595113121">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎Can’t open file‎‏‎‎‏‎"</string>
+    <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‎Cannot open files in archives‎‏‎‎‏‎"</string>
+    <string name="toast_failed_delete" msgid="3453846588205817591">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎Unable to delete some documents‎‏‎‎‏‎"</string>
+    <string name="share_via" msgid="8725082736005677161">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎Share via‎‏‎‎‏‎"</string>
+    <string name="copy_notification_title" msgid="52256435625098456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎Copying files‎‏‎‎‏‎"</string>
+    <string name="compress_notification_title" msgid="6830195148113751021">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‎Compressing files‎‏‎‎‏‎"</string>
+    <string name="extract_notification_title" msgid="5067393961754430469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‎Extracting files‎‏‎‎‏‎"</string>
+    <string name="move_notification_title" msgid="3173424987049347605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎Moving files‎‏‎‎‏‎"</string>
+    <string name="delete_notification_title" msgid="2512757431856830792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎Deleting files‎‏‎‎‏‎"</string>
+    <string name="copy_remaining" msgid="5390517377265177727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="DURATION">%s</xliff:g>‎‏‎‎‏‏‏‎ left‎‏‎‎‏‎"</string>
+    <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎Copying ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎Copying ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="compress_begin" formatted="false" msgid="3534158317098678895">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎Compressing ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎Compressing ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file.‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="extract_begin" formatted="false" msgid="1006380679562903749">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎Extracting ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎Extracting ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file.‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎Moving ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎Moving ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="deleting" formatted="false" msgid="1729138001178158901">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎Deleting ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎Deleting ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
+    </plurals>
+    <string name="undo" msgid="2902438994196400565">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎Undo‎‏‎‎‏‎"</string>
+    <string name="copy_preparing" msgid="5326063807006898223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎Preparing for copy…‎‏‎‎‏‎"</string>
+    <string name="compress_preparing" msgid="6650018601382062672">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎Preparing for compress…‎‏‎‎‏‎"</string>
+    <string name="extract_preparing" msgid="58266275455027829">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎Preparing for extract…‎‏‎‎‏‎"</string>
+    <string name="move_preparing" msgid="8742573245485449429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎Preparing for move…‎‏‎‎‏‎"</string>
+    <string name="delete_preparing" msgid="6513863752916028147">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎Preparing for delete…‎‏‎‎‏‎"</string>
+    <string name="delete_progress" msgid="2627631054702306423">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎<xliff:g id="TOTALCOUNT">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎Couldn’t copy ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎Couldn’t copy ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="compress_error_notification_title" formatted="false" msgid="3043630066678213644">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Couldn’t compress ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Couldn’t compress ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2185736082411854754">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎Couldn’t move ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎Couldn’t move ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7568122018481625267">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎Couldn’t delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎Couldn’t delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎Tap to view details‎‏‎‎‏‎"</string>
+    <string name="close" msgid="905969391788869975">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‎Close‎‏‎‎‏‎"</string>
+    <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎These files weren’t copied: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎This file wasn’t copied: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="compress_failure_alert_content" formatted="false" msgid="5760632881868842400">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎These files weren’t compressed: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎This file wasn’t compressed: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="extract_failure_alert_content" formatted="false" msgid="7572748127571720803">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎These files weren’t extracted: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎This file wasn’t extracted: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="move_failure_alert_content" formatted="false" msgid="2747390342670799196">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎These files weren’t moved: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎This file wasn’t moved: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="delete_failure_alert_content" formatted="false" msgid="6122372614839711711">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎These files weren’t deleted: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎This file wasn’t deleted: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎These files were converted to another format: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎This file was converted to another format: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Copied ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items to clipboard.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Copied ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item to clipboard.‎‏‎‎‏‎</item>
+    </plurals>
+    <string name="file_operation_rejected" msgid="4301554203329008794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎File operation is not supported.‎‏‎‎‏‎"</string>
+    <string name="file_operation_error" msgid="2234357335716533795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎File operation failed.‎‏‎‎‏‎"</string>
+    <string name="rename_error" msgid="6700093173508118635">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎Failed to rename document‎‏‎‎‏‎"</string>
+    <string name="menu_eject_root" msgid="9215040039374893613">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎Eject‎‏‎‎‏‎"</string>
+    <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎Some files were converted‎‏‎‎‏‎"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to ‎‏‎‎‏‏‎<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎ directory on ‎‏‎‎‏‏‎<xliff:g id="STORAGE"><i>^3</i></xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to ‎‏‎‎‏‏‎<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎ directory?‎‏‎‎‏‎"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to your data, including photos and videos, on ‎‏‎‎‏‏‎<xliff:g id="STORAGE"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="never_ask_again" msgid="525908236522201138">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎Don\'t ask again‎‏‎‎‏‎"</string>
+    <string name="allow" msgid="1275746941353040309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎Allow‎‏‎‎‏‎"</string>
+    <string name="deny" msgid="5127201668078153379">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎Deny‎‏‎‎‏‎"</string>
+    <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+    </plurals>
+    <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎Delete \"‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\"?‎‏‎‎‏‎"</string>
+    <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‎‎Delete folder \"‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\" and its contents?‎‏‎‎‏‎"</string>
+    <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files?‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file?‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ folders and their contents?‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ folder and its contents?‎‏‎‎‏‎</item>
+    </plurals>
+    <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items?‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item?‎‏‎‎‏‎</item>
+    </plurals>
+    <string name="images_shortcut_label" msgid="2545168016070493574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎Images‎‏‎‎‏‎"</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎Unable to open archive for browsing. File is either corrupt, or an unsupported format.‎‏‎‎‏‎"</string>
+    <string name="name_conflict" msgid="28407269328862986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎A file with this name already exists.‎‏‎‎‏‎"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎To view this directory, sign in to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎Can’t display contents‎‏‎‎‏‎"</string>
+    <string name="sign_in" msgid="6253762676723505592">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎Sign in‎‏‎‎‏‎"</string>
+    <string name="new_archive_file_name" msgid="1604650338077249838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎archive‎‏‎‎‏‏‎<xliff:g id="EXTENSION">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎Overwrite ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="continue_in_background" msgid="1974214559047793331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎Continue in background‎‏‎‎‏‎"</string>
+</resources>
diff --git a/res/values-es-rUS/inspector_strings.xml b/res/values-es-rUS/inspector_strings.xml
new file mode 100644
index 0000000..e82d604
--- /dev/null
+++ b/res/values-es-rUS/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Información"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"No se pudo cargar la información del archivo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Información de depuración (solo programadores)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadatos RAW: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalles del contenido multimedia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Este tipo de archivo se abre con"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Proveedor del archivo:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Sin seleccionar"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Desconocido"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensiones"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> (<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP)"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenadas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitud"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Cámara"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Apertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocidad del obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duración"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Fecha de la foto"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Longitud focal"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalente ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Álbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Ubicación"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipos de flujo"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Tamaño del archivo RAW (bytes)"</string>
+</resources>
diff --git a/res/values-es-rUS/mimes.xml b/res/values-es-rUS/mimes.xml
new file mode 100644
index 0000000..6cb9827
--- /dev/null
+++ b/res/values-es-rUS/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Archivo <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Archivo"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imagen"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imagen <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archivo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicación de Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texto sin formato"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento de Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Presentación PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Hoja de cálculo de Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento de Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Hoja de cálculo Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentación de Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Dibujo de Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabla de Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulario de Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa de Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Sitio de Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Carpeta"</string>
+</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 27e249a..07d660e 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extraer en…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Cambiar nombre"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propiedades"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obtener información"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ver en <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Ventana nueva"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cortar"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Descartar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Volver a intentar"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Borrar"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostrar en el proveedor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sin ordernar"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nombre"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumen"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaño"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificación"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Cantidad de hijos"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Cantidad de elementos"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raíces"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"No se puede abrir el archivo"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"No se pueden abrir los documentos en Archivos"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"No es posible borrar algunos documentos"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"No se pudieron cargar las propiedades"</string>
     <string name="share_via" msgid="8725082736005677161">"Compartir con"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copiando archivos"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Comprimiendo archivos"</string>
diff --git a/res/values-es/inspector_strings.xml b/res/values-es/inspector_strings.xml
new file mode 100644
index 0000000..fcd3d88
--- /dev/null
+++ b/res/values-es/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Información"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"No se ha podido cargar la información del archivo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Información de depuración (solo desarrolladores)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadatos sin procesar: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalles de contenido multimedia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Este tipo de archivo se abre con"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Proveedor del archivo:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"No se ha seleccionado"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Desconocida"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensiones"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g>x<xliff:g id="HEIGHT">%2$d</xliff:g> (<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP)"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenadas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitud"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Cámara"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Apertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocidad del obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duración"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Fecha de la foto"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Longitud focal"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalente ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Álbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Ubicación"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stream types"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Tamaño del archivo RAW (bytes)"</string>
+</resources>
diff --git a/res/values-es/mimes.xml b/res/values-es/mimes.xml
new file mode 100644
index 0000000..eb2e016
--- /dev/null
+++ b/res/values-es/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Archivo <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Archivo"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imagen"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imagen <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vídeo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vídeo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archivo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicación de Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texto sin formato"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento de Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Presentación PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Hoja de cálculo Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento de Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Hoja de cálculo Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentación de Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Dibujo de Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabla de Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulario de Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa de Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Sitio de Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Carpeta"</string>
+</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 6858822..636df57 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extraer a…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Cambiar nombre"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propiedades"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obtener información"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ver en <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nueva ventana"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cortar"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Descartar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Volver a intentarlo"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Borrar"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostrar en el proveedor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sin ordenar"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nombre"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumen"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaño"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Número de hijos"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Número de elementos"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raíces"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"No se puede abrir el archivo"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"No se pueden abrir los elementos archivados"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Error al eliminar algunos documentos"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"No se han podido cargar las propiedades"</string>
     <string name="share_via" msgid="8725082736005677161">"Compartir a través de"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copiando archivos"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Comprimiendo archivos"</string>
diff --git a/res/values-et/inspector_strings.xml b/res/values-et/inspector_strings.xml
new file mode 100644
index 0000000..010cf9a
--- /dev/null
+++ b/res/values-et/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Teave"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Faili teavet ei saanud laadida"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Silumisteave (ainult arendajatele)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Toormetaandmed: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Meedia üksikasjad"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Seda tüüpi faile saab avada rakendusega"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Selle faili allikas on"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Pole valitud"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Teadmata"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Mõõtmed"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinaadid"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Kõrgus"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kaamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Ava"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Säriaeg"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Kestus"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Jäädvustatud"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fookuskaugus"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Esitaja"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Helilooja"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Asukoht"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Voo tüübid"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Toorandmete maht (baitides)"</string>
+</resources>
diff --git a/res/values-et/mimes.xml b/res/values-et/mimes.xml
new file mode 100644
index 0000000..ab84b18
--- /dev/null
+++ b/res/values-et/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-fail"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fail"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Kujutis"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-kujutis"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Heli"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-helifail"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-videofail"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-arhiiv"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Androidi rakendus"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Lihttekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Wordi dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPointi esitlus"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Exceli arvutustabel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google\'i dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google\'i arvutustabel"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google\'i esitlus"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google\'i joonis"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google\'i tabel"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google\'i vorm"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google\'i kaart"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google\'i sait"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Kaust"</string>
+</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 253220a..e86fcd5 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Tihenda"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Ekstrakti …"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Nimeta ümber"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Atribuudid"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Teabe hankimine"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Kuva allikas <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Uus aken"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Lõika"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Teisalda"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Loobu"</string>
     <string name="button_retry" msgid="4011461781916631389">"Proovi uuesti"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Kustuta"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Kuva teenuses"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sortimata"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nimi"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Kokkuvõte"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tüüp"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Suurus"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Muudetud"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Laste arv"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Üksuste arv"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Kasvav"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Kahanev"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Kuva juured"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Faili ei saa avada"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Arhiivides olevaid faile ei saa avada"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Mõnda dokumenti ei saa kustutada"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Atribuute ei saanud laadida"</string>
     <string name="share_via" msgid="8725082736005677161">"Jaga rakendusega"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Failide kopeerimine"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Failide tihendamine"</string>
diff --git a/res/values-eu/inspector_strings.xml b/res/values-eu/inspector_strings.xml
new file mode 100644
index 0000000..24b9b4a
--- /dev/null
+++ b/res/values-eu/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informazioa"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Ezin izan da kargatu fitxategiaren informazioa"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Arazte-informazioa (garatzaileentzat soilik)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Prozesatu gabeko metadatuak: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Multimedia-elementuaren xehetasunak"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Mota honetako fitxategiak aplikazio honekin ireki daitezke:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Fitxategiaren hornitzailea:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Hautatu gabe"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Ezezaguna"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimentsioak"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordenatuak"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitudea"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Irekidura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Kliskagailuaren abiadura"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Iraupena"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Data"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Foku-distantzia"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO baliokidea"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Konpositorea"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albuma"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Kokapena"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Jario motak"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Prozesatu gabeko tamaina (byte-tan)"</string>
+</resources>
diff --git a/res/values-eu/mimes.xml b/res/values-eu/mimes.xml
new file mode 100644
index 0000000..45294b7
--- /dev/null
+++ b/res/values-eu/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> fitxategia"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fitxategia"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Irudia"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> irudia"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audioa"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audioa"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Bideoa"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> bideoa"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> artxiboa"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android aplikazioa"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Testu arrunta"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokumentua"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokumentua"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word dokumentua"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint aurkezpena"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel kalkulu-orria"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google dokumentua"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google kalkulu-orria"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google aurkezpena"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google marrazkia"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google taula"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google inprimakia"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google mapa"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google webgunea"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Karpeta"</string>
+</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 0196379..7c3deee 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Konprimatu"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Atera hona…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Aldatu izena"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propietateak"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Lortu informazioa"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ikusi <xliff:g id="SOURCE">%1$s</xliff:g> zerbitzuan"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Leiho berria"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Ebaki"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mugitu"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Baztertu"</string>
     <string name="button_retry" msgid="4011461781916631389">"Saiatu berriro"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Garbitu"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Erakutsi hornitzailean"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ordenatu gabe"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Izena"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Laburpena"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Mota"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Aldatze-ordua"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Haur kopurua"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Elementu kopurua"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Gorantz"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Beherantz"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Erakutsi erroko karpetak"</string>
@@ -81,8 +83,7 @@
     <string name="no_results" msgid="2371026325236359209">"Ez da aurkitu ezer %1$s atalean"</string>
     <string name="toast_no_application" msgid="7555319548595113121">"Ezin da ireki fitxategia"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Ezin dira ireki artxiboetako fitxategiak"</string>
-    <string name="toast_failed_delete" msgid="3453846588205817591">"Ezin izan dira ezabatu dokumentu batzuk"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Ezin izan dira kargatu propietateak"</string>
+    <string name="toast_failed_delete" msgid="3453846588205817591">"Ezin dira ezabatu dokumentu batzuk"</string>
     <string name="share_via" msgid="8725082736005677161">"Partekatu honekin:"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiatu fitxategiak"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Fitxategiak konprimatzen"</string>
diff --git a/res/values-fa/inspector_strings.xml b/res/values-fa/inspector_strings.xml
new file mode 100644
index 0000000..e6daea3
--- /dev/null
+++ b/res/values-fa/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"اطلاعات"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"اطلاعات فایل بارگیری نشد"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"اطلاعات اشکال‌زدایی (فقط برنامه‌نویس)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"‏فراداده فایل Raw: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"جزئیات رسانه"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"این نوع فایل با این برنامه باز می‌شود"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ارائه‌دهنده این فایل"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"انتخاب نشده است"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"نامشخص"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ابعاد"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"‏<xliff:g id="WIDTH">%1$d</xliff:g> x‏ <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>مگاپیکسل"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"مختصات"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>، <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ارتفاع"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"دوربین"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"دیافراگم"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"سرعت شاتر"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"مدت‌زمان"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"گرفته‌شده در"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"فیلم کامل"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>میلی‌متر"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‏معادل ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"‏<xliff:g id="ISO_SPEED">%1$d</xliff:g> ‏ISO"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"هنرمند"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"آهنگ‌ساز"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"آلبوم"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"مکان"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"انواع پخش جریانی"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"‏حجم فایل RAW (بایت)"</string>
+</resources>
diff --git a/res/values-fa/mimes.xml b/res/values-fa/mimes.xml
new file mode 100644
index 0000000..1fc105e
--- /dev/null
+++ b/res/values-fa/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"فایل <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"فایل"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"تصویر"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"تصویر <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"فایل صوتی"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"فایل صوتی <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ویدئو"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"ویدئوی <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"بایگانی <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"‏برنامه Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"متن ساده"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"‏سند HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"‏سند PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"‏سند Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"‏ارائه PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"‏صفحه‌گسترده Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"‏سند Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"‏صفحه‌گسترده Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"‏ارائه Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"‏طرح‌نگار Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"‏جدول Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"‏فرم‌نگار Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google Map"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"پوشه"</string>
+</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 8185604..5417179 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"فشرده کردن"</string>
     <string name="menu_extract" msgid="8171946945982532262">"استخراج در…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"تغییر نام"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"مشخصات"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"دریافت اطلاعات"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"مشاهده در <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"پنجره جدید"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"برش"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"انتقال"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"رد کردن"</string>
     <string name="button_retry" msgid="4011461781916631389">"دوباره امتحان کنید"</string>
+    <string name="button_clear" msgid="5412304437764369441">"پاک کردن"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"نمایش در برنامه ارائه‌دهنده"</string>
     <string name="not_sorted" msgid="7813496644889115530">"مرتب‌سازی نشده است"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"نام"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"خلاصه"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"نوع"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"اندازه"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"آخرین تغییر"</string>
-    <string name="directory_children" msgid="8115290268549503262">"تعداد کودکان"</string>
+    <string name="directory_items" msgid="6645621978998614003">"تعداد موارد"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"صعودی"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"نزولی"</string>
     <string name="drawer_open" msgid="8071673398187261741">"نمایش ریشه‌ها"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"فایل باز نمی‌شود"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"فایل‌های موجود در بایگانی‌ها باز نمی‌شوند"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"برخی از اسناد حذف نمی‌شوند"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"مشخصات بار نشدند"</string>
     <string name="share_via" msgid="8725082736005677161">"اشتراک‌گذاری از طریق"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"در حال کپی کردن فایل‌ها"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"درحال فشرده‌سازی فایل‌ها"</string>
diff --git a/res/values-fi/inspector_strings.xml b/res/values-fi/inspector_strings.xml
new file mode 100644
index 0000000..1e18204
--- /dev/null
+++ b/res/values-fi/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Tietoja"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Tiedoston tietojen lataus epäonnistui."</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Vianetsintätiedot (vain kehittäjät)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raa\'at sisällönkuvaustiedot: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Median tiedot"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Sovellus, jolla tiedostotyyppi avataan"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Tiedoston lähde"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ei valittu"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Tuntematon"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Mitat"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinaatit"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Korkeus"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aukko"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Suljinaika"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Kesto"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Kuvaushetki"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Polttoväli"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-vastine"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artisti"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Säveltäjä"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albumi"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Sijainti"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Striimaustyypit"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raaka koko (tavua)"</string>
+</resources>
diff --git a/res/values-fi/mimes.xml b/res/values-fi/mimes.xml
new file mode 100644
index 0000000..64cab9a
--- /dev/null
+++ b/res/values-fi/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-tiedosto"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Tiedosto"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Kuva"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-kuva"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Ääni"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-ääni"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-arkisto"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-sovellus"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Pelkkä teksti"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokumentti"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokumentti"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-dokumentti"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-esitys"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-laskentataulukko"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-dokumentti"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-laskentataulukko"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-esitys"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-piirros"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-taulukko"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-lomake"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-kartta"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-sivusto"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Kansio"</string>
+</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index fe0fc2e..a23dd94 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Pakkaa"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Pura kohteeseen…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Nimeä uudelleen"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Ominaisuudet"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Näytä tiedot"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Avaa sovelluksella <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Uusi ikkuna"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Leikkaa"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Siirrä"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Hylkää"</string>
     <string name="button_retry" msgid="4011461781916631389">"Yritä uudelleen"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Tyhjennä"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Näytä palveluntarjoajan sovelluksessa"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ei lajittelua"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nimi"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Yhteenveto"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tyyppi"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Koko"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Muokattu"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Lasten määrä"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Kohteiden määrä"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Nouseva"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Laskeva"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Näytä juuret"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Tiedoston avaaminen epäonnistui."</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Arkistoissa olevia tiedostoja ei voi avata."</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Joidenkin dokumenttien poistaminen epäonnistui."</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Ominaisuuksien lataaminen epäonnistui."</string>
     <string name="share_via" msgid="8725082736005677161">"Jaa sovelluksessa"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopioidaan tiedostoja"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Pakataan tiedostoja"</string>
diff --git a/res/values-fr-rCA/inspector_strings.xml b/res/values-fr-rCA/inspector_strings.xml
new file mode 100644
index 0000000..d4de841
--- /dev/null
+++ b/res/values-fr-rCA/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Renseignements"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Impossible de charger les renseignements sur le fichier"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Données de débogage (concepteurs uniquement)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Métadonnées brutes : <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Détails des médias"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ce type de fichier s\'ouvre avec"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Ce fichier est fourni par"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Non sélectionné"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Inconnu"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Mpx"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordonnées"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Appareil photo"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MODEL">%2$s</xliff:g> de <xliff:g id="MAKE">%1$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Ouverture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Vitesse de l\'obturateur"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Durée"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Prise le"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distance focale"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Équivalent ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artiste"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositeur"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Localisation"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Types de flux"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Taille brute (en octets)"</string>
+</resources>
diff --git a/res/values-fr-rCA/mimes.xml b/res/values-fr-rCA/mimes.xml
new file mode 100644
index 0000000..47f07c7
--- /dev/null
+++ b/res/values-fr-rCA/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Fichier <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fichier"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Image"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Image <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vidéo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vidéo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archive <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Application Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texte brut"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Document HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Document PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Document Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Présentation PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Feuille de calcul Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Document Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Feuille de calcul Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Présentation Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Dessin Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tableau Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulaire Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Carte Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Dossier"</string>
+</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 1f59cb5..66a68fb 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compresser"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extraire vers…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Renommer"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propriétés"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"En savoir plus"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Afficher dans <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nouvelle fenêtre"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Couper"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Déplacer"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Fermer"</string>
     <string name="button_retry" msgid="4011461781916631389">"Réessayer"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Effacer"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Afficher dans l\'application du fournisseur"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Non trié"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nom"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Résumé"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Taille"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Dernière modification"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Nombre d\'enfants"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Nombre d\'éléments"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Par ordre croissant"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Par ordre décroissant"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Afficher les racines"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Impossible d\'ouvrir le fichier"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Impossible d\'ouvrir des fichiers dans les archives"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Impossible de supprimer certains documents"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Les propriétés n\'ont pas pu être chargées"</string>
     <string name="share_via" msgid="8725082736005677161">"Partager via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copie de fichiers…"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compression des fichiers"</string>
diff --git a/res/values-fr/inspector_strings.xml b/res/values-fr/inspector_strings.xml
new file mode 100644
index 0000000..b2fa481
--- /dev/null
+++ b/res/values-fr/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informations"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Impossible de charger les informations relatives au fichier"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informations de débogage (développeur seulement)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Métadonnées brutes : <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Informations sur les médias"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ce type de fichier s\'ouvre avec"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Ce fichier est fourni par"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Non sélectionnée"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Inconnue"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensions"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Mpx"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordonnées"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Appareil photo"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Ouverture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Vitesse d\'obturation"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Durée"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Prise le"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Longueur focale"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Équivalent ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artiste"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositeur"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Localisation"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Types de flux"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Taille brute (octets)"</string>
+</resources>
diff --git a/res/values-fr/mimes.xml b/res/values-fr/mimes.xml
new file mode 100644
index 0000000..47f07c7
--- /dev/null
+++ b/res/values-fr/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Fichier <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fichier"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Image"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Image <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vidéo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vidéo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archive <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Application Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texte brut"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Document HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Document PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Document Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Présentation PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Feuille de calcul Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Document Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Feuille de calcul Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Présentation Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Dessin Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tableau Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulaire Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Carte Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Dossier"</string>
+</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index d0a96ee..73048ab 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compresser"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extraire sur…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Renommer"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propriétés"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obtenir les informations"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Afficher dans <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nouvelle fenêtre"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Couper"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Déplacer"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ignorer"</string>
     <string name="button_retry" msgid="4011461781916631389">"Réessayer"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Effacer"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Afficher dans le fournisseur"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Non triés"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nom"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Résumé"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Taille"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Dernière modif."</string>
-    <string name="directory_children" msgid="8115290268549503262">"Nombre d\'enfants"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Nombre d\'éléments"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Croissant"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Décroissant"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Afficher les répertoires racines"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Impossible d\'ouvrir le fichier"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Impossible d\'ouvrir un fichier dans une archive"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Impossible de supprimer certains documents"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Impossible de charger les propriétés"</string>
     <string name="share_via" msgid="8725082736005677161">"Partager via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copie de fichiers…"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compression de fichiers"</string>
diff --git a/res/values-gl/inspector_strings.xml b/res/values-gl/inspector_strings.xml
new file mode 100644
index 0000000..a33b561
--- /dev/null
+++ b/res/values-gl/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Información"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Non se puido cargar a información do ficheiro"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Datos de depuración (só para programadores)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadatos sen procesar: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Datos multimedia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Este tipo de ficheiro ábrese con"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Provedor do ficheiro"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Non seleccionada"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Descoñecida"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensións"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> (<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Mpx)"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenadas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Cámara"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MODEL">%2$s</xliff:g> de <xliff:g id="MAKE">%1$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Abertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocidade do obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duración"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Data da foto"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distancia focal"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalente ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Álbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Localización"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipos de emisión"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Tamaño sen procesar (bytes)"</string>
+</resources>
diff --git a/res/values-gl/mimes.xml b/res/values-gl/mimes.xml
new file mode 100644
index 0000000..05b48c4
--- /dev/null
+++ b/res/values-gl/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Ficheiro <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Ficheiro"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imaxe"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imaxe <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vídeo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vídeo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arquivo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicación Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texto sen formato"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento de Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Presentación PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Folla de cálculo Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento de Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Folla de cálculo Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentación de Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Debuxo de Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Táboa de Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulario de Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa de Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Sitio de Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Cartafol"</string>
+</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 2f2d5e1..606af08 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extraer en..."</string>
     <string name="menu_rename" msgid="1883113442688817554">"Cambiar nome"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propiedades"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obter información"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ver en <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nova ventá"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cortar"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ignorar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Tentar de novo"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Borrar"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostrar no provedor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sen ordenar"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nome"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaño"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Número de nenos"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Número de elementos"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raíces"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Non se pode abrir o ficheiro"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Non se poden abrir ficheiros dentro de arquivos"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Non se poden eliminar algúns documentos"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Non se puideron cargar as propiedades"</string>
     <string name="share_via" msgid="8725082736005677161">"Compartir a través de"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copiando ficheiros"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Comprimindo ficheiros"</string>
diff --git a/res/values-gu/inspector_strings.xml b/res/values-gu/inspector_strings.xml
new file mode 100644
index 0000000..97e0b8a
--- /dev/null
+++ b/res/values-gu/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"માહિતી"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ફાઇલની માહિતી લોડ કરી શકાતી નથી"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ડિબગ માહિતી (માત્ર વિકાસકર્તા)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw મેટાડેટા: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"મીડિયા વિગતો"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"આની સાથે આ પ્રકારની ફાઇલ ખૂલે છે"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"આ ફાઇલ આમના દ્વારા પૂરી પાડવામાં આવી"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"પસંદ કર્યું નથી"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"અજાણ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"પરિમાણો"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"કોઓર્ડિનેટ્સ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ઊંચાઈ"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"કૅમેરા"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ઍપર્ચર"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"શટરની સ્પીડ"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"અવધિ"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ના રોજ લીધેલો"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ફોકલ લંબાઈ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>મિમી"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO સમકક્ષ"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"કલાકાર"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"સંગીતકાર"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"આલ્બમ"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"સ્થાન"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"સ્ટ્રીમના પ્રકારો"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Rawનું કદ (બાઇટ)"</string>
+</resources>
diff --git a/res/values-gu/mimes.xml b/res/values-gu/mimes.xml
new file mode 100644
index 0000000..97e9224
--- /dev/null
+++ b/res/values-gu/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ફાઇલ"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ફાઇલ"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"છબી"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> છબી"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ઑડિઓ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ઑડિઓ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"વીડિઓ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> વીડિઓ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> આર્કાઇવ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ઍપ્લિકેશન"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"સાદી ટેક્સ્ટ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML દસ્તાવેજ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF દસ્તાવેજ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word દસ્તાવેજ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint પ્રસ્તુતિ"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel સ્પ્રેડશીટ"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google દસ્તાવેજ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google સ્પ્રેડશીટ"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google પ્રસ્તુતિ"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ડ્રોઇંગ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google કોષ્ટક"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ફોર્મ"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google નકશો"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google સાઇટ"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ફોલ્ડર"</string>
+</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index f61a9c4..c2116c4 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"સંકુચિત કરો"</string>
     <string name="menu_extract" msgid="8171946945982532262">"આમાં એક્સટ્રેક્ટ કરો…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"નામ બદલો"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"ગુણધર્મો"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"માહિતી મેળવો"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>માં જુઓ"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"નવી વિંડો"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"કાપો"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ખસેડો"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"છોડી દો"</string>
     <string name="button_retry" msgid="4011461781916631389">"ફરી પ્રયાસ કરો"</string>
+    <string name="button_clear" msgid="5412304437764369441">"સાફ કરો"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"પ્રદાતા સેવામાં બતાવો"</string>
     <string name="not_sorted" msgid="7813496644889115530">"સૉર્ટ કરેલ નથી"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"નામ"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"સારાંશ"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"પ્રકાર"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"કદ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"સંશોધિત"</string>
-    <string name="directory_children" msgid="8115290268549503262">"બાળકોની સંખ્યા"</string>
+    <string name="directory_items" msgid="6645621978998614003">"આઇટમની સંખ્યા:"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ચઢતાં ક્રમમાં"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ઉતરતા ક્રમમાં"</string>
     <string name="drawer_open" msgid="8071673398187261741">"રૂટ્સ બતાવો"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ફાઇલ ખોલી શકતાં નથી"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"આર્કાઇવમાંની ફાઇલો ખોલી શકાતી નથી"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"કેટલાક દસ્તાવેજો કાઢી નાખવામાં અસમર્થ"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"પ્રોપર્ટી લોડ કરી શકાઈ નથી"</string>
     <string name="share_via" msgid="8725082736005677161">"આના દ્વારા શેર કરો"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ફાઇલો કૉપિ કરી રહ્યાં છે"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ફાઇલોને સંકુચિત કરવી"</string>
@@ -170,7 +171,7 @@
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"કેટલીક ફાઇલો રૂપાંતરિત કરી હતી"</string>
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^3</i></xliff:g> પર <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
-    <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટા અને વિડિઓઝ સહિત તમારા ડેટાની અ‍ૅક્સેસ આપીએ?"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટો અને વિડિઓઝ સહિત તમારા ડેટાની અ‍ૅક્સેસ આપીએ?"</string>
     <string name="never_ask_again" msgid="525908236522201138">"ફરીથી પૂછશો નહીં"</string>
     <string name="allow" msgid="1275746941353040309">"મંજૂરી આપો"</string>
     <string name="deny" msgid="5127201668078153379">"નકારો"</string>
diff --git a/res/values-hi/inspector_strings.xml b/res/values-hi/inspector_strings.xml
new file mode 100644
index 0000000..e18a792
--- /dev/null
+++ b/res/values-hi/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"जानकारी"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"फ़ाइल की जानकारी लोड नहीं हो सकी"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"डीबग जानकारी (केवल डेवलपर)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"अपरिष्कृत मेटाडेटा: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"मीडिया की जानकारी"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"इस तरह की फ़ाइल इसमें खुलती है:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"यह फ़ाइल यहां से उपलब्ध कराई गई है"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"नहीं चुना गया"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"अज्ञात"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"आयाम"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>एमपी"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"निर्देशांक"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ऊंचाई"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"कैमरा"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"एपर्चर"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"शटर की गति"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"अवधि"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"फ़ोटो लिए जाने का समय"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"फ़ोकल लंबाई"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> मिमी"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO के बराबर"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"कलाकार"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"संगीतकार"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"एल्बम"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"जगह"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"प्रसारण के प्रकार"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"अपरिष्कृत आकार (बाइट)"</string>
+</resources>
diff --git a/res/values-hi/mimes.xml b/res/values-hi/mimes.xml
new file mode 100644
index 0000000..ffff6e9
--- /dev/null
+++ b/res/values-hi/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> फ़ाइल"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"फ़ाइल"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"चित्र"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> चित्र"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ऑडियो"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ऑडियो"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"वीडियो"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> वीडियो"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> संग्रह"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ऐप्लिकेशन"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"सादा पाठ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML दस्‍तावेज़"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"पीडीएफ़ दस्तावेज़"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word दस्तावेज़"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint प्रस्तुतिकरण"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel स्प्रैडशीट"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google दस्तावेज़"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google स्प्रैडशीट"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google प्रस्तुतिकरण"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google आरेखण"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google टेबल"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google फ़ॉर्म"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google मानचित्र"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google साइट"</string>
+    <string name="directory_type" msgid="2702987727566226354">"फ़ोल्डर"</string>
+</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 4924965..3ab5f55 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -23,25 +23,25 @@
     <!-- no translation found for launcher_label (799410258349837668) -->
     <skip />
     <string name="title_open" msgid="3165686459158020921">"यहां से खोलें"</string>
-    <string name="title_save" msgid="4384490653102710025">"यहां सहेजें"</string>
+    <string name="title_save" msgid="4384490653102710025">"यहां सेव करें"</string>
     <string name="menu_create_dir" msgid="2413624798689091042">"नया फ़ोल्डर"</string>
     <string name="menu_grid" msgid="1453636521731880680">"ग्रिड दृश्य"</string>
     <string name="menu_list" msgid="6714267452146410402">"सूची दृश्य"</string>
-    <string name="menu_search" msgid="1876699106790719849">"खोजें"</string>
+    <string name="menu_search" msgid="1876699106790719849">"सर्च करें"</string>
     <string name="menu_settings" msgid="6520844520117939047">"जगह सेटिंग"</string>
     <string name="menu_open" msgid="9092138100049759315">"खोलें"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"इसमें खोलें"</string>
     <string name="menu_open_in_new_window" msgid="6686563636123311276">"नई विंडो में खोलें"</string>
-    <string name="menu_save" msgid="5195367497138965168">"सहेजें"</string>
-    <string name="menu_share" msgid="4307140947108068356">"साझा करें"</string>
-    <string name="menu_delete" msgid="1022254131543256626">"हटाएं"</string>
+    <string name="menu_save" msgid="5195367497138965168">"सेव करें"</string>
+    <string name="menu_share" msgid="4307140947108068356">"शेयर करें"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"मिटाएं"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"सभी चुनें"</string>
     <string name="menu_copy" msgid="7404820171352314754">"इनकी कॉपी करें..."</string>
     <string name="menu_move" msgid="2310760789561129882">"यहां ले जाएं…"</string>
     <string name="menu_compress" msgid="37539111904724188">"कंप्रेस करें"</string>
     <string name="menu_extract" msgid="8171946945982532262">"यहां निकालें…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"नाम बदलें"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"गुण"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"जानकारी पाएं"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> में देखें"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"नई विंडो"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"काटें"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ले जाएं"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"खारिज करें"</string>
     <string name="button_retry" msgid="4011461781916631389">"फिर से कोशिश करें"</string>
+    <string name="button_clear" msgid="5412304437764369441">"साफ़ करें"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"प्रदाता में दिखाएं"</string>
     <string name="not_sorted" msgid="7813496644889115530">"क्रमबद्ध नहीं हैं"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"नाम"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"सारांश"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"बदलनेे का समय"</string>
-    <string name="directory_children" msgid="8115290268549503262">"बच्चों की संख्या"</string>
+    <string name="directory_items" msgid="6645621978998614003">"आइटम की संख्या"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"बढ़ते क्रम में"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"घटते क्रम में"</string>
     <string name="drawer_open" msgid="8071673398187261741">"रूट दिखाएं"</string>
@@ -82,8 +84,7 @@
     <string name="toast_no_application" msgid="7555319548595113121">"फ़ाइल नहीं खोली जा सकती"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"संग्रह में मौजूद फ़ाइलें नहीं खोली जा सकतीं"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"कुछ दस्तावेज़ों को हटाने में असमर्थ"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"प्रॉपर्टी लोड नहीं हो सकीं"</string>
-    <string name="share_via" msgid="8725082736005677161">"इसके द्वारा साझा करें"</string>
+    <string name="share_via" msgid="8725082736005677161">"इसके ज़रिए शेयर करें"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"फ़ाइलें कॉपी हो रही हैं"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"फ़ाइलें कंप्रेस करना"</string>
     <string name="extract_notification_title" msgid="5067393961754430469">"फ़ाइलें निकाली जा रही हैं"</string>
@@ -156,8 +157,8 @@
       <item quantity="other">ये फ़ाइलें नहीं मिटाई गई थीं: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
-      <item quantity="one">ये फ़ाइलें किसी और प्रारूप में बदल दी गई थीं: <xliff:g id="LIST_1">%1$s</xliff:g></item>
-      <item quantity="other">ये फ़ाइलें किसी और प्रारूप में बदल दी गई थीं: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ये फ़ाइलें किसी और फ़ॉर्मेट में बदल दी गई थीं: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="other">ये फ़ाइलें किसी और फ़ॉर्मेट में बदल दी गई थीं: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम क्‍लिपबोर्ड पर कॉपी किए गए.</item>
@@ -168,9 +169,9 @@
     <string name="rename_error" msgid="6700093173508118635">"दस्‍तावेज़ का नाम बदलना विफल रहा"</string>
     <string name="menu_eject_root" msgid="9215040039374893613">"निकालें"</string>
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"कुछ फ़ाइलें रूपांतरित हो गई थीं"</string>
-    <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस देना चाहते हैं?"</string>
-    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस देना चाहते हैं?"</string>
-    <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो सहित, अपने डेटा का एक्सेस देना चाहते हैं?"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> डिक्शनरी तक पहुंचने देना चाहते हैं?"</string>
+    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> डिक्शनरी तक पहुंचने देना चाहते हैं?"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो के साथ, अपने डेटा तक पहुंचने देना चाहते हैं?"</string>
     <string name="never_ask_again" msgid="525908236522201138">"फिर से ना पूछें"</string>
     <string name="allow" msgid="1275746941353040309">"अनुमति दें"</string>
     <string name="deny" msgid="5127201668078153379">"अस्वीकार करें"</string>
@@ -185,23 +186,23 @@
     <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"\"<xliff:g id="NAME">%1$s</xliff:g>\" को हटाना चाहते हैं?"</string>
     <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"फ़ोल्डर \"<xliff:g id="NAME">%1$s</xliff:g>\" और उसकी सामग्रियों को हटाना चाहते हैं?"</string>
     <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाएं?</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाएं?</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें मिटाएं?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें मिटाएं?</item>
     </plurals>
     <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ोल्डर और उनकी सामग्री हटाएं?</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ोल्डर और उनकी सामग्री हटाएं?</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ोल्डर और उनकी सामग्री मिटाएं?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ोल्डर और उनकी सामग्री मिटाएं?</item>
     </plurals>
     <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम हटाएं?</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम हटाएं?</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम मिटाएं?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम मिटाएं?</item>
     </plurals>
     <string name="images_shortcut_label" msgid="2545168016070493574">"चित्र"</string>
-    <string name="archive_loading_failed" msgid="7243436722828766996">"ब्राउज़िंग के लिए संग्रह खोलने में असमर्थ. फ़ाइल या तो दूषित हो गई है या असमर्थित प्रारूप में है."</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"ब्राउज़िंग के लिए संग्रह नहीं खोला जा सका. फ़ाइल या तो इस्तेमाल के लायक नहीं रही या ऐसे फ़ॉर्मेट में है जो काम नहीं कर रहा."</string>
     <string name="name_conflict" msgid="28407269328862986">"इस नाम की एक फ़ाइल पहले से मौजूद है."</string>
-    <string name="authentication_required" msgid="8030880723643436099">"यह निर्देशिका देखने के लिए, <xliff:g id="NAME">%1$s</xliff:g> में प्रवेश करें"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"यह डिक्शनरी देखने के लिए, <xliff:g id="NAME">%1$s</xliff:g> में साइन इन करें"</string>
     <string name="cant_display_content" msgid="8633226333229417237">"सामग्रियां प्रदर्शित नहीं की जा सकतीं"</string>
-    <string name="sign_in" msgid="6253762676723505592">"प्रवेश करें"</string>
+    <string name="sign_in" msgid="6253762676723505592">"साइन इन करें"</string>
     <string name="new_archive_file_name" msgid="1604650338077249838">"संग्रह<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> को ओवरराइट करना चाहते हैं?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"बैकग्राउंड में जारी रखें"</string>
diff --git a/res/values-hr/inspector_strings.xml b/res/values-hr/inspector_strings.xml
new file mode 100644
index 0000000..3101ae1
--- /dev/null
+++ b/res/values-hr/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informacije"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Učitavanje informacija o datoteci nije uspjelo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Podaci o otklanjanju pogrešaka (samo razvoj)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Neobrađeni metapodaci: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Pojedinosti o medijma"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ova se vrsta datoteke otvara aplikacijom"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Datoteku pruža"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nije odabrano"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Nepoznato"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimenzije"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Nadmorska visina"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fotoaparat"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Otvor blende"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Brzina zatvarača"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Trajanje"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Snimljeno"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Žarišna duljina"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Izvođač"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Skladatelj"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokacija"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Vrste strujanja"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Neobrađena veličina (u bajtovima)"</string>
+</resources>
diff --git a/res/values-hr/mimes.xml b/res/values-hr/mimes.xml
new file mode 100644
index 0000000..44c9e28
--- /dev/null
+++ b/res/values-hr/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> datoteka"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Datoteka"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Slika"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> slika"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audiozapisi"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audiozapis"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Videozapisi"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> videozapis"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arhiva"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android aplikacija"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Obični tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint prezentacija"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel proračun. tablica"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google proračun. tablica"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google prezentacija"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google crtež"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google tablica"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google obrazac"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google karta"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google web-lokacija"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mapa"</string>
+</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 91a705f..b5315d2 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Sažmi"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Izdvoji u…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Promijeni naziv"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Svojstva"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Pogledajte informacije"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Prikaži na usluzi <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Novi prozor"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Izreži"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Premjesti"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Odbaci"</string>
     <string name="button_retry" msgid="4011461781916631389">"Pokušaj ponovo"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Izbriši"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Prikaži na davatelju usluga"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nije poredano"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Naziv"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Sažetak"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Vrsta"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veličina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmijenjeno"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Broj djece"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Broj stavki"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Uzlazno"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Silazno"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Prikaži korijene"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Datoteka se ne može otvoriti"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Nije moguće otvoriti datoteke u arhivama"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nije moguće izbrisati neke dokumente"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Učitavanje svojstava nije uspjelo"</string>
     <string name="share_via" msgid="8725082736005677161">"Dijeli putem"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiranje datoteka"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Sažimanje datoteka"</string>
diff --git a/res/values-hu/inspector_strings.xml b/res/values-hu/inspector_strings.xml
new file mode 100644
index 0000000..b27149f
--- /dev/null
+++ b/res/values-hu/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Információ"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Nem sikerült betölteni a fájl információit"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Hibakeresési információ (csak fejlesztőknek)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW-metaadatok: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Médiainformációk"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ezt a fájltípust a következő alkalmazás nyitja meg:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"A fájlt a következő biztosítja:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nincs kiválasztva"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Ismeretlen"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Méretek"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> × <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordináták"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Magasság"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fényképezőgép"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Rekesz"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Záridő"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Időtartam"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Felvétel ideje:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fókusztávolság"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-egyenérték"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Előadó"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Zeneszerző"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Helyadatok"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Streamtípusok"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW-méret (bájt)"</string>
+</resources>
diff --git a/res/values-hu/mimes.xml b/res/values-hu/mimes.xml
new file mode 100644
index 0000000..013e5ec
--- /dev/null
+++ b/res/values-hu/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-fájl"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fájl"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Kép"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-kép"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Hang"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-hang"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Videó"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-videó"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-archívum"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-alkalmazás"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Egyszerű szöveg"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokumentum"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokumentum"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-dokumentum"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-prezentáció"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-táblázat"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-dokumentum"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-táblázat"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-prezentáció"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-rajz"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-táblázat"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-űrlap"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-térkép"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-webhely"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mappa"</string>
+</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 2bc2d24..ed24c97 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Tömörítés"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Kicsomagolás ide…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Átnevezés"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Tulajdonságok"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Információ megjelenítése"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Megtekintés a következőben: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Új ablak"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Kivágás"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Áthelyezés"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Elvetés"</string>
     <string name="button_retry" msgid="4011461781916631389">"Próbálja újra"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Törlés"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Megjelenítés a szolgáltatónál"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nincs rendezve"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Név"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Összefoglalás"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Típus"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Méret"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Módosítva"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Gyermekek száma"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Elemek száma"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Növekvő"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Csökkenő"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Gyökérszint megjelenítése"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"A fájlt nem lehet megnyitni"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Az archívumban nem lehet fájlokat megnyitni"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Néhány dokumentumot nem lehet törölni"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Nem sikerült betölteni a tulajdonságokat"</string>
     <string name="share_via" msgid="8725082736005677161">"Megosztás itt:"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Fájlok másolása"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Fájlok tömörítése"</string>
diff --git a/res/values-hy/inspector_strings.xml b/res/values-hy/inspector_strings.xml
new file mode 100644
index 0000000..c13b686
--- /dev/null
+++ b/res/values-hy/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Տեղեկություններ"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Չհաջողվեց բեռնել ֆայլի տվյալները"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Վրիպազերծման տեղեկություններ (միայն մշակող)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw մետատվյալներ՝ <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Մեդիա տվյալներ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Այս տեսակի ֆայլերի բացման հավելվածը"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Այս ֆայլի մատակարարը"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ընտրված չէ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Անհայտ է"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Չափեր"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$.1f</xliff:g> ՄՊ"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Կոորդինատներ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Բարձրություն"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Տեսախցիկ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Բացվածք"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Պահաժամ"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Տևողությունը"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Լուսանկարվել է՝"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Ֆոկուսային հեռավորությունը"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> մմ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-ի համարժեք"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Կատարող"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Կոմպոզիտոր"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Ալբոմ"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Գտնվելու վայրը"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Հոսքի տեսակներ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw ֆայլի չափ (բայթ)"</string>
+</resources>
diff --git a/res/values-hy/mimes.xml b/res/values-hy/mimes.xml
new file mode 100644
index 0000000..660d7b3
--- /dev/null
+++ b/res/values-hy/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ֆայլ"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Ֆայլ"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Պատկեր"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> պատկեր"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Աուդիո"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> աուդիո"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Տեսանյութ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> տեսանյութ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> արխիվ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android հավելված"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Հասարակ տեքստ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML փաստաթուղթ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF փաստաթուղթ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word փաստաթուղթ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint ներկայացում"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel աղյուսակ"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google փաստաթուղթ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google աղյուսակ"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google ներկայացում"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google գծագիր"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google աղյուսակ"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ձև"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google քարտեզ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google կայք"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Պանակ"</string>
+</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 2156865..8d036a7 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Սեղմել"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Արտահանել…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Վերանվանել"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Հատկություններ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Տեղեկություններ"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Դիտել <xliff:g id="SOURCE">%1$s</xliff:g>-ում"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Նոր պատուհան"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Կտրել"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Տեղափոխել"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Փակել"</string>
     <string name="button_retry" msgid="4011461781916631389">"Փորձել նորից"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Մաքրել"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Ցուցադրել մատակարարում"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Տեսակավորված չեն"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Անունը"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Ամփոփագիր"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Տեսակը"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Չափը"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Փոփոխվել է"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Երեխաների թիվը"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Տարրերի քանակ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Աճման կարգով"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Նվազման կարգով"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Ցույց տալ արմատները"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Հնարավոր չէ բացել ֆայլը"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Հնարավոր չէ բացել արխիվացված ֆայլերը"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Հնարավոր չէ ջնջել որոշ փաստաթղթեր"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Հատկությունները հնարավոր չէ բեռնել"</string>
     <string name="share_via" msgid="8725082736005677161">"Կիսվել"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Ֆայլերի պատճենում"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Ֆայլերի սեղմում"</string>
diff --git a/res/values-in/inspector_strings.xml b/res/values-in/inspector_strings.xml
new file mode 100644
index 0000000..0964060
--- /dev/null
+++ b/res/values-in/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Info"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Info file tidak dapat dimuat"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Info debug (khusus dev)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadata raw: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detail media"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"File jenis ini dibuka dengan"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"File ini diberikan oleh"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Tidak dipilih"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Tidak diketahui"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensi"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinat"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Ketinggian"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Bukaan"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Kecepatan rana"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Durasi"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Diambil pada"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Panjang fokal"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Setara ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artis"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komposer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokasi"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Jenis streaming"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Ukuran raw (byte)"</string>
+</resources>
diff --git a/res/values-in/mimes.xml b/res/values-in/mimes.xml
new file mode 100644
index 0000000..a5664d5
--- /dev/null
+++ b/res/values-in/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"File <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Gambar"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Gambar <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arsip <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikasi Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Teks biasa"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokumen HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokumen PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokumen Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Presentasi PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Spreadsheet Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokumen Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Spreadsheet Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentasi Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Gambar Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabel Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulir Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Peta Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Situs Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 0da9252..8ef3466 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Kompresi"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Ekstrak ke…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Ganti nama"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Properti"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Dapatkan info"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Lihat di <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Jendela baru"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Potong"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Pindahkan"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Tutup"</string>
     <string name="button_retry" msgid="4011461781916631389">"Coba Lagi"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Hapus"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Tampilkan di provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Tidak diurutkan"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nama"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Ringkasan"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Jenis"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Ukuran"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Diubah"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Jumlah Anak"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Jumlah item"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Naik"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Turun"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Tampilkan root"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Tidak dapat membuka file"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Tidak dapat membuka file dalam arsip"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Tidak dapat menghapus beberapa dokumen"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Properti tidak dapat dimuat"</string>
     <string name="share_via" msgid="8725082736005677161">"Bagikan melalui"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Menyalin file"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Mengompres file"</string>
diff --git a/res/values-is/inspector_strings.xml b/res/values-is/inspector_strings.xml
new file mode 100644
index 0000000..72dc56b
--- /dev/null
+++ b/res/values-is/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Upplýsingar"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Ekki var hægt að hlaða skráarupplýsingar"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Kembiupplýsingar (aðeins þróunaraðilar)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Óunnin lýsigögn: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Efnisupplýsingar"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Þessi tegund af skrá opnast með"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Veita þessarar skráar er:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ekki valið"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Óþekkt"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Stærð"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Hnit"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Hæð"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Myndavél"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Ljósop"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Lokarahraði"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Tímalengd"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Tekin"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Brennivídd"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-jafngildi"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Flytjandi"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Höfundur"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Plata"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Staðsetning"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Streymisgerðir"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Óunnin stærð (bæti)"</string>
+</resources>
diff --git a/res/values-is/mimes.xml b/res/values-is/mimes.xml
new file mode 100644
index 0000000..b21d293
--- /dev/null
+++ b/res/values-is/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> skrá"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Skrá"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Mynd"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> mynd"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Hljóð"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> hljóð"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Myndskeið"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> myndskeið"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> geymsla"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android forrit"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Hreinn texti"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-skjal"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-skjal"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-skjal"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-kynning"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-töflureiknir"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google skjal"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google töflureiknir"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google kynning"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google teikning"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google tafla"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google eyðublað"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google kort"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google vefsvæði"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mappa"</string>
+</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 1a3cce8..b5be412 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Þjappa"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Flytja út í…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Endurnefna"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Eiginleikar"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Sækja upplýsingar"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Opna í <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nýr gluggi"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Klippa"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Færa"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Hunsa"</string>
     <string name="button_retry" msgid="4011461781916631389">"Reyna aftur"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Hreinsa"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Sýna í þjónustu"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ekki flokkuð"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Heiti"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Samantekt"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Gerð"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Stærð"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Breytt"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Fjöldi barna"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Fjöldi atriða"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Hækkandi"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Lækkandi"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Sýna rótarsöfn"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Ekki hægt að opna skrá"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Ekki er hægt að opna skrár í geymslu"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Ekki hægt að eyða einhverjum skjölum"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Ekki tókst að sækja eiginleika"</string>
     <string name="share_via" msgid="8725082736005677161">"Deila í gegnum"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Afritar skrár"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Þjappar skrám"</string>
diff --git a/res/values-it/inspector_strings.xml b/res/values-it/inspector_strings.xml
new file mode 100644
index 0000000..fcc7c83
--- /dev/null
+++ b/res/values-it/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informazioni"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Impossibile caricare le informazioni del file"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informazioni di debug (solo sviluppatori)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadati non elaborati: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Dettagli contenuti multimediali"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Questo tipo di file viene aperto con"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Questo file è fornito da"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Non selezionata"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Sconosciuto"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensioni"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitudine"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fotocamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Apertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocità otturatore"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Durata"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Data/ora"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Lunghezza focale"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO equivalenti"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositore"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Geolocalizzazione"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipi di stream"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Dimensioni file non elaborato (byte)"</string>
+</resources>
diff --git a/res/values-it/mimes.xml b/res/values-it/mimes.xml
new file mode 100644
index 0000000..cffc59c
--- /dev/null
+++ b/res/values-it/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"File <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Immagine"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Immagine <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archivio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Applicazione Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Solo testo"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Presentazione PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Foglio di calcolo Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Foglio di lavoro Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentazione Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Disegno Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabella Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Modulo Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mappa Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Sito Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Cartella"</string>
+</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 8f6403e..fcf7baa 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimi"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Estrai in…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Rinomina"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Proprietà"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Informazioni"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Visualizza in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nuova finestra"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Taglia"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Sposta"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ignora"</string>
     <string name="button_retry" msgid="4011461781916631389">"Riprova"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Cancella"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostra in provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nessun ordine"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nome"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Riepilogo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Dimensioni"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ultima modifica"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Numero di figli"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Numero di elementi"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Crescente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Decrescente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostra nodi principali"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Impossibile aprire il file."</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Impossibile aprire i file negli archivi"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Impossibile eliminare alcuni documenti."</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Impossibile caricare le proprietà"</string>
     <string name="share_via" msgid="8725082736005677161">"Condividi tramite"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copia dei file in corso"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compressione di file"</string>
diff --git a/res/values-iw/inspector_strings.xml b/res/values-iw/inspector_strings.xml
new file mode 100644
index 0000000..e47dd80
--- /dev/null
+++ b/res/values-iw/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"מאפיינים"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"לא ניתן היה לטעון את פרטי הקובץ"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"מידע על ניפוי באגים (פיתוח בלבד)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"‏סוג המטא נתונים של קובץ ה-RAW: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"פרטי הקבצים"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"אפשר לפתוח קבצים מהסוג הזה באמצעות"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"הקובץ סופק על ידי"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"לא נבחרה"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"לא ידועה"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"מידות"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"‏<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>‏ - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"קואורדינטות"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"גובה"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"מצלמה"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"צמצם"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"מהירות תריס"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"משך"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"צולם ב-"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"אורך מוקד"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> מ\"מ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‏רגישות לאור (שווה ערך ל-ISO)"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>‎"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"אמן"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"מלחין"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"אלבום"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"מיקום"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Stream types"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"‏גודל קובץ RAW (בייט)"</string>
+</resources>
diff --git a/res/values-iw/mimes.xml b/res/values-iw/mimes.xml
new file mode 100644
index 0000000..b871900
--- /dev/null
+++ b/res/values-iw/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"קובץ <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"קובץ"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"תמונה"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"תמונה בפורמט <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"אודיו"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"אודיו בפורמט <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"וידאו"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"קובץ וידאו בפורמט <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"קובץ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"‏אפליקציית Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"טקסט פשוט"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"‏מסמך HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"‏קובץ PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"‏מסמך Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"‏מצגת PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"‏גיליון אלקטרוני ב-Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"‏מסמך ב-Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"‏גיליון אלקטרוני ב-Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"‏מצגת ב-Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"‏שרטוט ב-Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"‏טבלה ב-Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"‏טופס ב-Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"‏מפה ב-Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"‏אתר ב-Google Sites"</string>
+    <string name="directory_type" msgid="2702987727566226354">"תיקיה"</string>
+</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 0ea688e..7a45d7f 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -27,21 +27,21 @@
     <string name="menu_create_dir" msgid="2413624798689091042">"תיקיה חדשה"</string>
     <string name="menu_grid" msgid="1453636521731880680">"תצוגת רשת"</string>
     <string name="menu_list" msgid="6714267452146410402">"תצוגת רשימה"</string>
-    <string name="menu_search" msgid="1876699106790719849">"חפש"</string>
+    <string name="menu_search" msgid="1876699106790719849">"חיפוש"</string>
     <string name="menu_settings" msgid="6520844520117939047">"הגדרות אחסון"</string>
     <string name="menu_open" msgid="9092138100049759315">"פתח"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"פתיחה באמצעות"</string>
     <string name="menu_open_in_new_window" msgid="6686563636123311276">"פתיחה בחלון חדש"</string>
-    <string name="menu_save" msgid="5195367497138965168">"שמור"</string>
+    <string name="menu_save" msgid="5195367497138965168">"שמירה"</string>
     <string name="menu_share" msgid="4307140947108068356">"שתף"</string>
-    <string name="menu_delete" msgid="1022254131543256626">"מחק"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"מחיקה"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"בחר הכל"</string>
     <string name="menu_copy" msgid="7404820171352314754">"העתק אל…"</string>
     <string name="menu_move" msgid="2310760789561129882">"העבר אל…"</string>
     <string name="menu_compress" msgid="37539111904724188">"דחוס"</string>
     <string name="menu_extract" msgid="8171946945982532262">"חלץ לתיקייה…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"שנה שם"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"מאפיינים"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"מידע על המסמך"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"הצג ב-<xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"חלון חדש"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"גזור"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"העבר"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ביטול"</string>
     <string name="button_retry" msgid="4011461781916631389">"נסה שנית"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ניקוי"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"הצג באפליקציה של הספק"</string>
     <string name="not_sorted" msgid="7813496644889115530">"לא ממוין"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"שם"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"סיכום"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"סוג"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"גודל"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"שינוי אחרון"</string>
-    <string name="directory_children" msgid="8115290268549503262">"מספר הבנים"</string>
+    <string name="directory_items" msgid="6645621978998614003">"מספר הפריטים"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"סדר עולה"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"סדר יורד"</string>
     <string name="drawer_open" msgid="8071673398187261741">"הצג שורשים"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"לא ניתן לפתוח את הקובץ"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"לא ניתן לפתוח קבצים בארכיונים"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"לא ניתן למחוק חלק מהמסמכים"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"לא ניתן היה לטעון מאפיינים"</string>
     <string name="share_via" msgid="8725082736005677161">"שתף באמצעות"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"מעתיק קבצים"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"דוחס קבצים"</string>
diff --git a/res/values-ja/inspector_strings.xml b/res/values-ja/inspector_strings.xml
new file mode 100644
index 0000000..eb9737a
--- /dev/null
+++ b/res/values-ja/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"情報"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ファイル情報を読み込めませんでした"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"デバッグ情報(デベロッパーのみ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"未加工のメタデータ: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"メディアの詳細"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"このファイル形式を開けるアプリ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"このファイルの提供元"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"未選択"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"不明"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"サイズ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"座標"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"高度"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"カメラ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"絞り"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"シャッター スピード"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"時間"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"撮影"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"レンズ焦点距離"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO 相当"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"アーティスト"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"作曲者"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"アルバム"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"場所"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ストリーム タイプ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"未加工のサイズ(バイト)"</string>
+</resources>
diff --git a/res/values-ja/mimes.xml b/res/values-ja/mimes.xml
new file mode 100644
index 0000000..ce62382
--- /dev/null
+++ b/res/values-ja/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ファイル"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ファイル"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"画像"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> 画像"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"音声"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> 音声"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"動画"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> 動画"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> アーカイブ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android アプリ"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"書式なしテキスト"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ドキュメント"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ドキュメント"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ドキュメント"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint プレゼンテーション"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel スプレッドシート"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ドキュメント"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google スプレッドシート"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google プレゼンテーション"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google 図形描画"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google Table"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google フォーム"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google マップ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google サイト"</string>
+    <string name="directory_type" msgid="2702987727566226354">"フォルダ"</string>
+</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index fc101fb..c06bf9b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"圧縮"</string>
     <string name="menu_extract" msgid="8171946945982532262">"次の場所に解凍…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"名前を変更"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"プロパティ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"情報を見る"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>に表示"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"新しいウィンドウ"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"切り取り"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"移動"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"非表示"</string>
     <string name="button_retry" msgid="4011461781916631389">"再試行"</string>
+    <string name="button_clear" msgid="5412304437764369441">"削除"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"プロバイダで表示"</string>
     <string name="not_sorted" msgid="7813496644889115530">"並べ替えなし"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"名前"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"概要"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"タイプ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"サイズ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"最終変更"</string>
-    <string name="directory_children" msgid="8115290268549503262">"子供の数"</string>
+    <string name="directory_items" msgid="6645621978998614003">"アイテム数"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"昇順"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"降順"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ルートを表示する"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ファイルを開けません"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"アーカイブ内のファイルを開くことはできません"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"一部のドキュメントを削除できません"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"プロパティを読み込めませんでした"</string>
     <string name="share_via" msgid="8725082736005677161">"共有ツール"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ファイルのコピー中"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ファイルの圧縮中"</string>
diff --git a/res/values-ka/inspector_strings.xml b/res/values-ka/inspector_strings.xml
new file mode 100644
index 0000000..bb3cab1
--- /dev/null
+++ b/res/values-ka/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ინფორმაცია"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ფაილის ინფორმაციის ჩატვირთვა ვერ მოხერხდა"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"შეცდომების გამართვის ინფორმაცია (მხოლოდ დეველ.)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ნედლი მეტა-მონაცემები: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"მედიის დეტალები"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ამ ტიპის ფაილი იხსნება"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ფაილის მომწოდებელი:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"არ არის არჩეული"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"უცნობი"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ზომები"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> — <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>მეგაპიქსელი"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"კოორდინატები"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"სიმაღლე"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"კამერა"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g>, <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"აპერტურა"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ობიექტივის საკეტის სისწრაფე"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ხანგრძლივობა"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"გადაღებულია:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ფოკუსური მანძილი"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>მმ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-ს ეკვივალენტი"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO: <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"შემსრულებელი"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"კომპოზიტორი"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ალბომი"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"მდებარეობა"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"სტრიმინგის ტიპები"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ნედლი ზომა (ბაიტები)"</string>
+</resources>
diff --git a/res/values-ka/mimes.xml b/res/values-ka/mimes.xml
new file mode 100644
index 0000000..8264d81
--- /dev/null
+++ b/res/values-ka/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ფაილი"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ფაილი"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"სურათი"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> სურათი"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"აუდიო"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> აუდიო"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ვიდეო"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ვიდეო"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> არქივი"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-ის აპლიკაცია"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ჩვეულებრივი ტექსტი"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML დოკუმენტი"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF დოკუმენტი"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word დოკუმენტი"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint პრეზენტაცია"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-ის ელცხრილი"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google დოკუმენტი"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google ელცხრილი"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google პრეზენტაცია"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ნახაზი"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google ცხრილი"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ფორმა"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google რუკა"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google საიტი"</string>
+    <string name="directory_type" msgid="2702987727566226354">"საქაღალდე"</string>
+</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 506d232..4868fc5 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"შეკუმშვა"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ამოღება…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"გადარქმევა"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"მახასიათებლები"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"ინფორმაციის მიღება"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>-ში ნახვა"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"ახალი ფანჯარა"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ამოჭრა"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"გადაადგილება"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"უარყოფა"</string>
     <string name="button_retry" msgid="4011461781916631389">"ხელახლა ცდა"</string>
+    <string name="button_clear" msgid="5412304437764369441">"გასუფთავება"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"პროვაიდერში ჩვენება"</string>
     <string name="not_sorted" msgid="7813496644889115530">"დაულაგებელი"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"სახელი"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"რეზიუმე"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ტიპი"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ზომა"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ცვლილება"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ბავშვთა რაოდენობა"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ერთეულების რაოდენობა"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ზრდადი"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"კლებადი"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ფესვების ჩვენება"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ფაილის გახსნა ვერ ხერხდება"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"არქივებში განთავსებული ფაილების გახსნა ვერ მოხერხდა"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"მახასიათებლების ჩატვირთვა ვერ მოხერხდა"</string>
     <string name="share_via" msgid="8725082736005677161">"გაზიარება…"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ფაილების კოპირება…"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"მიმდინარეობს ფაილების შეკუმშვა"</string>
diff --git a/res/values-kk/inspector_strings.xml b/res/values-kk/inspector_strings.xml
new file mode 100644
index 0000000..88991f3
--- /dev/null
+++ b/res/values-kk/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Ақпарат"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Файл ақпараты жүктелмеді"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Түзету туралы ақпарат (тек әзірлеуші)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW метадеректері: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Медиамазмұн деректері"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Мұндай файл түрі келесі қолданбамен ашылады"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Файлды ұсынушы"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Таңдалмады"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Белгісіз"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Өлшемдер"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> МП"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координаталар"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Биіктік"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aпертура"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Ысырма жылдамдығы"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Ұзақтығы"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Түсірілді"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокус қашықтығы"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO баламасы"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO жылдамдығы: <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Орындаушы"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Альбом"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Орын"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Трансляция түрлері"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW файлының өлшемі (байт)"</string>
+</resources>
diff --git a/res/values-kk/mimes.xml b/res/values-kk/mimes.xml
new file mode 100644
index 0000000..166d2ed
--- /dev/null
+++ b/res/values-kk/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> файлы"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Сурет"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> суреті"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Aудио"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> аудиофайлы"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Бейне"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> бейнефайлы"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> мұрағаты"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android қолданбасы"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Қарапайым мәтін"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML құжаты"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF құжаты"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word құжаты"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint көрсетілімі"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel электрондық кестесі"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google құжаты"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google электрондық кестесі"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google көрсетілімі"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google суреті"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google кестесі"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google үлгісі"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google картасы"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google сайты"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Қалта"</string>
+</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index b466594..00a6a72 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Сығу"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Алынуда…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Атауын өзгерту"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Сипаттары"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Ақпарат алу"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> ішінде көру"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Жаңа терезе"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Қиып алу"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Тасымалдау"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Жабу"</string>
     <string name="button_retry" msgid="4011461781916631389">"Әрекетті қайталау"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Өшіру"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Провайдерде көрсету"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Сұрыпталмаған"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Аты"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Жиынтық мәлімет"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tүрі"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Көлемі"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Өзгертілген уақыты"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Балалар саны"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Элементтер саны"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Арту ретімен"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Кему ретімен"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Түбір қалтаны көрсету"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Файл ашылмады"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Мұрағаттағы файлдар ашылмайды"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Кейбір құжаттар жойылмады"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Сипаттар жүктелмеді"</string>
     <string name="share_via" msgid="8725082736005677161">"Бөлісу әдісі"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Файлдар көшірілуде"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Файлдар сығу"</string>
@@ -110,7 +111,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жойылуда.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жойылуда.</item>
     </plurals>
-    <string name="undo" msgid="2902438994196400565">"Кері қайтару"</string>
+    <string name="undo" msgid="2902438994196400565">"Қайтару"</string>
     <string name="copy_preparing" msgid="5326063807006898223">"Көшіруге дайындау…"</string>
     <string name="compress_preparing" msgid="6650018601382062672">"Сығуға дайындалуда…"</string>
     <string name="extract_preparing" msgid="58266275455027829">"Шығарып алуға дайындалуда…"</string>
diff --git a/res/values-km/inspector_strings.xml b/res/values-km/inspector_strings.xml
new file mode 100644
index 0000000..a199a86
--- /dev/null
+++ b/res/values-km/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ព័ត៌មាន"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"មិនអាច​ផ្ទុកព័ត៌មាន​ឯកសារបានទេ"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ព័ត៌មាន​អំពីការ​ជួសជុល (dev ប៉ុណ្ណោះ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ទិន្នន័យមេតា​ដើម៖ <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"ព័ត៌មាន​លម្អិតអំពី​មេឌៀ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ប្រភេទ​ឯកសារ​នេះបើក​ដោយប្រើ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ឯកសារនេះ​ត្រូវបានផ្ដល់ដោយ"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"មិនបាន​ជ្រើសរើស"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"មិន​ស្គាល់"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ទំហំ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"កូអរដោណេ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"រយៈកម្ពស់"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"កាមេរ៉ា"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ជម្រៅ​រូបភាព"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ល្បឿនពន្លឺរូបថត"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"រយៈពេល"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ថត​នៅថ្ងៃទី"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ប្រវែង​ផ្ដោត"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ល្បឿន ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"សិល្បករ"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"អ្នកតាក់តែង"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"អាល់ប៊ុម"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ទីកន្លែង"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ប្រភេទការផ្សាយ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ទំហំដើម (បៃ)"</string>
+</resources>
diff --git a/res/values-km/mimes.xml b/res/values-km/mimes.xml
new file mode 100644
index 0000000..3c16552
--- /dev/null
+++ b/res/values-km/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"ឯកសារ <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ឯកសារ​"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"រូបភាព"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"រូបភាព <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"សំឡេង"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"សំឡេង <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"វីដេអូ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"វីដេអូ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"បណ្ណសារ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"កម្មវិធី Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"អត្ថបទធម្មតា"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"ឯកសារ HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"ឯកសារ PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"ឯកសារ Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"បទបង្ហាញ PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"បញ្ជី Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ឯកសារ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"បញ្ជី Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google បទ​បង្ហាញ"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google គំនូរ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google តារាង"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ទម្រង់បែបបទ"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google ផែនទី"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"ទំព័រ Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ថត"</string>
+</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 046f1e5..137b870 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"បង្ហាប់"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ស្រង់​ទៅ…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"ប្ដូរឈ្មោះ"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"លក្ខណៈសម្បត្តិ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"ទទួល​ព័ត៌មាន"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"មើល​នៅក្នុង <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"ផ្ទាំងវិនដូថ្មី"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"កាត់"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ផ្លាស់ទី"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"បដិសេធ"</string>
     <string name="button_retry" msgid="4011461781916631389">"ព្យាយាម​ម្តង​ទៀត"</string>
+    <string name="button_clear" msgid="5412304437764369441">"សម្អាត"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"បង្ហាញ​នៅក្នុង​ក្រុមហ៊ុន​ផ្តល់សេវា"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Not sorted"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"ឈ្មោះ"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"សេចក្តីសង្ខេប"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ប្រភេទ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ទំហំ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"បានកែសម្រួល"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ចំនួន​កុមារ"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ចំនួន​ធាតុ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ឡើង"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ចុះ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"បង្ហាញ roots"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"មិនអាចបើកឯកសារបានទេ"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"មិនអាចបើក​ឯកសារ​នៅក្នុងបណ្ណសារបានទេ"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"មិនអាចលុបឯកសារមួយចំនួន"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"មិន​អាចផ្ទុក​លក្ខណសម្បត្តិបានទេ"</string>
     <string name="share_via" msgid="8725082736005677161">"ចែករំលែក​តាម"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"កំពុងចម្លងឯកសារ"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"កំពុង​បង្ហាប់​ឯកសារ"</string>
diff --git a/res/values-kn/inspector_strings.xml b/res/values-kn/inspector_strings.xml
new file mode 100644
index 0000000..29481bb
--- /dev/null
+++ b/res/values-kn/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ಮಾಹಿತಿ"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಲೋಡ್ ಮಾಡಲಾಗಲಿಲ್ಲ"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ಡೀಬಗ್‌ ಮಾಹಿತಿ (dev ಮಾತ್ರ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw ಮೆಟಾಡೇಟಾ: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"ಮಾಧ್ಯಮ ವಿವರಗಳು"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ಈ ಪ್ರಕಾರದ ಫೈಲ್ ಇದರ ಮೂಲಕ ತೆರೆಯುತ್ತದೆ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ಈ ಫೈಲ್ ಅನ್ನು ವಿತರಿಸಿದವರು"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ಆಯ್ಕೆಮಾಡಲಾಗಿಲ್ಲ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"ಅಪರಿಚಿತ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ಅಳತೆಗಳು"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>ಎಮ್‌ಪಿ"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ಅಕ್ಷಾಂಶಗಳು"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ಎತ್ತರ"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ಕ್ಯಾಮರಾ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ಅಪರ್ಚರ್‌‌"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ಶಟರ್ ವೇಗ"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ಅವಧಿ"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ತೆಗೆದುಕೊಂಡಾಗ"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ಫೋಕಲ್ ಅಂತರ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>ಮಿಮೀ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ಸಮಾನ"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"ಕಲಾವಿದರು"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"ಸಂಯೋಜಕ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ಆಲ್ಬಮ್‌"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ಸ್ಥಳ"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ಸ್ಟ್ರೀಮ್ ವಿಧಗಳು"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW ಗಾತ್ರ (ಬೈಟ್‌ಗಳು)"</string>
+</resources>
diff --git a/res/values-kn/mimes.xml b/res/values-kn/mimes.xml
new file mode 100644
index 0000000..515c423
--- /dev/null
+++ b/res/values-kn/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ಫೈಲ್"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ಫೈಲ್"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ಚಿತ್ರ"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> ಚಿತ್ರ"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ಆಡಿಯೋ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ಆಡಿಯೋ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ವೀಡಿಯೊ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ವೀಡಿಯೊ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> ಆರ್ಕೈವ್ ಮಾಡಿ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ಅಪ್ಲಿಕೇಶನ್"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ಸರಳ ಪಠ್ಯ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ಡಾಕ್ಯುಮೆಂಟ್"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ಡಾಕ್ಯುಮೆಂಟ್"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ಡಾಕ್ಯುಮೆಂಟ್‌"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint ಪ್ರಸ್ತುತಿ"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel ಸ್ಪ್ರೆಡ್‌ಶೀಟ್‌"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ಡಾಕ್ಯುಮೆಂಟ್"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google ಸ್ಪ್ರೆಡ್‌ಶೀಟ್"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google ಪ್ರಸ್ತುತಿ"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ರೇಖಾಚಿತ್ರ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google ಟೇಬಲ್"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ಫಾರ್ಮ್"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google ನಕ್ಷೆ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google ಸೈಟ್"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ಫೋಲ್ಡರ್"</string>
+</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index a199277..920af9d 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"ಕುಗ್ಗಿಸಿ"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ಇದಕ್ಕೆ ಬೇರ್ಪಡಿಸಲಾಗಿದೆ…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"ಮರುಹೆಸರಿಸು"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"ಗುಣಲಕ್ಷಣಗಳು"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಿರಿ"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> ನಲ್ಲಿ ವೀಕ್ಷಿಸಿ"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"ಹೊಸ ವಿಂಡೋ"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ಕತ್ತರಿಸು"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ಸರಿಸು"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ವಜಾಗೊಳಿಸಿ"</string>
     <string name="button_retry" msgid="4011461781916631389">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ತೆರವುಗೊಳಿಸಿ"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ಒದಗಿಸುವವರಲ್ಲಿ ತೋರಿಸಿ"</string>
     <string name="not_sorted" msgid="7813496644889115530">"ವಿಂಗಡಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"ಹೆಸರು"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"ಸಾರಾಂಶ"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ಪ್ರಕಾರ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ಗಾತ್ರ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ಮಾರ್ಪಾಡು"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ಮಕ್ಕಳ ಸಂಖ್ಯೆ"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ಐಟಂಗಳ ಸಂಖ್ಯೆ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ಆರೋಹಣ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ಅವರೋಹಣ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ರೂಟ್‌ಗಳನ್ನು ತೋರಿಸು"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"ಆರ್ಕೈವ್‌ಗಳಲ್ಲಿ ಫೈಲ್‌ಗಳನ್ನು ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"ಕೆಲವು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"ಗುಣಲಕ್ಷಣಗಳನ್ನು ಲೋಡ್ ಮಾಡುವುದು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="share_via" msgid="8725082736005677161">"ಈ ಮೂಲಕ ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ಫೈಲ್‌ ಕುಗ್ಗಿಸಲಾಗುತ್ತಿದೆ"</string>
@@ -166,7 +167,7 @@
     <string name="file_operation_rejected" msgid="4301554203329008794">"ಫೈಲ್ ಕಾರ್ಯಾಚರಣೆಗೆ ಬೆಂಬಲವಿಲ್ಲ."</string>
     <string name="file_operation_error" msgid="2234357335716533795">"ಫೈಲ್ ಕಾರ್ಯಾಚರಣೆ ವಿಫಲವಾಗಿದೆ."</string>
     <string name="rename_error" msgid="6700093173508118635">"ಡಾಕ್ಯುಮೆಂಟ್ ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
-    <string name="menu_eject_root" msgid="9215040039374893613">"ಎಜೆಕ್ಟ್‌‌"</string>
+    <string name="menu_eject_root" msgid="9215040039374893613">"ಇಜೆಕ್ಟ್‌‌"</string>
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"ಕೆಲವು ಫೈಲ್‌ಗಳನ್ನು ಪರಿವರ್ತಿಸಲಾಗಿದೆ"</string>
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> ರಲ್ಲಿ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಗೆ ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
diff --git a/res/values-ko/inspector_strings.xml b/res/values-ko/inspector_strings.xml
new file mode 100644
index 0000000..97acd80
--- /dev/null
+++ b/res/values-ko/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"정보"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"파일 정보를 로드할 수 없습니다"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"디버그 정보(개발자 전용)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"원본 메타데이터: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"미디어 세부정보"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"이 유형의 파일에 연결된 앱"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"파일 제공자:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"선택되지 않음"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"알 수 없음"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"크기"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g>x<xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"좌표"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"고도"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"카메라"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"조리개"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"셔터 속도"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"시간"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"촬영 일시"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"초점 거리"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO 등급"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"아티스트"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"작곡가"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"앨범"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"위치"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"스트림 유형"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"원본 크기(바이트)"</string>
+</resources>
diff --git a/res/values-ko/mimes.xml b/res/values-ko/mimes.xml
new file mode 100644
index 0000000..769d97a
--- /dev/null
+++ b/res/values-ko/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> 파일"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"파일"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"이미지"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> 이미지"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"오디오"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> 오디오"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"동영상"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> 동영상"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> 보관 파일"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android 애플리케이션"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"일반 텍스트"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML 문서"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF 문서"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word 문서"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint 프레젠테이션"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel 스프레드시트"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google 문서"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google 스프레드시트"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google 프레젠테이션"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google 드로잉"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google 표"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google 설문지"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google 지도"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google 사이트"</string>
+    <string name="directory_type" msgid="2702987727566226354">"폴더"</string>
+</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d2e3084..d2072cd 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"압축"</string>
     <string name="menu_extract" msgid="8171946945982532262">"다음 위치에 추출..."</string>
     <string name="menu_rename" msgid="1883113442688817554">"이름 바꾸기"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"속성"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"정보 확인"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>에서 보기"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"새 창"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"잘라내기"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"이동"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"닫기"</string>
     <string name="button_retry" msgid="4011461781916631389">"다시 시도"</string>
+    <string name="button_clear" msgid="5412304437764369441">"삭제"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"제공업체 앱에서 보기"</string>
     <string name="not_sorted" msgid="7813496644889115530">"정렬되지 않음"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"이름"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"요약"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"형식"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"크기"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"마지막 수정 시간"</string>
-    <string name="directory_children" msgid="8115290268549503262">"자녀 수"</string>
+    <string name="directory_items" msgid="6645621978998614003">"항목 수"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"오름차순"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"내림차순"</string>
     <string name="drawer_open" msgid="8071673398187261741">"루트 표시"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"파일을 열 수 없습니다."</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"보관 파일 안에 있는 파일은 열 수 없습니다."</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"일부 문서를 삭제할 수 없습니다."</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"속성을 로드할 수 없습니다."</string>
     <string name="share_via" msgid="8725082736005677161">"공유에 사용할 앱"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"파일 복사"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"파일 압축 중"</string>
diff --git a/res/values-ky/inspector_strings.xml b/res/values-ky/inspector_strings.xml
new file mode 100644
index 0000000..a120911
--- /dev/null
+++ b/res/values-ky/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Маалымат"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Файл жөнүндө маалымат жүктөлбөй койду"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Мүчүлүштүктөрдү оңдоо маалыматы (түзм. гана)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Баштапкы метадата: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Медиа маалымат"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Файлдын мындай түрү төмөнкү колдонмо менен ачылат"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Бул файлды жасаган тутум"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Тандалган жок"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Белгисиз"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Чен-өлчөмү"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>Мпикс."</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координаталар"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Бийиктик"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Апертура"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Жапкычтын ылдамдыгы"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Узактыгы"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Тартылган күнү"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокустук аралык"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO эквиваленти"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Аткаруучу"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Альбом"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Жайгашкан жер"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Агымдын түрү"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Баштапкы өлчөмү (байт)"</string>
+</resources>
diff --git a/res/values-ky/mimes.xml b/res/values-ky/mimes.xml
new file mode 100644
index 0000000..8eb7cd6
--- /dev/null
+++ b/res/values-ky/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> файлы"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Сүрөт"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> сүрөтү"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудио"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> форматындагы аудио файл"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Видео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> видеосу"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> форматындагы архив"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android колдонмосу"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Жөнөкөй текст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML документи"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF документи"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word документи"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint презентациясы"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel электрондук жадыбалы"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google документи"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google электрондук жадыбалы"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google презентациясы"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google чиймеси"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google жадыбалы"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google формасы"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google картасы"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google сайты"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Папка"</string>
+</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 5f98eaa..b92c8db 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Кысуу"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Төмөнкүгө чыгаруу…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Аталышын өзгөртүү"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Касиеттери"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Маалымат алуу"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> аркылуу көрүү"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Жаңы терезе"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Кесүү"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Жылдыруу"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Көз жаздымда калтыруу"</string>
     <string name="button_retry" msgid="4011461781916631389">"Кайра аракет кылыңыз"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Тазалоо"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Демейки колдонмодон көрсөтүү"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ылганган эмес"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Аты"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Жыйынтыгы"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Түрү"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Өлчөмү"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Өзгөрүлгөн"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Балдардын саны"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Элементтердин саны"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Чоңойгон ыраатта"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Кичирейген ыраатта"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Папкаларды көрсөтүү"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Файл ачылбай жатат"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Архивделген файлдарды ачуу мүмкүн эмес"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Кээ бир документтерди өчүрүү мүмкүн болбой жатат"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Касиеттери жүктөлбөй койду"</string>
     <string name="share_via" msgid="8725082736005677161">"Бул аркылуу бөлүшүү"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Файлдар көчүрүлүүдө"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Файлдар кысылууда"</string>
diff --git a/res/values-lo/inspector_strings.xml b/res/values-lo/inspector_strings.xml
new file mode 100644
index 0000000..6d02420
--- /dev/null
+++ b/res/values-lo/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ຂໍ້ມູນ"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ບໍ່ສາມາດໂຫຼດຂໍ້ມູນໄຟລ໌ໄດ້"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ຂໍ້ມູນດີບັກ (ນັກພັດທະນາເທົ່ານັ້ນ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ເມເຕເດຕາ Raw: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"ລາຍລະອຽດມີເດຍ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ໄຟລ໌ປະເພດນີ້ເປີດດ້ວຍ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ໄຟລ໌ນີ້ຖືກຈຳໜ່າຍໃຫ້ໂດຍ"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ບໍ່ໄດ້ເລືອກ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ຂະໜາດພາບ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ພິກັດ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ຄວາມສູງ"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ກ້ອງຖ່າຍຮູບ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ຮູຮັບແສງ"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ຄວາມໄວຊັດເຕີ"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ໄລຍະເວລາ"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ຖ່າຍເມື່ອ"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ທາງຍາວໂຟກັສ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ທຽບເທົ່າ"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"ສິນລະປິນ"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"ຜູ້ແຕ່ງ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ອະລະບໍ້າ"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ສະຖານທີ່"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ປະເພດສະຕຣີມ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ຂະໜາດ Raw (ໄບຕ໌)"</string>
+</resources>
diff --git a/res/values-lo/mimes.xml b/res/values-lo/mimes.xml
new file mode 100644
index 0000000..55775c2
--- /dev/null
+++ b/res/values-lo/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"ໄຟລ໌ <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ໄຟລ໌"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ຮູບພາບ"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"ຮູບພາບ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ໄຟລ໌ສຽງ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"ໄຟລ໌ສຽງ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ວິດີໂອ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"ວິດີໂອ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"ແຟ້ມຈັດເກັບ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"ແອັບພລິເຄຊັນ Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ຂໍ້ຄວາມທຳມະດາ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"ເອກະສານ HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"ເອກະສານ PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"ເອກະສານ Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"ພຣີເຊັນເທເຊິນ PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"ສະເປຣດຊີດ Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"ເອກະສານ Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"ສະເປຣດຊີດ Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"ພຣີເຊັນເທເຊິນ Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"ແບບແຕ້ມ Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"ຕາຕາລາງ Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"ແບບຟອມ Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"ແຜນທີ່ Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"ເວັບໄຊ Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ໂຟນເດີ"</string>
+</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 1e53a8e..320075e 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"ບີບອັດ"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ແຕກໄຟລ໌ໄປ…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"ປ່ຽນຊື່"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"ຄຸນສົມບັດ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"ຂໍຂໍ້ມູນ"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"ເບິ່ງໃນ <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"ໜ້າຈໍໃໝ່"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ຕັດ"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ຍ້າຍ"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ປິດໄວ້"</string>
     <string name="button_retry" msgid="4011461781916631389">"ລອງໃໝ່ອີກເທື່ອໜຶ່ງ"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ລຶບລ້າງ"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ສະແດງໃນຜູ້ໃຫ້ບລິການ"</string>
     <string name="not_sorted" msgid="7813496644889115530">"ບໍ່ໄດ້ຈັດຮຽງ"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"ຊື່"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"ສະຫຼຸບ"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ປະເພດ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ຂະໜາດ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ແກ້ໄຂເມື່ອ"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ຈຳນວນຂອງລູກ"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ຈໍານວນລາຍການ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ໃຫຍ່ຫານ້ອຍ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ນ້ອຍຫາໃຫຍ່"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ສະແດງ roots"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"ບໍ່ສາມາດເປີດໄຟລ໌ໃນແຟ້ມຈັດເກັບໄດ້"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"ບໍ່ສາມາດໂຫຼດຄຸນສົມບັດໄດ້"</string>
     <string name="share_via" msgid="8725082736005677161">"ແບ່ງປັນຜ່ານ"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ກຳລັງສຳເນົາໄຟລ໌"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ກຳລັງບີບອັດໄຟລ໌"</string>
diff --git a/res/values-lt/inspector_strings.xml b/res/values-lt/inspector_strings.xml
new file mode 100644
index 0000000..20c28bb
--- /dev/null
+++ b/res/values-lt/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informacija"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Nepavyko įkelti failo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Derinimo informacija (tik kūrėjams)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Neapdoroto failo metaduomenys: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Išsami medijos informacija"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Šio tipo failas atidaromas naudojant"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Šį failą teikia"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nepasirinkta"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Nežinoma"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Matmenys"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinatės"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Aukštis virš jūros lygio"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fotoaparatas"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Diafragma"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Užrakto greitis"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Trukmė"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Nufotografuota"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Židinio nuotolis"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalentas"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Atlikėjas"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Kompozitorius"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albumas"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Vieta"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Srautų tipai"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Neapdoroto failo dydis (baitais)"</string>
+</resources>
diff --git a/res/values-lt/mimes.xml b/res/values-lt/mimes.xml
new file mode 100644
index 0000000..5bf01e2
--- /dev/null
+++ b/res/values-lt/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> failas"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Failas"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Vaizdas"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> vaizdas"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Garso įrašas"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> garso įrašas"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vaizdo įrašas"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> vaizdo įrašas"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> archyvas"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"„Android“ programa"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Grynasis tekstas"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokumentas"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokumentas"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"„Word“ dokumentas"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"„PowerPoint“ pristatymas"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"„Excel“ skaičiuoklė"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"„Google“ dokumentas"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"„Google“ skaičiuoklė"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"„Google“ pristatymas"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"„Google“ piešinys"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"„Google“ lentelė"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"„Google“ forma"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"„Google“ žemėlapis"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"„Google“ svetainė"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Aplankas"</string>
+</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 681b3df..ec80676 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Suglaudinti"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Išskleisti į..."</string>
     <string name="menu_rename" msgid="1883113442688817554">"Pervardyti"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Ypatybės"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Gauti informacijos"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Žr. <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Naujas langas"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Iškirpti"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Perkelti"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Atsisakyti"</string>
     <string name="button_retry" msgid="4011461781916631389">"Bandyti dar kartą"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Išvalyti"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Rodyti naudojant teikėjo programą"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nerūšiuota"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Pavadinimas"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Suvestinė"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipas"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Dydis"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Pakeista"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Antrinių elementų skaičius"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Elementų skaičius"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Didėjimo tvarka"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Mažėjimo tvarka"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Rodyti šaknis"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Nepavyksta atidaryti failo"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Negalima atidaryti failų archyvuose"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nepavyko ištrinti kai kurių dokumentų"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Nepavyko įkelti nuosavybių"</string>
     <string name="share_via" msgid="8725082736005677161">"Bendrinti naudojant"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopijuojami failai"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Glaudinami failai"</string>
diff --git a/res/values-lv/inspector_strings.xml b/res/values-lv/inspector_strings.xml
new file mode 100644
index 0000000..739d519
--- /dev/null
+++ b/res/values-lv/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informācija"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Nevarēja ielādēt faila informāciju"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Atkļūdošanas informācija (tikai izstrādātājiem)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Neapstrādāti metadati: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Multivides informācija"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Šāda veida failu var atvērt lietotnē"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Šis fails ir nodrošināts lietotnē"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nav atlasīta"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Nezināma"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Izmēri"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> — <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinātas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Augstums"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Diafragmas atvērums"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Slēdža ātrums"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Ilgums"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Uzņemts:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fokusa attālums"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalents"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Izpildītājs"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komponists"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albums"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Atrašanās vieta"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Straumes veidi"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Neapstrādāta faila lielums (baiti)"</string>
+</resources>
diff --git a/res/values-lv/mimes.xml b/res/values-lv/mimes.xml
new file mode 100644
index 0000000..afe110b
--- /dev/null
+++ b/res/values-lv/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> fails"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fails"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Attēls"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> attēls"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arhīvs"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android lietotne"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Vienkāršs teksts"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokuments"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokuments"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word dokuments"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint prezentācija"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel izklājlapa"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google dokuments"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google izklājlapa"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google prezentācija"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google zīmējums"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google tabula"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google veidlapa"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google karte"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google vietne"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mape"</string>
+</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 3672588..16e50a8 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Saspiest"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Izvilkt..."</string>
     <string name="menu_rename" msgid="1883113442688817554">"Pārdēvēt"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Rekvizīti"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Iegūt informāciju"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Skatīt, izmantojot <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Jauns logs"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Izgriezt"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Pārvietot"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Nerādīt"</string>
     <string name="button_retry" msgid="4011461781916631389">"Mēģināt vēlreiz"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Dzēst"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Rādīt nodrošinātājā"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nav kārtoti"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nosaukums"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Kopsavilkums"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Veids"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Lielums"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmaiņas"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Bērnu skaits"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Vienumu skaits"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Augošā secībā"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Dilstošā secībā"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Rādīt saknes"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Nevar atvērt failu."</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Nevar atvērt arhīvos esošos failus"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nevar izdzēst dažus dokumentus."</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Nevarēja ielādēt rekvizītus"</string>
     <string name="share_via" msgid="8725082736005677161">"Kopīgošanas veids"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Failu kopēšana"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Failu saspiešana"</string>
diff --git a/res/values-mk/inspector_strings.xml b/res/values-mk/inspector_strings.xml
new file mode 100644
index 0000000..66cc7b6
--- /dev/null
+++ b/res/values-mk/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Информации"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Не можеше да се вчитаат информациите за датотеката"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Информации за отстранување грешки (само за DEV)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Необработени метаподатоци: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Детали за аудиовизуелните содржини"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Овој вид датотека се отвора со"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Датотекава е обезбедена од"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Не е избрана"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Непозната"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Димензии"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> х <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координати"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Надморска височина"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Апертура"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Брзина на блендата"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Времетраење"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Фотографирано на"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокусна должина"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Еквивалент на ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Изведувач"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Албум"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Локација"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Типови пренос"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Големина на необработена (бајти)"</string>
+</resources>
diff --git a/res/values-mk/mimes.xml b/res/values-mk/mimes.xml
new file mode 100644
index 0000000..167ab2d
--- /dev/null
+++ b/res/values-mk/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> датотека"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Датотека"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Слика"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> слика"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудио"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> аудио"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Видео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> видео"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> архива"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Апликација за Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Обичен текст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML документ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF документ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word документ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint презентација"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Таб. пресметка на Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Документ на Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Таб. пресметка на Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Презентација на Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Цртеж на Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Табела на Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Формулар на Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Карта на Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Сајт на Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Папка"</string>
+</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 97d5141..7322e73 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Компресирај"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Отпакувај во…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Преименувај"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Својства"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Добијте информации"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Прикажи во <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Нов прозорец"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Исечи"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Премести"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Отфрли"</string>
     <string name="button_retry" msgid="4011461781916631389">"Обидете се повторно"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Исчисти"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Прикажи во услугата на операторот"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Неподредени"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Име"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Краток преглед"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Големина"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Изменето"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Број на деца"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Број на ставки"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Растечко"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Опаѓачко"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Прикажи корени"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Датотеката не може да се отвори"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Не може да се отвораат датотеките во архивите"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Некои документи не може да се избришат"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Не можеше да се вчитаат својствата"</string>
     <string name="share_via" msgid="8725082736005677161">"Споделете преку"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Се копираат датотеки"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Компримирање датотеки"</string>
diff --git a/res/values-ml/inspector_strings.xml b/res/values-ml/inspector_strings.xml
new file mode 100644
index 0000000..0537230
--- /dev/null
+++ b/res/values-ml/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"വിവരം"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ഫയൽ വിവരം ലോഡുചെയ്യാനായില്ല"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ഡീബഗ് ‌വിവരങ്ങൾ (dev മാത്രം)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"റോ മെറ്റാഡാറ്റാ: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"മീഡിയ വിശദാംശങ്ങള്‍"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ഇത്തരത്തിലുള്ള ‌ഫയലുകൾ ‌തുറക്കുന്നു"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ഈ ഫയൽ വിതരണം ചെയ്യുന്നത്"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"തിരഞ്ഞെടുത്തില്ല"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"അറിയില്ല"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"തലങ്ങൾ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"കോർഡിനേറ്റുകൾ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ഉയരം"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ക്യാമറ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"അപ്‌റേച്ചർ"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ഷട്ടര്‍ വേഗത"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ദൈര്‍ഘ്യം"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"എടുത്തത്"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ഫോക്കൽ ദൈർഘ്യം"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>മി.മീ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO തത്തുല്യം"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"ആർട്ടിസ്‌റ്റ്"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"കമ്പോസർ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ആല്‍‌ബം"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ലൊക്കേഷൻ"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"സ്‌ട്രീം തരങ്ങൾ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"റോ വലുപ്പം (ബൈറ്റുകൾ)"</string>
+</resources>
diff --git a/res/values-ml/mimes.xml b/res/values-ml/mimes.xml
new file mode 100644
index 0000000..a6cfb79
--- /dev/null
+++ b/res/values-ml/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ഫയൽ"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ഫയല്‍‌"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ചിത്രം"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> ചിത്രം"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ഓഡിയോ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ഓഡിയോ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"വീഡിയോ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> വീഡിയോ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> ആർക്കൈവുചെയ്യുക"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ആപ്പ്"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"പ്ലെയിന്‍ ടെക്സ്റ്റ്"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ഡോക്യുമെന്‍റ്"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ഡോക്യുമെന്‍റ്"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ഡോക്യുമെന്‍റ്"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint പ്രസന്‍റേഷൻ"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel സ്‌പ്രെഡ്‌ഷീറ്റ്"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google പ്രമാണം"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google സ്‌പ്രെഡ്‌ഷീറ്റ്"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google അവതരണം"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ഡ്രോയിംഗ്"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google പട്ടിക"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ഫോം"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google മാപ്പ്"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google സൈറ്റ്"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ഫോള്‍ഡര്‍"</string>
+</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index ebfbc6b..c7692e7 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"കംപ്രസ്സുചെയ്യുക"</string>
     <string name="menu_extract" msgid="8171946945982532262">"എക്സ്ട്രാക്റ്റുചെയ്യുക…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"പേരുമാറ്റുക"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"പ്രോപ്പർട്ടികൾ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"വിവരങ്ങൾ സ്വന്തമാക്കൂ"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> എന്നതിൽ കാണുക"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"പുതിയ വിന്‍‍ഡോ"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"മുറിക്കുക"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"നീക്കുക"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ഡിസ്മിസ് ചെയ്യുക"</string>
     <string name="button_retry" msgid="4011461781916631389">"വീണ്ടും ശ്രമിക്കുക"</string>
+    <string name="button_clear" msgid="5412304437764369441">"മായ്‌ക്കുക"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ദാതാവിൽ കാണിക്കുക"</string>
     <string name="not_sorted" msgid="7813496644889115530">"അടുക്കിയിട്ടില്ല"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"പേര്"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"ചുരുക്കം"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"തരം"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"വലുപ്പം"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"പരിഷ്‌ക്കരിച്ചു"</string>
-    <string name="directory_children" msgid="8115290268549503262">"കുട്ടികളുടെ എണ്ണം"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ഇനങ്ങളുടെ എണ്ണം"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ആരോഹണം"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"അവരോഹണം"</string>
     <string name="drawer_open" msgid="8071673398187261741">"റൂട്ടുകൾ ദൃശ്യമാക്കുക"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ഫയൽ തുറക്കാൻ കഴിയില്ല"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"ആർക്കൈവുകളിലെ ഫയലുകൾ തുറക്കാൻ കഴിയില്ല"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"ചില പ്രമാണങ്ങൾ ഇല്ലാതാക്കാനായില്ല"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"പ്രോപ്പർട്ടികൾ ലോഡുചെയ്യാനായില്ല"</string>
     <string name="share_via" msgid="8725082736005677161">"ഇതുവഴി പങ്കിടുക"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ഫയലുകൾ പകർത്തുന്നു"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ഫയലുകൾ കംപ്രസ്സുചെയ്യുന്നു"</string>
@@ -134,7 +135,7 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഇനം ‌ഇല്ലാതാക്കാനായില്ല</item>
     </plurals>
     <string name="notification_touch_for_details" msgid="2385563502445129570">"വിശദാംശങ്ങൾ കാണുന്നതിന് ടാപ്പുചെയ്യുക"</string>
-    <string name="close" msgid="905969391788869975">"അടയ്‌ക്കുക"</string>
+    <string name="close" msgid="905969391788869975">"അവസാനിപ്പിക്കുക"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
       <item quantity="other">ഈ ഫയലുകൾ പകർത്തപ്പെട്ടില്ല: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="one">ഈ ഫയൽ പകർത്തപ്പെട്ടില്ല: <xliff:g id="LIST_0">%1$s</xliff:g></item>
diff --git a/res/values-mn/inspector_strings.xml b/res/values-mn/inspector_strings.xml
new file mode 100644
index 0000000..a06af5a
--- /dev/null
+++ b/res/values-mn/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Мэдээлэл"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Файлын мэдээллийг ачааллаж чадсангүй"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Дебаг хийх мэдээлэл (зөвхөн хөгжүүлэгчид)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW мета өгөгдөл: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Медианы дэлгэрэнгүй"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ийм төрлийн файлыг дараахаар нээдэг"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Энэ файлыг дараахаас хангасан"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Сонгоогүй"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Тодорхойгүй"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Хэмжээс"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координат"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Өндөр"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камер"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Өрц"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Зураг дарах хурд"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Хугацаа"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Авсан огноо"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокусын урт"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO дүйцэх"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Уран бүтээлч"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Хөгжмийн зохиолч"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Цомог"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Байршил"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Цацалтын төрөл"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW-н хэмжээ (байт)"</string>
+</resources>
diff --git a/res/values-mn/mimes.xml b/res/values-mn/mimes.xml
new file mode 100644
index 0000000..fed9c98
--- /dev/null
+++ b/res/values-mn/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> файл"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Зураг"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> зураг"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудио"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> аудио"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Видео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> видео"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> архив"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Андройд апп"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Энгийн бичвэр"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML документ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF документ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word документ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint үзүүлэн"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-н хүснэгт"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google документ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google хүснэгт"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google үзүүлэн"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google зураглал"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google хүснэгт"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google маягт"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google газрын зураг"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google сайт"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Фолдер"</string>
+</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index d20cbee..3988b41 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Шахах"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Дараахад задлах…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Нэр өөрчлөх"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Шинж чанар"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Мэдээлэл авах"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>-д харах"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Шинэ цонх"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Таслах"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Зөөх"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Хаах"</string>
     <string name="button_retry" msgid="4011461781916631389">"Дахин оролдох"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Устгах"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Үйлчилгээ үзүүлэгчид харуулах"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Эрэмбэлээгүй"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Нэр"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Хураангуй"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Төрөл"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Хэмжээ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Өөрчилсөн"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Хүүхдийн тоо"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Зүйлийн тоо"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Дээшилж буй"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Буурч буй"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Документын санг харуулах"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Файлыг нээх боломжгүй байна"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Архивын файлыг нээх боломжгүй"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Зарим документыг устгах боломжгүй"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Документын мэдээллийг ачааллаж чадсангүй"</string>
     <string name="share_via" msgid="8725082736005677161">"Дараахаар хуваалцах"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Файлыг хуулж байна"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Файлыг шахаж байна"</string>
diff --git a/res/values-mr/inspector_strings.xml b/res/values-mr/inspector_strings.xml
new file mode 100644
index 0000000..d933b56
--- /dev/null
+++ b/res/values-mr/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"माहिती"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"फाइलची माहिती लोड करता आली नाही"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"डीबग माहिती (फक्त डेव्हलपरसाठी)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"अविश्लेषित मेटाडेटा: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"मीडिया तपशील"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"या प्रकारची फाइल ज्याने उघडेल ते"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"कडून ही फाइल पुरवण्यात आली"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"निवडलेले नाही"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"अज्ञात"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"आकारमान"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"अक्षांश रेखांश"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"उंची"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"कॅमेरा"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"अ‍ॅपर्चर"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"शटर गती"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"कालावधी"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"रोजी घेतला"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"केंद्रावरून लांबी"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>मिमी"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO सारखे"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"कलाकार"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"रचनाकार"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"अल्बम"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"स्थान"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"स्ट्रीम प्रकार"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"रॉ आकार (बाइट)"</string>
+</resources>
diff --git a/res/values-mr/mimes.xml b/res/values-mr/mimes.xml
new file mode 100644
index 0000000..0429515
--- /dev/null
+++ b/res/values-mr/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> फाइल"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"फाइल"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"इमेज"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> इमेज"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ऑडिओ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ऑडिओ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"व्हिडिओ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> व्हिडिओ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> संग्रहित करा"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android अॅप्लिकेशन"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"साधा मजकूर"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML दस्तऐवज"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"पीडीएफ दस्तऐवज"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word दस्तऐवज"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint सादरीकरण"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel स्प्रेडशीट"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google दस्तऐवज"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google स्प्रेडशीट"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google सादरीकरण"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google रेखांकन"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google सारणी"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google फॉर्म"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google नकाशा"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google साइट"</string>
+    <string name="directory_type" msgid="2702987727566226354">"फोल्डर"</string>
+</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 5827eb9..81899f5 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -23,7 +23,7 @@
     <!-- no translation found for launcher_label (799410258349837668) -->
     <skip />
     <string name="title_open" msgid="3165686459158020921">"वरून उघडा"</string>
-    <string name="title_save" msgid="4384490653102710025">"येथे जतन करा"</string>
+    <string name="title_save" msgid="4384490653102710025">"येथे सेव्ह करा"</string>
     <string name="menu_create_dir" msgid="2413624798689091042">"नवीन फोल्डर"</string>
     <string name="menu_grid" msgid="1453636521731880680">"ग्रिड दृश्य"</string>
     <string name="menu_list" msgid="6714267452146410402">"सूची"</string>
@@ -32,7 +32,7 @@
     <string name="menu_open" msgid="9092138100049759315">"उघडा"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"यासह उघडा"</string>
     <string name="menu_open_in_new_window" msgid="6686563636123311276">"नवीन विंडोमध्ये उघडा"</string>
-    <string name="menu_save" msgid="5195367497138965168">"जतन करा"</string>
+    <string name="menu_save" msgid="5195367497138965168">"सेव्ह करा"</string>
     <string name="menu_share" msgid="4307140947108068356">"सामायिक करा"</string>
     <string name="menu_delete" msgid="1022254131543256626">"हटवा"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"सर्व निवडा"</string>
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"संकुचित करा"</string>
     <string name="menu_extract" msgid="8171946945982532262">"मध्ये काढा..."</string>
     <string name="menu_rename" msgid="1883113442688817554">"पुनर्नामित करा"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"गुणधर्म"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"माहिती मिळवा"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> मध्ये पहा"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"नवीन विंडो"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"कट करा"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"हलवा"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"डिसमिस करा"</string>
     <string name="button_retry" msgid="4011461781916631389">"पुन्हा प्रयत्न करा"</string>
+    <string name="button_clear" msgid="5412304437764369441">"साफ करा"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"पुरवठादारामध्ये दाखवा"</string>
     <string name="not_sorted" msgid="7813496644889115530">"क्रमवारी लावलेली नाही"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"नाव"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"सारांश"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"सुधारित"</string>
-    <string name="directory_children" msgid="8115290268549503262">"मुलांची संख्‍या"</string>
+    <string name="directory_items" msgid="6645621978998614003">"आयटमची संख्या"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"चढत्या क्रमाने"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"उतरत्या क्रमाने"</string>
     <string name="drawer_open" msgid="8071673398187261741">"रूट दर्शवा"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"फाईल उघडू शकत नाही"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"संग्रहणांमध्‍ये फायली उघडू शकत नाही"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"काही दस्‍तऐवज हटविण्‍यात अक्षम"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"गुणधर्म लोड करू शकत नाही"</string>
     <string name="share_via" msgid="8725082736005677161">"द्वारे सामायिक करा"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"फायली कॉपी करणे"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"फायली संकुचित करत आहे"</string>
@@ -111,11 +112,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम हटवत आहे.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"पूर्ववत करा"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"कॉपी करण्‍यासाठी तयार करीत आहे…"</string>
+    <string name="copy_preparing" msgid="5326063807006898223">"कॉपी करण्‍यासाठी तयार करत आहे…"</string>
     <string name="compress_preparing" msgid="6650018601382062672">"संकुचित करण्‍यासाठी तयार होत आहे…"</string>
     <string name="extract_preparing" msgid="58266275455027829">"काढण्यासाठी तयार करत आहे..."</string>
     <string name="move_preparing" msgid="8742573245485449429">"हलविण्‍यास तयार होत आहे…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"हटविण्‍यासाठी तयार करीत आहे..."</string>
+    <string name="delete_preparing" msgid="6513863752916028147">"हटविण्‍यासाठी तयार करत आहे..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम कॉपी करु शकलो नाही</item>
@@ -196,10 +197,10 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम हटवायचा?</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम हटवायचे?</item>
     </plurals>
-    <string name="images_shortcut_label" msgid="2545168016070493574">"प्रतिमा"</string>
+    <string name="images_shortcut_label" msgid="2545168016070493574">"इमेज"</string>
     <string name="archive_loading_failed" msgid="7243436722828766996">"ब्राउझिंगसाठी संग्रहण उघडण्यात अक्षम. फाइल एकतर दूषित झाली आहे किंवा असमर्थित स्वरूपात आहे."</string>
     <string name="name_conflict" msgid="28407269328862986">"या नावाची फाइल आधीपासून अस्तित्वात आहे."</string>
-    <string name="authentication_required" msgid="8030880723643436099">"निर्देशिका पाहण्यासाठी <xliff:g id="NAME">%1$s</xliff:g> मध्ये साइन इन करा"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"डिरेक्टरी पाहण्यासाठी <xliff:g id="NAME">%1$s</xliff:g> मध्ये साइन इन करा"</string>
     <string name="cant_display_content" msgid="8633226333229417237">"सामग्री प्रदर्शित करू शकत नाही"</string>
     <string name="sign_in" msgid="6253762676723505592">"साइन इन करा"</string>
     <string name="new_archive_file_name" msgid="1604650338077249838">"संग्रहण<xliff:g id="EXTENSION">%s</xliff:g>"</string>
diff --git a/res/values-ms/inspector_strings.xml b/res/values-ms/inspector_strings.xml
new file mode 100644
index 0000000..c6f214b
--- /dev/null
+++ b/res/values-ms/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Maklumat"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Maklumat fail tidak dapat dimuatkan"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Maklumat nyahpepijat (pembangun sahaja)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadata mentah: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Butiran media"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Jenis fail ini dibuka menggunakan"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Fail ini dibekalkan oleh"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Tidak dipilih"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Tidak diketahui"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensi"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinat"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitud"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Bukaan"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Kelajuan pengatup"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Tempoh"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Diambil pada"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Jarak fokus"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Setara ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artis"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komposer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokasi"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Jenis strim"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Saiz mentah (bait)"</string>
+</resources>
diff --git a/res/values-ms/mimes.xml b/res/values-ms/mimes.xml
new file mode 100644
index 0000000..14a56d8
--- /dev/null
+++ b/res/values-ms/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Fail <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fail"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imej"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imej <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arkib <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikasi Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Teks biasa"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokumen HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokumen PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokumen Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Pembentangan PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Hamparan Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokumen Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Hamparan Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Pembentangan Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Lukisan Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Jadual Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Borang Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Peta Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Tapak Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 35adcad..d156645 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Mampatkan"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Ekstrak ke…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Namakan semula"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Sifat"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Dapatkan maklumat"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Lihat dalam <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Tetingkap baharu"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Potong"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Alih"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ketepikan"</string>
     <string name="button_retry" msgid="4011461781916631389">"Cuba Lagi"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Kosongkan"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Tunjukkan dalam pembekal"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Tidak diisih"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nama"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Ringkasan"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Jenis"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Saiz"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Diubah suai"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Bilangan Anak"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Bilangan item"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Menaik"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Menurun"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Tunjukkan akar"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Tidak dapat membuka fail"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Tidak dapat membuka fail dalam arkib"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Tidak dapat memadamkan sesetengah dokumen"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Sifat tidak dapat dimuatkan"</string>
     <string name="share_via" msgid="8725082736005677161">"Kongsi melalui"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Menyalin fail"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Memampatkan fail"</string>
diff --git a/res/values-my/inspector_strings.xml b/res/values-my/inspector_strings.xml
new file mode 100644
index 0000000..af368f3
--- /dev/null
+++ b/res/values-my/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"အချက်အလက်"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ဖိုင်အချက်အလက်များကို ဖွင့်၍မရပါ"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"အမှားရှာပြင်ရန် အချက်အလက် (ဆော့ဖ်ဝဲအင်ဂျင်နီယာသာ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"အကြမ်းထည် မက်တာဒေတာ− <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"မီဒီယာ အသေးစိတ်များ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"၎င်းဖိုင်အမျိုးအစားကို ဖွင့်နိုင်သည့်အက်ပ်−"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ဤဖိုင်အား ဝန်ဆောင်ပေးသူ−"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ရွေးမထားပါ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"အမျိုးအမည်မသိ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"အတိုင်းအတာများ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> − <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ကိုဩဒိနိတ်များ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>၊ <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"အမြင့်"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ကင်မရာ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"အလင်းဝင်ပေါက်"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ရှပ်တာအမြန်နှုန်း"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ကြာချိန်"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ရိုက်ထားသည့်အချိန်−"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ဆုံတာ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO နှုန်း"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"အနုပညာရှင်"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"ရေးစပ်သူ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"အယ်လ်ဘမ်"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"တည်နေရာ"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ထုတ်လွှင့်မှုအမျိုးအစားများ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"အကြမ်းထည် အရွယ်အစား (ဘိုက်)"</string>
+</resources>
diff --git a/res/values-my/mimes.xml b/res/values-my/mimes.xml
new file mode 100644
index 0000000..23e75cb
--- /dev/null
+++ b/res/values-my/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ဖိုင်"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ဖိုင်"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ပုံ"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> ပုံ"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"အသံ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> အသံ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ဗီဒီယို"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ဗီဒီယို"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> မှတ်တမ်းဟောင်း"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android အပလီကေးရှင်း"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ရိုးရိုးစာသား"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML နှင့်ရေးသည့်ဖိုင်"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ဖိုင်"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ဖိုင်"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint တင်ပြမှု"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel ဇယားကွက်"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google စာရွက်စာတမ်း"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google ဇယားကွက်"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google တင်ပြမှု"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ပုံ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google ဇယား"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ဖောင်"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google မြေပုံ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google ဝဘ်ဆိုက်"</string>
+    <string name="directory_type" msgid="2702987727566226354">"အကန့်"</string>
+</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index f0ec986..b0d66e9 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"ချုံ့ရန်"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ရွှေးချယ်ထည့်သွင်းရန်…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"အမည်ပြောင်းပါ"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"သတ်မှတ်ချက်များ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"အချက်အလက် ရယူရန်"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> တွင် ကြည့်ရန်"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"ဝင်းဒိုးသစ်"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ဖြတ်ယူပါ"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ရွှေ့ရန်"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ပယ်ရန်"</string>
     <string name="button_retry" msgid="4011461781916631389">"ပြန်စမ်းကြည့်ပါ"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ရှင်းထုတ်ရန်"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ပံ့ပိုးပေးသူတွင် ပြရန်"</string>
     <string name="not_sorted" msgid="7813496644889115530">"စီမထားပါ"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"အမည်"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"အနှစ်ချုပ်"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"အမျိုးအစား"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"အရွယ်အစား"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"မွမ်းမံပြီး"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ကလေးအရေအတွက်"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ပစ္စည်းအရေအတွက်"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ငယ်စဉ်ကြီးလိုက်"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ကြီးစဉ်ငယ်လိုက်"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ပင်မဖိုင်တွဲများကို ပြပါ"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ဖိုင်ကို ဖွင့်၍မရပါ"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"မှတ်တမ်းဟောင်းထဲမှ ဖိုင်များကို ဖွင့်၍မရပါ"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"အချို့စာဖိုင်များကို ဖျက်၍မရပါ"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"သတ်မှတ်ချက်များကို ဖွင့်၍မရပါ"</string>
     <string name="share_via" msgid="8725082736005677161">"အောက်ပါနည်းလမ်းဖြင့် မျှဝေပါ"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ဖိုင်များကူးယူနေသည်"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ဖိုင်များကို ချုံ့နေသည်"</string>
diff --git a/res/values-nb/inspector_strings.xml b/res/values-nb/inspector_strings.xml
new file mode 100644
index 0000000..cd315e6
--- /dev/null
+++ b/res/values-nb/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informasjon"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Kunne ikke laste inn filinformasjonen"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Feilsøkingsinfo (bare for utviklere)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Råmetadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Mediadetaljer"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Denne filtypen åpnes med"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Denne filen leveres av"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ikke valgt"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Ukjent"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensjoner"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinater"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Høyde over havet"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Blender"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Lukkerhastighet"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Varighet"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Tatt"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Brennvidde"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Tilsvarende ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Komponist"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Posisjon"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Strømtyper"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Råstørrelse (byte)"</string>
+</resources>
diff --git a/res/values-nb/mimes.xml b/res/values-nb/mimes.xml
new file mode 100644
index 0000000..eb89ea2
--- /dev/null
+++ b/res/values-nb/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-fil"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fil"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Bilde"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-bilde"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Lyd"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-lyd"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-arkiv"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-app"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Ren tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-presentasjon"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-regneark"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-regneark"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-presentasjon"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-tegning"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-tabell"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-skjema"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-kart"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-nettsted"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mappe"</string>
+</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index df75079..106371b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Komprimer"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Pakk ut til …"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Gi nytt navn"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Egenskaper"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Hent inn informasjon"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Se i <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nytt vindu"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Klipp ut"</string>
@@ -55,15 +55,17 @@
     <string name="button_compress" msgid="8951561310857223966">"Komprimer"</string>
     <string name="button_extract" msgid="1038674453689912247">"Pakk ut"</string>
     <string name="button_move" msgid="8596460499325291272">"Flytt"</string>
-    <string name="button_dismiss" msgid="7235249361023803349">"Avvis"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"Lukk"</string>
     <string name="button_retry" msgid="4011461781916631389">"Prøv på nytt"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Fjern"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Vis i leverandøren"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ikke sortert"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Navn"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Sammendrag"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Størrelse"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Endret"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Antall barn"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Antall elementer"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stigende"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Synkende"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Vis røtter"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Kan ikke åpne filen"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Kan ikke åpne filer i arkiver"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Kunne ikke slette enkelte dokumenter"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Kunne ikke laste inn egenskapene"</string>
     <string name="share_via" msgid="8725082736005677161">"Del via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopierer filer"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Komprimerer filer"</string>
diff --git a/res/values-ne/inspector_strings.xml b/res/values-ne/inspector_strings.xml
new file mode 100644
index 0000000..41102e4
--- /dev/null
+++ b/res/values-ne/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"जानकारी"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"फाइलसम्बन्धी जानकारी लोड गर्न सकिएन"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"डिबगसम्बन्धी जानकारी (विकासकर्ताका लागि मात्र)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"अप्रशोधित मेटाडेटा: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"मिडियासम्बन्धी विवरणहरू"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"यस प्रकारको फाइल निम्न अनुप्रयोगमार्फत खुल्छ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"यो फाइलको प्रदायक"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"चयन गरिएको छैन"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"अज्ञात"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"उचाइ तथा चौडाइ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> एम. पि."</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"तस्बिर खिचेको स्थानका भौगोलिक स्थितिहरू"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"उचाइ"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"क्यामेरा"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"अपार्चर"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"सटरको गति"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"अवधि"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"तस्बिर खिचेको समय"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"फोकल लम्बाइ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> मि. मि."</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO बराबर"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"कलाकार"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"रचनाकार"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"एल्बम"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"स्थान"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"स्ट्रिमका प्रकारहरू"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"अप्रशोधित आकार (बाइट)"</string>
+</resources>
diff --git a/res/values-ne/mimes.xml b/res/values-ne/mimes.xml
new file mode 100644
index 0000000..efbb6f4
--- /dev/null
+++ b/res/values-ne/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> फाइल"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"फाइल"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"छवि"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> छवि"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"अडियो"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> अडियो"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"भिडियो"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> भिडियो"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> अभिलेख"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android अनुप्रयोग"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"सामान्य पाठ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML कागजात"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF कागजात"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word कागजात"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint प्रस्तुतीकरण"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel स्प्रेडसिट"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google कागजात"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google स्प्रिेडसिट"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google प्रस्तुतीकरण"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google रेखाचित्र"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google तालिका"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google फारम"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google नक्सा"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google साइट"</string>
+    <string name="directory_type" msgid="2702987727566226354">"फोल्डर"</string>
+</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 1903f51..cada88e 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"कम्प्रेस गर्नुहोस्"</string>
     <string name="menu_extract" msgid="8171946945982532262">"यसमा एकस्ट्र्याक्ट गर्नुहोस्…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"पुनःनामाकरण गर्नुहोस्"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"विशेषताहरू"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"जानकारी प्राप्त गर्नुहोस्"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> मा हेर्नुहोस्"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"नयाँ विन्डो"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"काट्नुहोस्"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"सार्नुहोस्"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"खारेज गर्नुहोस्"</string>
     <string name="button_retry" msgid="4011461781916631389">"फेरि प्रयास गर्नुहोस्"</string>
+    <string name="button_clear" msgid="5412304437764369441">"खाली गर्नुहोस्"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"प्रदायकको सेवामा देखाउनुहोस्"</string>
     <string name="not_sorted" msgid="7813496644889115530">"क्रमबद्ध गरिएको छैन"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"नाम"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"सारांश"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"परिमार्जित"</string>
-    <string name="directory_children" msgid="8115290268549503262">"बालबालिकाहरूको सङ्ख्या"</string>
+    <string name="directory_items" msgid="6645621978998614003">"वस्तुहरूको संख्या"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"बढ्दो क्रम"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"घट्दो क्रम"</string>
     <string name="drawer_open" msgid="8071673398187261741">"मूल ठाउँहरू देखाउनुहोस्"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"फाइल खोल्न सकिँदैन"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"अभिलेखहरूमा भएका फाइलहरू खोल्न सकिँदैन"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"केही कागजातहरूलाई मेट्न सकिएन"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"विशेषताहरू लोड गर्न सकिएन"</string>
     <string name="share_via" msgid="8725082736005677161">"निम्न मार्फत साझेदारी गर्नुहोस्"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"फाइलहरूका प्रतिलिपि बनाउँदै"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"फाइलहरू कम्प्रेस गर्दै"</string>
diff --git a/res/values-nl/inspector_strings.xml b/res/values-nl/inspector_strings.xml
new file mode 100644
index 0000000..51e438e
--- /dev/null
+++ b/res/values-nl/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informatie"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Bestandsgegevens kunnen niet worden geladen"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Foutopsporingsinfo (alleen ontwikkelaars)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Onbewerkte metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Mediagegevens"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Dit type bestand wordt geopend met"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Dit bestand wordt geleverd door"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Niet geselecteerd"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Onbekend"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Afmetingen"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coördinaten"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Hoogte"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Diafragma"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Sluitersnelheid"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duur"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Gemaakt op"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Focuslengte"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-equivalent"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artiest"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Componist"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Locatie"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Streamtypen"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Onbewerkte grootte (bytes)"</string>
+</resources>
diff --git a/res/values-nl/mimes.xml b/res/values-nl/mimes.xml
new file mode 100644
index 0000000..1f762be
--- /dev/null
+++ b/res/values-nl/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-bestand"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Bestand"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Afbeelding"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-afbeelding"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-archief"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-app"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Platte tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-document"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Pdf-document"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-document"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-presentatie"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-spreadsheet"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-document"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-spreadsheet"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-presentatie"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-tekening"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-tabel"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-formulier"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-kaart"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Map"</string>
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 0124f8a..6b864f9 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimeren"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Uitpakken naar…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Naam wijzigen"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Eigenschappen"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Informatie bekijken"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Bekijken in <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nieuw venster"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Knippen"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Verplaatsen"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Sluiten"</string>
     <string name="button_retry" msgid="4011461781916631389">"Opnieuw proberen"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Wissen"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Weergeven in provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Niet gesorteerd"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Naam"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Overzicht"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Grootte"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Aangepast"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Aantal kinderen"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Aantal items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Oplopend"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Aflopend"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Roots weergeven"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Kan bestand niet openen"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Kan bestanden in archieven niet openen"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Kan bepaalde documenten niet verwijderen"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Eigenschappen kunnen niet worden geladen"</string>
     <string name="share_via" msgid="8725082736005677161">"Delen via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Bestanden kopiëren"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Bestanden comprimeren"</string>
diff --git a/res/values-pa/inspector_strings.xml b/res/values-pa/inspector_strings.xml
new file mode 100644
index 0000000..117a840
--- /dev/null
+++ b/res/values-pa/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ਜਾਣਕਾਰੀ"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ਫ਼ਾਈਲ ਜਾਣਕਾਰੀ ਲੋਡ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ਡੀਬੱਗ ਜਾਣਕਾਰੀ (ਸਿਰਫ਼ ਵਿਕਾਸਕਾਰ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ਰਾਅ ਮੈਟਾਡਾਟਾ: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"ਮੀਡੀਆ ਦੇ ਵੇਰਵੇ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ਇਸ ਕਿਸਮ ਦੀ ਫ਼ਾਈਲ ਇਸ ਨਾਲ ਖੁੱਲ੍ਹਦੀ ਹੈ:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ਇਹ ਫ਼ਾਈਲ ਇਹਨਾਂ ਵੱਲੋਂ ਦਿੱਤੀ ਗਈ ਹੈ:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ਚੁਣੀ ਨਹੀਂ ਗਈ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"ਅਗਿਆਤ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ਮਾਪ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> ਮੈਗਾ ਪਿਕਸਲ"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ਲੰਬਕਾਰ ਅਤੇ ਵਿਥਕਾਰ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ਉਚਾਈ"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"ਕੈਮਰਾ"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ਕੈਮਰੇ ਦੀ ਮੋਰੀ"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ਸ਼ਟਰ ਦੀ ਗਤੀ"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ਮਿਆਦ"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ਇਸ ਮਿਤੀ ਨੂੰ ਖਿੱਚੀ ਗਈ:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ਫੋਕਲ ਲੰਬਾਈ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>ਮਿ.ਮੀ."</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ਦੇ ਬਰਾਬਰ"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"ਕਲਾਕਾਰ"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"ਗੀਤਕਾਰ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ਐਲਬਮ"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ਟਿਕਾਣਾ"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ਸਟ੍ਰੀਮ ਦੀਆਂ ਕਿਸਮਾਂ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw ਆਕਾਰ (ਬਾਈਟ)"</string>
+</resources>
diff --git a/res/values-pa/mimes.xml b/res/values-pa/mimes.xml
new file mode 100644
index 0000000..94969c5
--- /dev/null
+++ b/res/values-pa/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ਫ਼ਾਈਲ"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ਫ਼ਾਈਲ"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ਚਿੱਤਰ"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> ਚਿੱਤਰ"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">" ਆਡੀਓ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>  ਆਡੀਓ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ਵੀਡੀਓ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ਵੀਡੀਓ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> ਪੁਰਾਲੇਖ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ਐਪਲੀਕੇਸ਼ਨ"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ਸਰਲ ਲਿਖਤ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ਦਸਤਾਵੇਜ਼"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ਦਸਤਾਵੇਜ਼"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ਦਸਤਾਵੇਜ਼"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint ਪੇਸ਼ਕਾਰੀ"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel ਸਪਰੈੱਡਸ਼ੀਟ"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ਦਸਤਾਵੇਜ਼"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google ਸਪਰੈੱਡਸ਼ੀਟ"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google ਪੇਸ਼ਕਾਰੀ"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ਚਿੱਤਰਕਾਰੀ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google ਸਾਰਨੀ"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ਫ਼ਾਰਮ"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google ਨਕਸ਼ਾ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google ਸਾਈਟ"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ਫੋਲਡਰ"</string>
+</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index abe79b3..0a320ae 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -27,7 +27,7 @@
     <string name="menu_create_dir" msgid="2413624798689091042">"ਨਵਾਂ ਫੋਲਡਰ"</string>
     <string name="menu_grid" msgid="1453636521731880680">"ਗਰਿੱਡ ਦ੍ਰਿਸ਼"</string>
     <string name="menu_list" msgid="6714267452146410402">"ਸੂਚੀ ਦ੍ਰਿਸ਼"</string>
-    <string name="menu_search" msgid="1876699106790719849">"ਖੋਜ"</string>
+    <string name="menu_search" msgid="1876699106790719849">"ਖੋਜੋ"</string>
     <string name="menu_settings" msgid="6520844520117939047">"ਸਟੋਰੇਜ ਸੈਟਿੰਗਾਂ"</string>
     <string name="menu_open" msgid="9092138100049759315">"ਖੋਲ੍ਹੋ"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"ਇਸ ਨਾਲ ਖੋਲ੍ਹੋ"</string>
@@ -41,14 +41,14 @@
     <string name="menu_compress" msgid="37539111904724188">"ਆਕਾਰ ਛੋਟਾ ਕਰੋ"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ਇਸ ਵਿੱਚ ਐਕਸਟ੍ਰੈਕਟ ਕਰੋ…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"ਮੁੜ-ਨਾਮਕਰਨ ਕਰੋ"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ"</string>
-    <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> ਵਿੱਚ ਵੇਖੋ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
+    <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> ਵਿੱਚ ਦੇਖੋ"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"ਨਵੀਂ ਵਿੰਡੋ"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ਕੱਟੋ"</string>
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"ਕਾਪੀ ਕਰੋ"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"ਪੇਸਟ ਕਰੋ"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"ਫੋਲਡਰ ਵਿੱਚ ਪੇਸਟ ਕਰੋ"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਵਿਖਾਓ"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਦਿਖਾਓ"</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਲੁਕਾਓ"</string>
     <string name="button_select" msgid="240863497069321364">"ਚੁਣੋ"</string>
     <string name="button_copy" msgid="8219059853840996027">"ਕਾਪੀ ਕਰੋ"</string>
@@ -57,16 +57,18 @@
     <string name="button_move" msgid="8596460499325291272">"ਤਬਦੀਲ ਕਰੋ"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ਖਾਰਜ ਕਰੋ"</string>
     <string name="button_retry" msgid="4011461781916631389">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ਕਲੀਅਰ ਕਰੋ"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ਪ੍ਰਦਾਨਕ ਸੇਵਾ ਵਿੱਚ ਦਿਖਾਓ"</string>
     <string name="not_sorted" msgid="7813496644889115530">"ਛਾਂਟੀ ਨਹੀਂ ਕੀਤੀ ਗਈ"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"ਨਾਮ"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"ਸਾਰਾਂਸ਼"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ਕਿਸਮ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ਆਕਾਰ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ਸੋਧਣ ਦਾ ਸਮਾਂ"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ਬੱਚਿਆਂ ਦੀ ਗਿਣਤੀ"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ਆਈਟਮਾਂ ਦੀ ਗਿਣਤੀ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ਵਧਦਾ ਕ੍ਰਮ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ਘਟਦਾ ਕ੍ਰਮ"</string>
-    <string name="drawer_open" msgid="8071673398187261741">"ਰੂਟਾਂ ਨੂੰ ਵਿਖਾਓ"</string>
+    <string name="drawer_open" msgid="8071673398187261741">"ਰੂਟਾਂ ਨੂੰ  ਦਿਖਾਓ"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ਰੂਟਾਂ ਨੂੰ ਲੁਕਾਓ"</string>
     <string name="save_error" msgid="8631128801982095782">"ਦਸਾਤਵੇਜ਼ ਰੱਖਿਅਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
     <string name="create_error" msgid="3092144450044861994">"ਫੋਲਡਰ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ਫ਼ਾਈਲ ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"ਪੁਰਾਲੇਖਾਂ ਵਿੱਚ ਫ਼ਾਈਲਾਂ ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"ਕੁਝ ਦਸਤਾਵੇਜ਼ਾਂ ਨੂੰ ਮਿਟਾਉਣ ਦੇ ਅਯੋਗ"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="share_via" msgid="8725082736005677161">"ਇਸ ਰਾਹੀਂ ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ਫ਼ਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ਆਕਾਰ ਛੋਟਾ ਕੀਤਾ ਜਾ ਰਿਹਾ"</string>
@@ -115,7 +116,7 @@
     <string name="compress_preparing" msgid="6650018601382062672">"ਆਕਾਰ ਛੋਟਾ ਕਰਨ ਦੀ ਤਿਆਰੀ ਅਧੀਨ…"</string>
     <string name="extract_preparing" msgid="58266275455027829">"ਐਕਸਟ੍ਰੈਕਟ ਕਰਨ ਦੀ ਤਿਆਰੀ…"</string>
     <string name="move_preparing" msgid="8742573245485449429">"ਤਬਦੀਲ ਕਰਨ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ਮਿਟਾਉਣ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
+    <string name="delete_preparing" msgid="6513863752916028147">"ਮਿਟਾਉਣ ਦੀ ਤਿਆਰੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
@@ -133,7 +134,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="2385563502445129570">"ਵੇਰਵਿਆਂ ਨੂੰ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"ਵੇਰਵਿਆਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="close" msgid="905969391788869975">"ਬੰਦ ਕਰੋ"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
       <item quantity="one">ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਗਿਆ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
@@ -156,8 +157,8 @@
       <item quantity="other">ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਨਹੀਂ ਮਿਟਾਇਆ ਗਿਆ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
-      <item quantity="one">ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਿਸੇ ਹੋਰ ਵੰਨਗੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
-      <item quantity="other">ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਿਸੇ ਹੋਰ ਵੰਨਗੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਿਸੇ ਹੋਰ ਫਾਰਮੈਟ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="other">ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਿਸੇ ਹੋਰ ਫਾਰਮੈਟ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।</item>
@@ -170,7 +171,7 @@
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"ਕੁਝ ਫ਼ਾਈਲਾਂ ਦਾ ਰੂਪਾਂਤਰਨ ਕੀਤਾ ਗਿਆ ਸੀ"</string>
     <string name="open_external_dialog_request" msgid="8173558471322861268">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^3</i></xliff:g> \'ਤੇ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
-    <string name="open_external_dialog_root_request" msgid="6776729293982633">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ਉੱਪਰ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ ਤੁਹਾਡੇ ਡੈਟੇ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ਉੱਪਰ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ ਤੁਹਾਡੇ ਡਾਟਾ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
     <string name="never_ask_again" msgid="525908236522201138">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
     <string name="allow" msgid="1275746941353040309">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
     <string name="deny" msgid="5127201668078153379">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
@@ -197,11 +198,11 @@
       <item quantity="other">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
     </plurals>
     <string name="images_shortcut_label" msgid="2545168016070493574">"ਚਿੱਤਰ"</string>
-    <string name="archive_loading_failed" msgid="7243436722828766996">"ਬ੍ਰਾਊਜ਼ਿੰਗ ਲਈ ਪੁਰਾਲੇਖ ਨੂੰ ਖੋਲ੍ਹਣ ਦੇ ਅਯੋਗ ਹੈ। ਫ਼ਾਈਲ ਜਾਂ ਤਾਂ ਖਰਾਬ ਹੈ, ਜਾਂ ਅਸਮਰਥਿਤ ਵੰਨਗੀ ਵਿੱਚ ਹੈ।"</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"ਬ੍ਰਾਊਜ਼ਿੰਗ ਲਈ ਪੁਰਾਲੇਖ ਨੂੰ ਖੋਲ੍ਹਣ ਦੇ ਅਯੋਗ ਹੈ। ਫ਼ਾਈਲ ਜਾਂ ਤਾਂ ਖਰਾਬ ਹੈ, ਜਾਂ ਅਸਮਰਥਿਤ ਫਾਰਮੈਟ ਵਿੱਚ ਹੈ।"</string>
     <string name="name_conflict" msgid="28407269328862986">"ਇਸ ਨਾਮ ਵਾਲੀ ਫ਼ਾਈਲ ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਹੈ।"</string>
-    <string name="authentication_required" msgid="8030880723643436099">"ਇਸ ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਦੇਖਣ ਲਈ, <xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
-    <string name="cant_display_content" msgid="8633226333229417237">"ਸਮੱਗਰੀਆਂ ਦਿਖਾਈਆਂ ਨਹੀਂ ਜਾ ਸਕਦੀਆਂ"</string>
-    <string name="sign_in" msgid="6253762676723505592">"ਸਾਈਨ ਇਨ ਕਰੋ"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"ਇਸ ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਦੇਖਣ ਲਈ, <xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"ਸਮੱਗਰੀਆਂ ਪ੍ਰਦਰਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾ ਸਕਦੀਆਂ"</string>
+    <string name="sign_in" msgid="6253762676723505592">"ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
     <string name="new_archive_file_name" msgid="1604650338077249838">"ਪੁਰਾਲੇਖ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ਉੱਤੇ ਲਿਖੀਏ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਜਾਰੀ ਰੱਖੋ"</string>
diff --git a/res/values-pl/inspector_strings.xml b/res/values-pl/inspector_strings.xml
new file mode 100644
index 0000000..e17ccd9
--- /dev/null
+++ b/res/values-pl/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informacje"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Nie udało się załadować informacji o pliku"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informacje o debugowaniu (tylko programiści)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadane pliku RAW: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Informacje o pliku multimedialnym"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ten rodzaj pliku możesz otworzyć w:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Dostawca pliku:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nie wybrano"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Nieznana"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Wymiary"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Współrzędne"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Wysokość"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Aparat"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Przysłona"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Szybkość migawki"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Czas"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Data wykonania"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Ogniskowa"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Równoważnik ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Wykonawca"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Kompozytor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokalizacja"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Typy strumienia"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Rzeczywisty rozmiar pliku (bajty)"</string>
+</resources>
diff --git a/res/values-pl/mimes.xml b/res/values-pl/mimes.xml
new file mode 100644
index 0000000..6e96f69
--- /dev/null
+++ b/res/values-pl/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Plik <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Plik"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Zdjęcie"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Obraz <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Plik audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Plik audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Plik wideo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Plik wideo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archiwum <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikacja na Androida"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Zwykły tekst"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokument HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokument PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokument Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Prezentacja PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Arkusz kalkulacyjny Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokument Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Arkusz kalkulacyjny Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Prezentacja Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Rysunek Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabela Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formularz Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Witryna Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 4949a69..13c3264 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Skompresuj"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Rozpakuj do…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Zmień nazwę"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Właściwości"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Zobacz informacje"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Zobacz w: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nowe okno"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Wytnij"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Przenieś"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Odrzuć"</string>
     <string name="button_retry" msgid="4011461781916631389">"Spróbuj jeszcze raz"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Zrezygnuj"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Pokaż w usłudze"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Brak sortowania"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nazwa"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Podsumowanie"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Typ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Rozmiar"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Zmieniono"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Liczba dzieci"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Liczba elementów"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Rosnąco"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Malejąco"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Pokaż elementy główne"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Nie można otworzyć pliku"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Nie można otworzyć plików w archiwum"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nie można usunąć niektórych dokumentów"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Nie udało się załadować właściwości"</string>
     <string name="share_via" msgid="8725082736005677161">"Udostępnij przez"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiowanie plików"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Kompresuję pliki"</string>
diff --git a/res/values-pt-rBR/inspector_strings.xml b/res/values-pt-rBR/inspector_strings.xml
new file mode 100644
index 0000000..03d2545
--- /dev/null
+++ b/res/values-pt-rBR/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informações"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Não foi possível carregar as informações do arquivo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Info de depuração (apenas desenvolvimento)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadados brutos: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalhes de mídia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Este tipo de arquivo é aberto no app"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Este arquivo é fornecido por"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Não selecionado"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Desconhecido"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensões"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenadas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Câmera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Abertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocidade do obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duração"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Tirada em"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distância focal:"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalente de ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Álbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Localização"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipos de stream"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Tamanho bruto (bytes)"</string>
+</resources>
diff --git a/res/values-pt-rBR/mimes.xml b/res/values-pt-rBR/mimes.xml
new file mode 100644
index 0000000..07dd5e2
--- /dev/null
+++ b/res/values-pt-rBR/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Arquivo <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Arquivo"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imagem"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imagem <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Áudio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Áudio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vídeo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vídeo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arquivo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicativo Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texto simples"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento do Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Apresentação PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Planilha do Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento do Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Planilha do Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Apresentação do Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Desenho do Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabela do Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulário do Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa do Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site do Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Pasta"</string>
+</resources>
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index 3ee2c03..af691a1 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compactar"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extrair para…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Renomear"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propriedades"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Ver informações"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ver em <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nova janela"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Recortar"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Dispensar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Tentar novamente"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Limpar"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostrar no provedor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sem classificação"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nome"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamanho"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificação"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Número de filhos"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Número de itens"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Crescente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Decrescente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raízes"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Não é possível abrir o arquivo"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Não é possível abrir itens arquivados"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Não foi possível excluir alguns documentos"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Não foi possível carregar as propriedades"</string>
     <string name="share_via" msgid="8725082736005677161">"Compartilhar via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copiando arquivos"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compactando arquivos"</string>
diff --git a/res/values-pt-rPT/inspector_strings.xml b/res/values-pt-rPT/inspector_strings.xml
new file mode 100644
index 0000000..2b63c49
--- /dev/null
+++ b/res/values-pt-rPT/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informações"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Não foi possível carregar as informações do ficheiro"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informação de depuração (apenas programadores)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadados não processados: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalhes de multimédia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Este tipo de ficheiro abre com a aplicação"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Este ficheiro é fornecido por"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Não selecionada"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Desconhecida"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensões"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenadas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Câmara"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Abertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocidade do obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duração"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Tirada em"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distância focal"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalente de ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Álbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Localização"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipos de transmissão"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Tamanho não processado (bytes)"</string>
+</resources>
diff --git a/res/values-pt-rPT/mimes.xml b/res/values-pt-rPT/mimes.xml
new file mode 100644
index 0000000..ec8d2fd
--- /dev/null
+++ b/res/values-pt-rPT/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Ficheiro <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Ficheiro"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imagem"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imagem <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Áudio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Áudio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vídeo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vídeo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arquivo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicação Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texto simples"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento do Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Apresentação PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Folha de cálculo Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento do Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Folha de cálculo do Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Apresentação do Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Desenho do Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabela do Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulário do Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa do Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site do Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Pasta"</string>
+</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 4a24854..9a71ed4 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extrair para…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Mudar o nome"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propriedades"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obter informações"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ver no <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nova janela"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cortar"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ignorar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Tentar novamente"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Limpar"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostrar no fornecedor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Não ordenados"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nome"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamanho"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Número de crianças"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Número de itens"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raízes"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Não é possível abrir o ficheiro"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Não é possível abrir ficheiros nos arquivos"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Não é possível eliminar alguns documentos"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Não foi possível carregar as propriedades"</string>
     <string name="share_via" msgid="8725082736005677161">"Partilhar através de"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"A copiar ficheiros"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"A comprimir ficheiros…"</string>
@@ -91,24 +92,24 @@
     <string name="delete_notification_title" msgid="2512757431856830792">"A eliminar ficheiros"</string>
     <string name="copy_remaining" msgid="5390517377265177727">"Faltam <xliff:g id="DURATION">%s</xliff:g>"</string>
     <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
-      <item quantity="one">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> items.</item>
-      <item quantity="other">A copiar <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="other">A copiar <xliff:g id="COUNT_1">%1$d</xliff:g> itens…</item>
+      <item quantity="one">A copiar <xliff:g id="COUNT_0">%1$d</xliff:g> item…</item>
     </plurals>
     <plurals name="compress_begin" formatted="false" msgid="3534158317098678895">
-      <item quantity="one">Compressing <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
       <item quantity="other">A comprimir <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros…</item>
+      <item quantity="one">A comprimir <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro…</item>
     </plurals>
     <plurals name="extract_begin" formatted="false" msgid="1006380679562903749">
-      <item quantity="one">Extracting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
       <item quantity="other">A extrair <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros…</item>
+      <item quantity="one">A extrair <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro…</item>
     </plurals>
     <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
-      <item quantity="one">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> items.</item>
-      <item quantity="other">A mover <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="other">A mover <xliff:g id="COUNT_1">%1$d</xliff:g> itens…</item>
+      <item quantity="one">A mover <xliff:g id="COUNT_0">%1$d</xliff:g> item…</item>
     </plurals>
     <plurals name="deleting" formatted="false" msgid="1729138001178158901">
-      <item quantity="one">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> items.</item>
-      <item quantity="other">A eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="other">A eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> itens…</item>
+      <item quantity="one">A eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> item…</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Anular"</string>
     <string name="copy_preparing" msgid="5326063807006898223">"A preparar para copiar…"</string>
@@ -118,50 +119,50 @@
     <string name="delete_preparing" msgid="6513863752916028147">"A preparar para eliminar…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
-      <item quantity="one">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
       <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
     </plurals>
     <plurals name="compress_error_notification_title" formatted="false" msgid="3043630066678213644">
-      <item quantity="one">Couldn’t compress <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="other">Não foi possível comprimir <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Não foi possível comprimir <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
     </plurals>
     <plurals name="move_error_notification_title" formatted="false" msgid="2185736082411854754">
-      <item quantity="one">Couldn’t move <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
       <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="one">Não foi possível mover <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
     </plurals>
     <plurals name="delete_error_notification_title" formatted="false" msgid="7568122018481625267">
-      <item quantity="one">Couldn’t delete <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
       <item quantity="other">Não foi possível eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="one">Não foi possível eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
     </plurals>
     <string name="notification_touch_for_details" msgid="2385563502445129570">"Tocar para ver detalhes"</string>
     <string name="close" msgid="905969391788869975">"Fechar"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
-      <item quantity="one">These files weren’t copied: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">Estes ficheiros não foram copiados: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">Este ficheiro não foi copiado: <xliff:g id="LIST_0">%1$s</xliff:g></item>
     </plurals>
     <plurals name="compress_failure_alert_content" formatted="false" msgid="5760632881868842400">
-      <item quantity="one">These files weren’t compressed: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">Estes ficheiros não foram comprimidos: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">Este ficheiro não foi comprimido: <xliff:g id="LIST_0">%1$s</xliff:g></item>
     </plurals>
     <plurals name="extract_failure_alert_content" formatted="false" msgid="7572748127571720803">
-      <item quantity="one">These files weren’t extracted: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">Estes ficheiros não foram extraídos: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">Este ficheiro não foi extraído: <xliff:g id="LIST_0">%1$s</xliff:g></item>
     </plurals>
     <plurals name="move_failure_alert_content" formatted="false" msgid="2747390342670799196">
-      <item quantity="one">These files weren’t moved: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">Estes ficheiros não foram movidos: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">Este ficheiro não foi movido: <xliff:g id="LIST_0">%1$s</xliff:g></item>
     </plurals>
     <plurals name="delete_failure_alert_content" formatted="false" msgid="6122372614839711711">
-      <item quantity="one">These files weren’t deleted: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">Estes ficheiros não foram eliminados: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">Este ficheiro não foi eliminado: <xliff:g id="LIST_0">%1$s</xliff:g></item>
     </plurals>
     <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
-      <item quantity="one">These files were converted to another format: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">Estes ficheiros foram convertidos para outro formato: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">Este ficheiro foi convertido para outro formato: <xliff:g id="LIST_0">%1$s</xliff:g></item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
-      <item quantity="one">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> items to clipboard.</item>
-      <item quantity="other">Foram copiados <xliff:g id="COUNT_1">%1$d</xliff:g> itens para a área de transferência</item>
+      <item quantity="other">Copiou <xliff:g id="COUNT_1">%1$d</xliff:g> itens para a área de transferência.</item>
+      <item quantity="one">Copiou <xliff:g id="COUNT_0">%1$d</xliff:g> item para a área de transferência.</item>
     </plurals>
     <string name="file_operation_rejected" msgid="4301554203329008794">"O ficheiro não permite a operação."</string>
     <string name="file_operation_error" msgid="2234357335716533795">"Falha na operação do ficheiro."</string>
@@ -175,26 +176,26 @@
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Recusar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item>
     </plurals>
     <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
     </plurals>
     <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"Pretende eliminar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
     <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"Pretende eliminar a pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e os respetivos conteúdos?"</string>
     <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
-      <item quantity="one">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item>
       <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros?</item>
+      <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro?</item>
     </plurals>
     <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
-      <item quantity="one">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> folders and their contents?</item>
       <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> pastas e os respetivos conteúdos?</item>
+      <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> pasta e os respetivos conteúdos?</item>
     </plurals>
     <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
-      <item quantity="one">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> items?</item>
       <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> itens?</item>
+      <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
     </plurals>
     <string name="images_shortcut_label" msgid="2545168016070493574">"Imagens"</string>
     <string name="archive_loading_failed" msgid="7243436722828766996">"Não é possível abrir o arquivo para navegação. O ficheiro está danificado ou está num formato que não é suportado."</string>
diff --git a/res/values-pt/inspector_strings.xml b/res/values-pt/inspector_strings.xml
new file mode 100644
index 0000000..03d2545
--- /dev/null
+++ b/res/values-pt/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informações"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Não foi possível carregar as informações do arquivo"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Info de depuração (apenas desenvolvimento)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadados brutos: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalhes de mídia"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Este tipo de arquivo é aberto no app"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Este arquivo é fornecido por"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Não selecionado"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Desconhecido"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensões"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordenadas"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Câmera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Abertura"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Velocidade do obturador"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Duração"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Tirada em"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distância focal:"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Equivalente de ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artista"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compositor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Álbum"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Localização"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipos de stream"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Tamanho bruto (bytes)"</string>
+</resources>
diff --git a/res/values-pt/mimes.xml b/res/values-pt/mimes.xml
new file mode 100644
index 0000000..07dd5e2
--- /dev/null
+++ b/res/values-pt/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Arquivo <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Arquivo"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imagem"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imagem <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Áudio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Áudio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Vídeo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Vídeo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arquivo <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicativo Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Texto simples"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Documento HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Documento PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Documento do Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Apresentação PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Planilha do Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Documento do Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Planilha do Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Apresentação do Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Desenho do Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabela do Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulário do Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa do Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site do Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Pasta"</string>
+</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 3ee2c03..af691a1 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Compactar"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extrair para…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Renomear"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Propriedades"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Ver informações"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Ver em <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nova janela"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Recortar"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Dispensar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Tentar novamente"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Limpar"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Mostrar no provedor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sem classificação"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nome"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamanho"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificação"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Número de filhos"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Número de itens"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Crescente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Decrescente"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raízes"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Não é possível abrir o arquivo"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Não é possível abrir itens arquivados"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Não foi possível excluir alguns documentos"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Não foi possível carregar as propriedades"</string>
     <string name="share_via" msgid="8725082736005677161">"Compartilhar via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Copiando arquivos"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Compactando arquivos"</string>
diff --git a/res/values-ro/inspector_strings.xml b/res/values-ro/inspector_strings.xml
new file mode 100644
index 0000000..f37e07c
--- /dev/null
+++ b/res/values-ro/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informații"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Informațiile despre fișier nu au putut fi încărcate"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informații remediere (numai pentru dezvoltatori)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadate brute: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detalii despre conținutul media"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Acest tip de fișier se deschide cu"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Acest fișier este furnizat de"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nu ați selectat"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Necunoscut"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Dimensiuni"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Coordonate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitudine"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera foto"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Diafragmă"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Viteza de declanșare"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Durată"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Realizată pe"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Distanța focală"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Echivalent ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Compozitor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Locație"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Tipuri de flux"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Dimensiune brută (octeți)"</string>
+</resources>
diff --git a/res/values-ro/mimes.xml b/res/values-ro/mimes.xml
new file mode 100644
index 0000000..fdebbb6
--- /dev/null
+++ b/res/values-ro/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Fișier <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fișier"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imagine"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imagine <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Conținut audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Videoclip"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Fișier video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arhivă <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplicaţie Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Text simplu"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Document HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Document PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Document Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Prezentare PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Foaie de calcul Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Document Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Foaie de calcul Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Prezentare Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Desen Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabel Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formular Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Hartă Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Dosar"</string>
+</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 3ac2a54..c14d37f 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Comprimați"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extrageți în…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Redenumiți"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Proprietăți"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Obțineți informații"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Afișați în <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Fereastră nouă"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Decupați"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Mutați"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Închideți"</string>
     <string name="button_retry" msgid="4011461781916631389">"Încercați din nou"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Ștergeți"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Afișați în furnizor"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nesortate"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nume"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Rezumat"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tip"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Dimensiune"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ultima modificare"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Număr de copii"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Numărul de articole"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"În ordine crescătoare"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"În ordine descrescătoare"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Afișați directoarele rădăcină"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Fișierul nu poate fi deschis"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Nu se pot deschide fișierele în arhive"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Anumite documente nu au putut fi șterse"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Proprietățile nu au putut fi încărcate"</string>
     <string name="share_via" msgid="8725082736005677161">"Trimiteți prin"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Se copiază fișierele"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Se comprimă fișierele"</string>
diff --git a/res/values-ru/inspector_strings.xml b/res/values-ru/inspector_strings.xml
new file mode 100644
index 0000000..614b3fa
--- /dev/null
+++ b/res/values-ru/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Информация"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Не удалось загрузить сведения о файле"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Сведения об отладке (только для разработчиков)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Исходные метаданные: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Медиаданные"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"В каком приложении открываются файлы этого типа"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Где находится файл"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Не выбрано"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Неизвестное приложение"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Размер"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> (<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Мпикс.)"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координаты"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Высота"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Диафрагма"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Выдержка"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Продолжительность"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Дата съемки"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокусное расстояние"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Эквивалент ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Исполнитель"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Альбом"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Место съемки"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Типы потоков"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Исходный размер (в байтах)"</string>
+</resources>
diff --git a/res/values-ru/mimes.xml b/res/values-ru/mimes.xml
new file mode 100644
index 0000000..55e9d8d
--- /dev/null
+++ b/res/values-ru/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Файл <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Изображение"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Изображение <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудиофайл"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Аудиофайл <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Видео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Видео <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Архив <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Приложение Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Обычный текст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-документ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Документ PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Документ Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Презентация PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Таблица Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Документ Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Таблица Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Презентация Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Рисунок Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Таблица Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Форма Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Карта Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Сайт на платформе Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Папка"</string>
+</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index c776240..6778c9f 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Сжать"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Извлечь"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Переименовать"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Свойства"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Сведения о файле"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Открыть в приложении \"<xliff:g id="SOURCE">%1$s</xliff:g>\""</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Новое окно"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Вырезать"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Переместить"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Скрыть"</string>
     <string name="button_retry" msgid="4011461781916631389">"Повторить"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Сбросить"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Открыть в приложении по умолчанию"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Документы не отсортированы"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Имя"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Сведения"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Размер"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Изменено"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Количество дочерних элементов"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Количество объектов"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"По возрастанию"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"По убыванию"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Показать корневые папки"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Не удалось открыть файл"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Нельзя открывать файлы в архивах"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Не удалось удалить некоторые документы"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Не удалось загрузить свойства"</string>
     <string name="share_via" msgid="8725082736005677161">"Поделиться"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Копирование файлов"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Сжатие файлов"</string>
diff --git a/res/values-si/inspector_strings.xml b/res/values-si/inspector_strings.xml
new file mode 100644
index 0000000..cbfab14
--- /dev/null
+++ b/res/values-si/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"තොරතුරු"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ගොනු තොරතුරු පූරණය කළ නොහැකි විය"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"දෝෂ නිරාකරණ තොරතුරු (සංවර්ධක පමණි)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"අමු පාරදත්ත: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"මාධ්‍ය විස්තර"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"මෙම ආකාරයේ ගොනුව මේ සමගින් විවෘත වේ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"මෙම ගොනුව සපයනු ලබන්නේ"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"තෝරා නොමැත"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"නොදනී"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"මාන"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ඛණ්ඩාංක"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"උන්නතාංශය"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"කැමරාව"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"විවරය"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"සංවාරක වේගය"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"කාල සීමාව"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ගන්නා ලද්දේ"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"නාභි දුර"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO තුල්‍ය"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"කලාකරු"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"සංගීතඥ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ඇල්බමය"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ස්ථානය"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ප්‍රවාහ වර්ග"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"අමු තරම (බයිට්)"</string>
+</resources>
diff --git a/res/values-si/mimes.xml b/res/values-si/mimes.xml
new file mode 100644
index 0000000..b881624
--- /dev/null
+++ b/res/values-si/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ගොනුව"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ගොනුව"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"රූපය"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> රූපය"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ශ්‍රව්‍ය"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ශ්‍රව්‍ය"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"වීඩියෝව"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> වීඩියෝව"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> සංරක්ෂණය"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android යෙදුම"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"සරල පෙළ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ලේඛනය"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ලේඛනය"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ලේඛනය"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint ඉදිරිපත් කිරීම"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel පැතුරුම්පත"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ලේඛනය"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google පැතුරුම්පත"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google ඉදිරිපත් කිරීම"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ඇඳීම"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google වගුව"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google පෝරමය"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google සිතියම්"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google අඩවිය"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ෆෝල්ඩරය"</string>
+</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index ead672e..e7eff9e 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"සම්පීඩනය කරන්න"</string>
     <string name="menu_extract" msgid="8171946945982532262">"උපුටා ගන්න…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"යළි නම් කරන්න"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"ගුණාංග"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"තොරතුරු ලබා ගන්න"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> තුළ බලන්න"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"නව කවුළුව"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"කපන්න"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ගෙන යන්න"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"අස් කරන්න"</string>
     <string name="button_retry" msgid="4011461781916631389">"නැවත උත්සාහ කරන්න"</string>
+    <string name="button_clear" msgid="5412304437764369441">"හිස් කරන්න"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"සැපයුම්කරු තුළ පෙන්වන්න"</string>
     <string name="not_sorted" msgid="7813496644889115530">"අනුපිළිවෙළට සකසා නැත"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"නම‍"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"සාරාංශය"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"වර්ගය"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"තරම"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"වෙනස් කළේ"</string>
-    <string name="directory_children" msgid="8115290268549503262">"ළමයින් ගණන"</string>
+    <string name="directory_items" msgid="6645621978998614003">"අයිතම ගණන:"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ආරෝහණ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"අවරෝහණ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"මුල් පෙන්වන්න"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ගොනුව විවෘත කළ නොහැකිය"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"සංරක්ෂිත තුළ ඇති ගොනු විවෘත කළ නොහැකිය"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"සමහර ලේඛන මැකීමට නොහැකිය"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"ගුණාංග පූරණය කිරීමට නොහැකි විය"</string>
     <string name="share_via" msgid="8725082736005677161">"බෙදාගන්නේ"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ගොනු පිටපත් කරමින්"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ගොනු සම්පීඩනය කරමින්"</string>
diff --git a/res/values-sk/inspector_strings.xml b/res/values-sk/inspector_strings.xml
new file mode 100644
index 0000000..d187051
--- /dev/null
+++ b/res/values-sk/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informácie"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Informácie o súbore sa nepodarilo načítať"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informácie o ladení (iba pre vývojárov)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Nespracované metadáta: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Podrobnosti o médiách"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Tento typ súboru sa otvára v aplikácii"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Poskytovateľ tohto súboru:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Nie je vybraná"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Neznáme"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Rozmery"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MPx"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Súradnice"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Nadmorská výška"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fotoaparát"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Clona"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Rýchlosť uzávierky"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Trvanie"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Nasnímané"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Ohnisková vzdialenosť"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Ekvivalent ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Interpret"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Skladateľ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Poloha"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Typy streamu"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Nespracovaná veľkosť (v bajtoch)"</string>
+</resources>
diff --git a/res/values-sk/mimes.xml b/res/values-sk/mimes.xml
new file mode 100644
index 0000000..5f5da5e
--- /dev/null
+++ b/res/values-sk/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Súbor <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Súbor"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Obrázok"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Obrázok <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Zvuk"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Zvuk <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Archív <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikácia Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Obyčajný text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokument HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokument PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokument Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Prezentácia PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Tabuľka Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokument Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Tabuľka Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Prezentácia Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Nákres Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabuľka Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formulár Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Web Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Priečinok"</string>
+</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index e2ce01a..f145c9a 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Komprimovať"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Rozbaliť do…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Premenovať"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Vlastnosti"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Zobraziť informácie"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Zobraziť v službe <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nové okno"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Vystrihnúť"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Presunúť"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Odmietnuť"</string>
     <string name="button_retry" msgid="4011461781916631389">"Skúsiť znova"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Vymazať"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Zobraziť u poskytovateľa"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nezoradené"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Názov"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Súhrn"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Typ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veľkosť"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Upravené"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Počet detí"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Počet položiek"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Vzostupne"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Zostupne"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Zobraziť korene"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Súbor nie je možné otvoriť"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Súbory sa nedajú otvoriť v archívoch"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Vlastníctva sa nepodarilo načítať"</string>
     <string name="share_via" msgid="8725082736005677161">"Zdieľať prostredníctvom"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopírovanie súborov"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Komprimujú sa súbory"</string>
diff --git a/res/values-sl/inspector_strings.xml b/res/values-sl/inspector_strings.xml
new file mode 100644
index 0000000..94ff443
--- /dev/null
+++ b/res/values-sl/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Podatki"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Podatkov o datoteki ni bilo mogoče naložiti"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Podatki za odpravljanje napak (samo za razvijalce)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Neobdelani metapodatki: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Podrobnosti o predstavnosti"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Za odpiranje te vrste datoteke se uporablja"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"To datoteko je posredoval"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ni izbrano"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Neznano"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Mere"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Višina"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Fotoaparat"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Zaslonka"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Hitrost zaslonke"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Trajanje"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Posneto"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Goriščna razdalja"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Ekvivalent ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Izvajalec"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Skladatelj"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokacija"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Vrste toka"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Neobdelana velikost (bajti)"</string>
+</resources>
diff --git a/res/values-sl/mimes.xml b/res/values-sl/mimes.xml
new file mode 100644
index 0000000..1428e27
--- /dev/null
+++ b/res/values-sl/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Datoteka <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Datoteka"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Slika"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Slika <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Zvočna datoteka"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Zvočna datoteka <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arhiv <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikacija za Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Navadno besedilo"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokument HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokument PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Wordov dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPointova predstavitev"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excelova preglednica"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Googlov dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Googlova preglednica"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Googlova predstavitev"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Googlova risba"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Googlova tabela"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Googlov obrazec"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Googlov zemljevid"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Googlovo spletno mesto"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mapa"</string>
+</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 0b43dbe..d462cbe 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Stisni"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Razširi v …"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Preimenuj"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Lastnosti"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Prikaži informacije"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Prikaži v aplikaciji <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Novo okno"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Izreži"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Premakni"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Opusti"</string>
     <string name="button_retry" msgid="4011461781916631389">"Poskusi znova"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Izbriši"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Prikaži na izvorni lokaciji"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Ni razvrščeno"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Ime"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Povzetek"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Vrsta"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Velikost"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Spremenjeno"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Število otrok"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Število elementov"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Naraščajoče"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Padajoče"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Pokaži korene"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Datoteke ni mogoče odpreti"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Datotek ni mogoče odpreti v arhivih"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nekaterih dokumentov ni mogoče izbrisati"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Lastnosti ni bilo mogoče naložiti"</string>
     <string name="share_via" msgid="8725082736005677161">"Deli z drugimi prek"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiranje datotek"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Stiskanje datotek"</string>
diff --git a/res/values-sq/inspector_strings.xml b/res/values-sq/inspector_strings.xml
new file mode 100644
index 0000000..2ab36dc
--- /dev/null
+++ b/res/values-sq/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Informacione"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Informacioni i skedarit nuk mund të ngarkohej"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Informacioni i korrigjimit (vetëm zhvilluesit)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Të dhënat meta të papërpunuara: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Detajet e medias"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ky lloj skedari hapet me"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Ky skedar ofrohet nga"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"I pazgjedhur"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"I panjohur"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Përmasat"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinatat"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Lartësia"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Hapja e diafragmës"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Shpejtësia e obturatorit"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Kohëzgjatja"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Shkrepur në"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Gjatësia fokale"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekuivalente"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artisti"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Kompozitori"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albumi"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Vendndodhja"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Llojet e transmetimit"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Madhësia e papërpunuar (bajte)"</string>
+</resources>
diff --git a/res/values-sq/mimes.xml b/res/values-sq/mimes.xml
new file mode 100644
index 0000000..915eb17
--- /dev/null
+++ b/res/values-sq/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Skedar <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Skedar"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Imazh"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Imazh <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Audio <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Arkiv <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Aplikacion i Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Tekst i thjeshtë"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Dokument HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Dokument PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokument Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Prezantim PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Fletëllogaritëse Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokument i Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Fletëllogaritëse e Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Prezantim i Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Vizatim i Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Tabelë e Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Formular i Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Hartë e Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Sajt i Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Dosje"</string>
+</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index f1f1478..3e31507 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Ngjish"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Nxirre te…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Riemërto"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Karakteristikat"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Merr informacione"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Shikoje në <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Dritare e re"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Prit"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Lëviz"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Hiqe"</string>
     <string name="button_retry" msgid="4011461781916631389">"Provo përsëri"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Pastro"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Shfaq te ofruesi"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Nuk janë të renditura"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Emri"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Përmbledhja"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Lloji"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Madhësia"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"U modifikua"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Numri i fëmijëve"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Numri i artikujve"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Në rritje"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Në zbritje"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Trego rrënjët"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Skedari nuk mund të hapet"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Skedarët në arkiva nuk mund të hapen"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"E pamundur të fshihen disa dokumente"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Karakteristikat nuk mund të ngarkoheshin"</string>
     <string name="share_via" msgid="8725082736005677161">"Shpërnda nëpërmjet"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Po kopjon skedarët"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Skedarët po ngjishen"</string>
diff --git a/res/values-sr/inspector_strings.xml b/res/values-sr/inspector_strings.xml
new file mode 100644
index 0000000..c5d9aff
--- /dev/null
+++ b/res/values-sr/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Информације"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Учитавање података о датотеци није успело"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Подаци о отклањању грешака (само за програмере)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Метаподаци RAW датотеке: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Детаљи о медијима"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Ова врста датотеке се отвара помоћу:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Ову датотеку пружа"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Није изабрано"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Непознато"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Димензије"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g>×<xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> мегапиксела"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координате"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Надморска висина"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Отвор бленде"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Брзина затварача"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Трајање"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Снимљено"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Жижна даљина"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO еквивалент"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Извођач"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Албум"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Локација"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Типови стримова"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Величина RAW датотеке (у бајтовима)"</string>
+</resources>
diff --git a/res/values-sr/mimes.xml b/res/values-sr/mimes.xml
new file mode 100644
index 0000000..f810e4a
--- /dev/null
+++ b/res/values-sr/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> датотека"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Датотека"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Слика"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> слика"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудио"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> аудио"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Видео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> видео"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> архива"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android апликација"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Обичан текст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML документ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF документ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word документ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint презентација"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel табела"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google документ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google табела"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google презентација"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google цртеж"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google табела"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google упитник"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google мапа"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google сајт"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Директоријум"</string>
+</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index ded0fb6..a36c3eb 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Компримуј"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Издвој у…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Преименуј"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Својства"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Прикажи информације"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Прикажи у: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Нови прозор"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Исеци"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Премести"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Одбаци"</string>
     <string name="button_retry" msgid="4011461781916631389">"Пробај поново"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Обриши"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Прикажи у апликацији добављача"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Нису сортирани"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Назив"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Резиме"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Величина"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Измењено"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Број деце"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Број ставки"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Растуће"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Опадајуће"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Прикажи основне директоријуме"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Отварање датотеке није успело"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Не можете да отварате датотеке у архивама"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Није могуће избрисати неке документе"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Учитавање својстава није успело"</string>
     <string name="share_via" msgid="8725082736005677161">"Дељење преко"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Копирамо датотеке"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Датотеке се компримују"</string>
diff --git a/res/values-sv/inspector_strings.xml b/res/values-sv/inspector_strings.xml
new file mode 100644
index 0000000..bb15919
--- /dev/null
+++ b/res/values-sv/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Information"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Det gick inte att läsa in filinformationen"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Felsökningsinformation (endast utvecklare)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Rå metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Medieuppgifter"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Den här filtypen öppnas med"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Den här filen tillhandahålls av"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Ingen har valts"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Okänd"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Mått"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinater"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Höjd"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Bländare"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Slutarhastighet"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Varaktighet"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Taget den"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Brännvidd"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO-motsvarighet"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Kompositör"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Plats"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Flödestyper"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Råstorlek (byte)"</string>
+</resources>
diff --git a/res/values-sv/mimes.xml b/res/values-sv/mimes.xml
new file mode 100644
index 0000000..a6b73ba
--- /dev/null
+++ b/res/values-sv/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g>-fil"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fil"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Bild"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g>-bild"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Ljud"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g>-ljud"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g>-video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g>-arkiv"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android-app"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Oformaterad text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML-dokument"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF-dokument"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word-dokument"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint-presentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel-kalkylark"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-dokument"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-kalkylark"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-presentation"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-teckning"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-tabell"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-formulär"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-karta"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-webbplats"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Mapp"</string>
+</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 107c2a4..7eab784 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Komprimera"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Extrahera till …"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Byt namn"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Egenskaper"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Hämta information"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Visa i <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Nytt fönster"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Klipp ut"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Flytta"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ta bort"</string>
     <string name="button_retry" msgid="4011461781916631389">"Försök igen"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Ta bort"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Visa hos leverantören"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Inte sorterade"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Namn"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Översikt"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Filtyp"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Storlek"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ändrades senast"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Antal barn"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Antal objekt"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stigande"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Fallande"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Visa rötter"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Det går inte att öppna filen"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Det går inte att öppna filer i arkiv"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Det gick inte att radera vissa dokument"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Det gick inte att läsa in egenskaper"</string>
     <string name="share_via" msgid="8725082736005677161">"Dela via"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopierar filer"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Filerna komprimeras"</string>
diff --git a/res/values-sw/inspector_strings.xml b/res/values-sw/inspector_strings.xml
new file mode 100644
index 0000000..d6d8e37
--- /dev/null
+++ b/res/values-sw/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Maelezo"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Imeshindwa kupakia maelezo ya faili"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Maelezo ya utatuzi (usanidi pekee)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Metadata ghafi: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Maelezo ya faili"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Aina hii ya faili inafunguka kwa kutumia"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Faili hii imetoka kwenye"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Haijachaguliwa"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Haijulikani"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Vipimo"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"MP <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Maeneo"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Mwinuko"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Kitundu cha kamera"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Kasi ya kilango cha kamera"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Muda"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Ilipigwa"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Urefu wa fokasi"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"mm <xliff:g id="LENGTH">%1$.2f </xliff:g>"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Inayolingana na ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Msanii"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Mtunzi"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albamu"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Mahali"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Aina za mipasho"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Ukubwa wa faili ghafi (baiti)"</string>
+</resources>
diff --git a/res/values-sw/mimes.xml b/res/values-sw/mimes.xml
new file mode 100644
index 0000000..e24a7f2
--- /dev/null
+++ b/res/values-sw/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Faili ya <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Faili"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Picha"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Picha ya <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Sauti"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Faili ya sauti ya <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video ya <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Faili ya kumbukumbu ya <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Programu ya Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Maandishi pekee"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Hati ya HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Hati ya PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Hati ya Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Wasilisho la PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Lahajedwali la Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Hati ya Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Lahajedwali la Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Wasilisho la Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Mchoro wa Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Jedwali la Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Fomu ya Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Ramani ya Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Tovuti ya Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folda"</string>
+</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 73ffd27..5063641 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Bana"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Weka kwenye…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Badilisha jina"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Sifa"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Pata maelezo zaidi"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Angalia katika <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Dirisha jipya"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Kata"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Hamisha"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Ondoa"</string>
     <string name="button_retry" msgid="4011461781916631389">"Jaribu Tena"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Futa"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Onyesha kwenye programu ya mtoa huduma"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Hazijapangwa"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Jina"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Muhtasari"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Aina"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Ukubwa"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ilibadilishwa"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Idadi ya Watoto"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Idadi ya vipengee"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Kupanga kwa kupanda"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Kupanga kwa kushuka"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Onyesha nyenzo"</string>
@@ -82,11 +84,10 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Haiwezi kufungua faili"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Haiwezi kufungua faili zilizo kwenye kumbukumbu"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Imeshindwa kufuta baadhi ya hati"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Imeshindwa kupakia vipengee vya faili"</string>
     <string name="share_via" msgid="8725082736005677161">"Shiriki kupitia"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Inanakili faili"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Inabana faili"</string>
-    <string name="extract_notification_title" msgid="5067393961754430469">"Inatoa faili"</string>
+    <string name="extract_notification_title" msgid="5067393961754430469">"Faili zinatolewa"</string>
     <string name="move_notification_title" msgid="3173424987049347605">"Inahamisha faili"</string>
     <string name="delete_notification_title" msgid="2512757431856830792">"Inafuta faili"</string>
     <string name="copy_remaining" msgid="5390517377265177727">"Zimesalia <xliff:g id="DURATION">%s</xliff:g>"</string>
@@ -99,8 +100,8 @@
       <item quantity="one">Inabana faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
     </plurals>
     <plurals name="extract_begin" formatted="false" msgid="1006380679562903749">
-      <item quantity="other">Inatoa faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
-      <item quantity="one">Inatoa faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+      <item quantity="other">Faili <xliff:g id="COUNT_1">%1$d</xliff:g> zinatolewa.</item>
+      <item quantity="one">Faili <xliff:g id="COUNT_0">%1$d</xliff:g> inatolewa.</item>
     </plurals>
     <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
       <item quantity="other">Inahamisha vipengee <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
@@ -133,7 +134,7 @@
       <item quantity="other">Imeshindwa kufuta vipengee <xliff:g id="COUNT_1">%1$d</xliff:g></item>
       <item quantity="one">Imeshindwa kufuta kipengee <xliff:g id="COUNT_0">%1$d</xliff:g></item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="2385563502445129570">"Gonga ili uangalie maelezo"</string>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"Gusa ili uangalie maelezo"</string>
     <string name="close" msgid="905969391788869975">"Funga"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
       <item quantity="other">Haikunakili faili hizi: <xliff:g id="LIST_1">%1$s</xliff:g></item>
@@ -203,6 +204,6 @@
     <string name="cant_display_content" msgid="8633226333229417237">"Imeshindwa kuonyesha maudhui"</string>
     <string name="sign_in" msgid="6253762676723505592">"Ingia katika akaunti"</string>
     <string name="new_archive_file_name" msgid="1604650338077249838">"weka <xliff:g id="EXTENSION">%s</xliff:g> kwenye kumbukumbu"</string>
-    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Ungependa kufuta <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Ungependa kubadili <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Endelea shughuli chini chini"</string>
 </resources>
diff --git a/res/values-ta/inspector_strings.xml b/res/values-ta/inspector_strings.xml
new file mode 100644
index 0000000..41bad8a
--- /dev/null
+++ b/res/values-ta/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"தகவல்"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"கோப்புத் தகவலை ஏற்ற முடியவில்லை"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"பிழைத்திருத்தத் தகவல் (டெவெலப்பர்கள் மட்டும்)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"அசல் மீத்தரவு: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"மீடியா விவரங்கள்"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"இந்தக் கோப்பு வகையை, பின்வரும் பயன்பாடு திறக்கும்:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"இந்தக் கோப்பை வழங்குவது:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"தேர்ந்தெடுக்கவில்லை"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"தெரியாதது"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"பரிமாணங்கள்"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ஆயத்தொலைவுகள்"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"உயரம்"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"கேமரா"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"அபெர்ச்சர்"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ஷட்டர் வேகம்"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"கால அளவு"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"படமெடுத்தது:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"குவியத்தூரம்"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>மிமீ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO சமதிறன்"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"கலைஞர்"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"இசையமைப்பாளர்"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ஆல்பம்"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"இருப்பிடம்"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ஸ்ட்ரீம் வகைகள்"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"அசல் அளவு (பைட்டுகள்)"</string>
+</resources>
diff --git a/res/values-ta/mimes.xml b/res/values-ta/mimes.xml
new file mode 100644
index 0000000..04a8c3f
--- /dev/null
+++ b/res/values-ta/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> கோப்பு"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"கோப்பு"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"படம்"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> படம்"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ஆடியோ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ஆடியோ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"வீடியோ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> வீடியோ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> காப்பகம்"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android பயன்பாடு"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"எளிய உரை"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ஆவணம்"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ஆவணம்"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ஆவணம்"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint விளக்கக்காட்சி"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel விரிதாள்"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ஆவணம்"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google விரிதாள்"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google விளக்கக்காட்சி"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google டிராயிங்"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google அட்டவணை"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google படிவம்"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google வரைபடம்"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google தளம்"</string>
+    <string name="directory_type" msgid="2702987727566226354">"கோப்புறை"</string>
+</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 1090358..cac3838 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="files_label" msgid="771781190045103748">"கோப்புகள்"</string>
+    <string name="files_label" msgid="771781190045103748">"ஃபைல்கள்"</string>
     <string name="downloads_label" msgid="5462789470049501103">"இறக்கங்கள்"</string>
     <!-- no translation found for app_label (8089292432455111409) -->
     <skip />
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"அளவைக் குறை"</string>
     <string name="menu_extract" msgid="8171946945982532262">"இங்கு பிரி…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"மறுபெயரிடு"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"பண்புகள்"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"தகவலைப் பெறு"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> இல் காட்டு"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"புதிய சாளரம்"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"வெட்டு"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"நகர்த்து"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"நிராகரி"</string>
     <string name="button_retry" msgid="4011461781916631389">"மீண்டும் முயலவும்"</string>
+    <string name="button_clear" msgid="5412304437764369441">"அழி"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"வழங்குநரில் காட்டு"</string>
     <string name="not_sorted" msgid="7813496644889115530">"வரிசைப்படுத்தப்படவில்லை"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"பெயர்"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"சுருக்க விவரம்"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"வகை"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"அளவு"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"மாற்றியது"</string>
-    <string name="directory_children" msgid="8115290268549503262">"குழந்தைகளின் எண்ணிக்கை"</string>
+    <string name="directory_items" msgid="6645621978998614003">"உருப்படிகளின் எண்ணிக்கை"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ஏறுவரிசையில்"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"இறங்குவரிசையில்"</string>
     <string name="drawer_open" msgid="8071673398187261741">"சேமித்த இடத்தைக் காட்டு"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"கோப்பைத் திறக்க முடியாது"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"காப்பகங்களில் உள்ள கோப்புகளைத் திறக்க முடியாது"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"பண்புகளை ஏற்ற முடியவில்லை"</string>
     <string name="share_via" msgid="8725082736005677161">"இதன் வழியாகப் பகிர்"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"கோப்புகளை நகலெடுத்தல்"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"அளவைக் குறைக்கிறது"</string>
diff --git a/res/values-te/inspector_strings.xml b/res/values-te/inspector_strings.xml
new file mode 100644
index 0000000..97dd812
--- /dev/null
+++ b/res/values-te/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"సమాచారం"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ఫైల్ సమాచారాన్ని లోడ్ చేయడం సాధ్యపడలేదు"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"డీబగ్ సమాచారం (డెవలపర్ మాత్రమే)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ప్రాసెస్ చేయని మెటాడేటా: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"మీడియా వివరాలు"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ఈ రకమైన ఫైల్ దీనితో తెరవబడుతుంది"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ఇది ఈ ఫైల్‌ని అందించింది"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ఎంచుకోబడలేదు"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"తెలియదు"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"కొలతలు"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"అక్షాంశాలు"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ఎత్తు"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"కెమెరా"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ఎపర్చర్"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"షట్టర్ వేగం"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"వ్యవధి"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ఫోటో ఈ తేదీన తీయబడింది"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ఫోకల్ పొడవు"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>మి.మీ"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO సమానమైనది"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"కళాకారుడు"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"కంపోజర్"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ఆల్బమ్"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"స్థానం"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ప్రసార రకాలు"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ప్రాసెస్ చేయని పరిమాణం (బైట్‌లు)"</string>
+</resources>
diff --git a/res/values-te/mimes.xml b/res/values-te/mimes.xml
new file mode 100644
index 0000000..bcbbda2
--- /dev/null
+++ b/res/values-te/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ఫైల్"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ఫైల్"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"చిత్రం"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> చిత్రం"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ఆడియో"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ఆడియో"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"వీడియో"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> వీడియో"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> ఆర్కైవ్"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android అప్లికేషన్"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"సాదా వచనం"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML పత్రం"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF పత్రం"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word పత్రం"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint ప్రెజెంటేషన్"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel స్ప్రెడ్‌షీట్"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google పత్రం"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google స్ప్రెడ్‌షీట్"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google ప్రెజెంటేషన్"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google డ్రాయింగ్"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google పట్టిక"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ఫారమ్"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google మ్యాప్"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google సైట్"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ఫోల్డర్"</string>
+</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index bc286e2..68ac482 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -27,7 +27,7 @@
     <string name="menu_create_dir" msgid="2413624798689091042">"కొత్త ఫోల్డర్"</string>
     <string name="menu_grid" msgid="1453636521731880680">"గ్రిడ్ వీక్షణ"</string>
     <string name="menu_list" msgid="6714267452146410402">"జాబితా వీక్షణ"</string>
-    <string name="menu_search" msgid="1876699106790719849">"శోధించు"</string>
+    <string name="menu_search" msgid="1876699106790719849">"వెతుకు"</string>
     <string name="menu_settings" msgid="6520844520117939047">"నిల్వ సెట్టింగ్‌లు"</string>
     <string name="menu_open" msgid="9092138100049759315">"తెరువు"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"దీనితో తెరువు"</string>
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"కుదించు"</string>
     <string name="menu_extract" msgid="8171946945982532262">"దీనిలోకి సంగ్రహించు…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"పేరు మార్చు"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"లక్షణాలు"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"సమాచారాన్ని పొందండి"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>లో వీక్షించు"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"కొత్త విండో"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"కత్తిరించు"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"తరలించు"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"తీసివేయి"</string>
     <string name="button_retry" msgid="4011461781916631389">"మళ్లీ ప్రయత్నించు"</string>
+    <string name="button_clear" msgid="5412304437764369441">"తీసివేయండి"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ప్రదాతలో చూపించండి"</string>
     <string name="not_sorted" msgid="7813496644889115530">"క్రమబద్ధీకరించలేదు"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"పేరు"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"సారాంశం"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"రకం"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"పరిమాణం"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"సవరించిన సమయం"</string>
-    <string name="directory_children" msgid="8115290268549503262">"పిల్లల సంఖ్య"</string>
+    <string name="directory_items" msgid="6645621978998614003">"అంశాల సంఖ్య"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ఆరోహణ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"అవరోహణ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"మూలాలను చూపు"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"ఫైల్‌ను తెరవడం సాధ్యపడదు"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"ఆర్కైవ్‌లలో ఉన్న ఫైల్‌లను తెరవడం సాధ్యం కాదు"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"కొన్ని పత్రాలను తొలగించడం సాధ్యపడలేదు"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"లక్షణాలను లోడ్ చేయలేకపోయింది"</string>
     <string name="share_via" msgid="8725082736005677161">"దీనితో భాగస్వామ్యం చేయండి"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"ఫైల్‌లు కాపీ అవుతున్నాయి"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ఫైల్‌లను కుదిస్తోంది"</string>
@@ -179,7 +180,7 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item>
     </plurals>
     <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> అంశాలు</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> వస్తువులు</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> అంశం</item>
     </plurals>
     <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"\"<xliff:g id="NAME">%1$s</xliff:g>\"ని తొలగించాలా?"</string>
diff --git a/res/values-th/inspector_strings.xml b/res/values-th/inspector_strings.xml
new file mode 100644
index 0000000..855b581
--- /dev/null
+++ b/res/values-th/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ข้อมูล"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ไม่สามารถโหลดข้อมูลไฟล์"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ข้อมูลการแก้ไขข้อบกพร่อง (dev only)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ข้อมูลเมตา Raw: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"รายละเอียดสื่อ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ไฟล์ประเภทนี้เปิดด้วย"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ไฟล์นี้จัดหาโดย"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ไม่ได้เลือก"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"ไม่ทราบ"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ขนาด"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"พิกัด"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ระดับความสูง"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"กล้อง"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"รูรับแสง"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ความเร็วชัตเตอร์"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ระยะเวลา"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ถ่ายเมื่อ"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ความยาวโฟกัส"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> มม."</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO เทียบเท่า"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"ศิลปิน"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"ผู้ประพันธ์เพลง"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"อัลบั้ม"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ตำแหน่ง"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ประเภทสตรีม"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ขนาด Raw (ไบต์)"</string>
+</resources>
diff --git a/res/values-th/mimes.xml b/res/values-th/mimes.xml
new file mode 100644
index 0000000..c29f40b
--- /dev/null
+++ b/res/values-th/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"ไฟล์ <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ไฟล์"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"รูปภาพ"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"ภาพ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"เสียง"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"ไฟล์เสียง <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"วิดีโอ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"วิดีโอ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"ไฟล์ที่เก็บถาวร <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"แอปพลิเคชัน Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"ข้อความล้วน"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"เอกสาร HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"เอกสาร PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"เอกสาร Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"งานนำเสนอ PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"สเปรดชีต Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google เอกสาร"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google สเปรดชีต"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google งานนำเสนอ"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ภาพวาด"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google ตาราง"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ฟอร์ม"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google Map"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google Site"</string>
+    <string name="directory_type" msgid="2702987727566226354">"โฟลเดอร์"</string>
+</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index a3a85d3..b94205c 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"บีบอัด"</string>
     <string name="menu_extract" msgid="8171946945982532262">"แตกข้อมูลไปยัง…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"เปลี่ยนชื่อ"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"คุณสมบัติ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"รับข้อมูล"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"ดูใน <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"หน้าต่างใหม่"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"ตัด"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"ย้าย"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"ปิด"</string>
     <string name="button_retry" msgid="4011461781916631389">"ลองใหม่"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ล้าง"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"แสดงในแอปผู้ให้บริการ"</string>
     <string name="not_sorted" msgid="7813496644889115530">"ไม่ได้จัดเรียง"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"ชื่อ"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"สรุป"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ประเภท"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ขนาด"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"แก้ไข"</string>
-    <string name="directory_children" msgid="8115290268549503262">"จำนวนบุตรหลาน"</string>
+    <string name="directory_items" msgid="6645621978998614003">"จำนวนรายการ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"จากน้อยไปมาก"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"จากมากไปน้อย"</string>
     <string name="drawer_open" msgid="8071673398187261741">"แสดงราก"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"เปิดไฟล์ไม่ได้"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"เปิดไฟล์ในที่เก็บถาวรไม่ได้"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"ไม่สามารถลบเอกสารบางรายการ"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"ไม่สามารถโหลดพร็อพเพอร์ตี้"</string>
     <string name="share_via" msgid="8725082736005677161">"แชร์ผ่าน"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"กำลังคัดลอกไฟล์"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"กำลังบีบอัดไฟล์"</string>
diff --git a/res/values-tl/inspector_strings.xml b/res/values-tl/inspector_strings.xml
new file mode 100644
index 0000000..a18fe5a
--- /dev/null
+++ b/res/values-tl/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Impormasyon"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Hindi ma-load ang impormasyon ng file"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Impormasyon ng debug (dev lang)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Raw na metadata: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Mga detalye ng media"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Nabubuksan ang ganitong uri ng file sa"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Ang file na ito ay ibinigay ng"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Hindi napili"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Hindi Alam"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Mga Dimensyon"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Mga Coordinate"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Altitude"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Camera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Aperture"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Bilis ng shutter"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Tagal"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Kinunan noong"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Focal length"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Katumbas sa ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Artist"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Composer"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Lokasyon"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Mga uri ng stream"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Raw na laki (mga byte)"</string>
+</resources>
diff --git a/res/values-tl/mimes.xml b/res/values-tl/mimes.xml
new file mode 100644
index 0000000..ecc62d8
--- /dev/null
+++ b/res/values-tl/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> na file"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"File"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Larawan"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> na larawan"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> na audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> na video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> na archive"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android application"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Plain text"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML na dokumento"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF na dokumento"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Dokumento sa Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint presentation"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Spreadsheet sa Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Dokumento sa Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Spreadsheet sa Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Presentation sa Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Drawing sa Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Talahanayan sa Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Form sa Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Mapa sa Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Site ng Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Folder"</string>
+</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 25daf25..ac28e52 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"I-compress"</string>
     <string name="menu_extract" msgid="8171946945982532262">"I-extract sa…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Palitan ang pangalan"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Mga Property"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Kumuha ng impormasyon"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Tingnan sa <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Bagong window"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"I-cut"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Ilipat"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"I-dismiss"</string>
     <string name="button_retry" msgid="4011461781916631389">"Subukang Muli"</string>
+    <string name="button_clear" msgid="5412304437764369441">"I-clear"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Ipakita sa provider"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Hindi napagbukud-bukod"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Pangalan"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Buod"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Uri"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Laki"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Binago"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Bilang ng Mga Bata"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Bilang ng mga item"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Pataas"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Pababa"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Ipakita ang mga root"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Hindi mabuksan ang file"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Hindi mabuksan ang mga file sa mga archive"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Hindi ma-delete ang ilang dokumento"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Hindi ma-load ang mga property"</string>
     <string name="share_via" msgid="8725082736005677161">"Ibahagi gamit ang"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kinokopya ang mga file"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Kino-compress ang files"</string>
diff --git a/res/values-tr/inspector_strings.xml b/res/values-tr/inspector_strings.xml
new file mode 100644
index 0000000..23e01c0
--- /dev/null
+++ b/res/values-tr/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Bilgi"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Dosya bilgisi yüklenemedi"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Hata ayıklama bilgileri (yalnızca geliştirici)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"İşlenmemiş meta veri: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Medya ayrıntıları"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Bu tür dosyalar şu uygulamayla açılır:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Bu dosyayı sağlayan:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Seçili değil"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Bilinmiyor"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Boyutlar"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinatlar"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Rakım"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Diyafram açıklığı"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Deklanşör hızı"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Süre"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Çekim zamanı:"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Odak uzaklığı"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO karşılığı"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Sanatçı"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Besteci"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albüm"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Konum"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Akış türleri"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"İşlenmemiş boyut (bayt)"</string>
+</resources>
diff --git a/res/values-tr/mimes.xml b/res/values-tr/mimes.xml
new file mode 100644
index 0000000..c76e0f6
--- /dev/null
+++ b/res/values-tr/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> dosyası"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Dosya"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Resim"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> resmi"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Ses"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ses"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> videosu"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arşivi"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android uygulaması"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Düz metin"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML dokümanı"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF dokümanı"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word dokümanı"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint sunusu"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel e-tablosu"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google dokümanı"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google e-tablosu"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google sunusu"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google çizimi"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google tablosu"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google formu"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google haritası"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google sitesi"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Klasör"</string>
+</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 46d631e..7556431 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Sıkıştır"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Şuraya çıkar:"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Yeniden Adlandır"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Özellikler"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Bilgi al"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> içinde görüntüle"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Yeni pencere"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Kes"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Taşı"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Kapat"</string>
     <string name="button_retry" msgid="4011461781916631389">"Tekrar Dene"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Temizle"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Sağlayıcıda göster"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Sıralanmadı"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Ad"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Özet"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tür"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Boyut"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Değiştirilme zamanı"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Çocuk Sayısı"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Ürün sayısı"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Artan"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Azalan"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Kök dizinleri göster"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Dosya açılamıyor"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Arşivlerdeki dosyalar açılamaz"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Bazı dokümanlar silinemiyor"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Özellikler yüklenemedi"</string>
     <string name="share_via" msgid="8725082736005677161">"Şunu kullanarak paylaşın:"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Dosyalar kopyalanıyor"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Dosyalar sıkıştırılıyor"</string>
diff --git a/res/values-uk/inspector_strings.xml b/res/values-uk/inspector_strings.xml
new file mode 100644
index 0000000..319b598
--- /dev/null
+++ b/res/values-uk/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Інформація"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Не вдалося завантажити інформацію про файл"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Дані про налагодження (лише для розробників)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Метадані файлу RAW: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Деталі медіа-вмісту"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Цей тип файлу відкривається в додатку"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Цей файл надає"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Не вибрано"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Невідомо"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Розміри"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> Мпікс."</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Координати"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Висота"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Камера"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Апертура"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Швидкість затвора"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Тривалість"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Знято"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Фокусна відстань"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> мм"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Еквівалент ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"Швидкість ISO: <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Виконавець"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Композитор"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Альбом"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Місцезнаходження"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Типи потоків"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Розмір файлу RAW (байти)"</string>
+</resources>
diff --git a/res/values-uk/mimes.xml b/res/values-uk/mimes.xml
new file mode 100644
index 0000000..e41138b
--- /dev/null
+++ b/res/values-uk/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Файл <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Файл"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Зображення"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Зображення <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Аудіо"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Аудіо <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Відео"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Відео <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Архів <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Додаток Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Звичайний текст"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Документ HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Документ PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Документ Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Презентація PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Електронна таблиця Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Документ Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Таблиця Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Презентація Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Малюнок Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Таблиця Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Форма Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Карта Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Сайт Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Папка"</string>
+</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 1a7f83e..e0d1fb0 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Стиснути"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Розпакувати…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Перейменувати"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Властивості"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Переглянути інформацію"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Переглянути в службі <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Нове вікно"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Вирізати"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Перемістити"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Відхилити"</string>
     <string name="button_retry" msgid="4011461781916631389">"Повторити"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Очистити"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Показати в сервісі постачальника"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Не сортовано"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Назва"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Короткий опис"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Розмір"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Змінено"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Кількість дітей"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Кількість елементів"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"За зростанням"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"За спаданням"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Показати кореневі каталоги"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Не вдалося відкрити файл"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Не вдалося відкрити файли в архівах"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Не вдалося видалити деякі документи"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Не вдалося завантажити параметри"</string>
     <string name="share_via" msgid="8725082736005677161">"Надіслати через"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Копіювання файлів"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Файли стискаються"</string>
diff --git a/res/values-ur/inspector_strings.xml b/res/values-ur/inspector_strings.xml
new file mode 100644
index 0000000..bfe1b66
--- /dev/null
+++ b/res/values-ur/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"معلومات"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"فائل کى معلومات لوڈ نہیں کی جا سکی"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ڈیبگ کی معلومات (ڈیولپر فقط)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"خام میٹا ڈیٹا: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"میڈیا کی تفصیلات"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"اس قسم کی فائل اس کے ساتھ کُھلتی ہے"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"یہ فائل فراہم کی جاتی ہے"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"غیر منتخب کردہ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"نامعلوم"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ابعاد"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"کوآرڈینیٹس"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>، <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"اونچائی"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"کیمرا"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"اپرچر"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"شٹر کی رفتار"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"مدت"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"تصویر لے لی گئی"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ماسکہ کی طوالت"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>ملی میٹر"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‏ISO کے مساوی"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"فنکار"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"کمپوزر"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"البم"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"مقام"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"سلسلہ کی قسمیں"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"خام سائز (بائٹس)"</string>
+</resources>
diff --git a/res/values-ur/mimes.xml b/res/values-ur/mimes.xml
new file mode 100644
index 0000000..045182a
--- /dev/null
+++ b/res/values-ur/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> فائل"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"فائل"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"تصویر"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> تصویر"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"آڈیو"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> آڈیو"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ویڈیو"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ویڈیو"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> آرکائيو"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"‏Android ایپلیکیشن"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"سادہ متن"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"‏HTML دستاویز"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"‏PDF دستاویز"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"‏Word دستاویز"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"‏PowerPoint پیشکش"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"‏Excel اسپریڈ شیٹ"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"‏Google دستاویز"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"‏Google اسپریڈ شیٹ"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"‏Google پیشکش"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"‏Google ڈرائنگ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"‏Google ٹیبل"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"‏Google فارم"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"‏Google نقشہ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"‏Google سائٹ"</string>
+    <string name="directory_type" msgid="2702987727566226354">"فولڈر"</string>
+</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 068550d..2956505 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"کمپریس کریں"</string>
     <string name="menu_extract" msgid="8171946945982532262">"اس میں کھولیں۔۔۔"</string>
     <string name="menu_rename" msgid="1883113442688817554">"نام تبدیل کریں"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"خصوصیات"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"معلومات حاصل کریں"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> میں دیکھیں"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"نئی ونڈو"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"کٹ کریں"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"منتقل کریں"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"کالعدم کریں"</string>
     <string name="button_retry" msgid="4011461781916631389">"دوبارہ کوشش کریں"</string>
+    <string name="button_clear" msgid="5412304437764369441">"صاف کریں"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"فراہم کنندہ میں دکھائیں"</string>
     <string name="not_sorted" msgid="7813496644889115530">"ترتیب میں نہیں ہیں"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"نام"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"خلاصہ"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"قسم"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"سائز"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ترمیم ہوئی"</string>
-    <string name="directory_children" msgid="8115290268549503262">"بچوں کی تعداد"</string>
+    <string name="directory_items" msgid="6645621978998614003">"آئٹمز کی تعداد"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"صعودی"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"نزولی"</string>
     <string name="drawer_open" msgid="8071673398187261741">"روٹس دکھائیں"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"فائل نہیں کھل سکتی"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"فائلوں کو آرکائیوز میں کھولا نہیں جا سکتا"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"کچھ دستاویزات کو حذف کرنے سے قاصر"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"خصوصیات کو لوڈ نہیں کیا جا سکا"</string>
     <string name="share_via" msgid="8725082736005677161">"اشتراک کریں بذریعہ"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"فائلیں کاپی ہو رہی ہیں"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"فائلز کمپریس ہو رہی ہیں"</string>
diff --git a/res/values-uz/inspector_strings.xml b/res/values-uz/inspector_strings.xml
new file mode 100644
index 0000000..1a791f3
--- /dev/null
+++ b/res/values-uz/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Ma’lumot"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Fayl haqida ma’lumotni yuklab bo‘lmadi"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Xatoliklarni tuzatish (faqat dasturchilar uchun)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW fayli meta-axboroti: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Media tafsilotlari"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Bu turdagi fayl quyidagilar bilan ochiladi"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Bu fayl ta’minotchisi"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Tanlanmagan"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Noma’lum"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"O‘lchamlar"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> – <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Koordinatalari"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Dengiz sathidan balandligi"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Kamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Diafragma"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Zatvor tezligi"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Davomiyligi"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Yaratilgan sanasi"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Fokus masofasi"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ekvivalenti"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Ijrochi"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Bastakor"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Albom"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Joylashuv"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Strim turlari"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"RAW fayl hajmi (bayt)"</string>
+</resources>
diff --git a/res/values-uz/mimes.xml b/res/values-uz/mimes.xml
new file mode 100644
index 0000000..d9a4346
--- /dev/null
+++ b/res/values-uz/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> fayl"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Fayl"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Rasm"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> rasm"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Audio"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> audio"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> video"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> arxiv"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ilovasi"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Oddiy matn"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML hujjat"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF hujjat"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word hujjat"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint taqdimot"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel jadval"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google-hujjat"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google-jadval"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google-taqdimot"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google-chizma"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google-jadval"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google-shakl"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google-xarita"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-sayt"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Jild"</string>
+</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 9d84a82..e221715 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -26,7 +26,7 @@
     <string name="title_save" msgid="4384490653102710025">"Saqlash"</string>
     <string name="menu_create_dir" msgid="2413624798689091042">"Yangi jild"</string>
     <string name="menu_grid" msgid="1453636521731880680">"To‘r ko‘rinishida"</string>
-    <string name="menu_list" msgid="6714267452146410402">"Ro‘yxat ko‘rinishida"</string>
+    <string name="menu_list" msgid="6714267452146410402">"Qator"</string>
     <string name="menu_search" msgid="1876699106790719849">"Qidiruv"</string>
     <string name="menu_settings" msgid="6520844520117939047">"Xotira sozlamalari"</string>
     <string name="menu_open" msgid="9092138100049759315">"Ochish"</string>
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Arxivlash"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Arxivdan chiqarish"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Qayta nomlash"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Xususiyatlar"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Ma’lumot olish"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> orqali ochish"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Yangi oyna"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Kesish"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Ko‘chirib o‘tkazish"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Yopish"</string>
     <string name="button_retry" msgid="4011461781916631389">"Qayta urinib ko‘rish"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Tozalash"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Ta’minotchi orqali ko‘rsatish"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Saralanmagan"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Nomi"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Qisqacha tavsif"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Turi"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Hajmi"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Tahrirlangan"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Quyi elementlar soni"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Elementlar soni"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"O‘sish bo‘yicha"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Kamayish bo‘yicha"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Ko‘rsatish"</string>
@@ -82,8 +84,7 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Faylni ochib bo‘lmadi"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Arxivdagi fayllarni ochib bo‘lmadi"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Ba’zi hujjatlarni o‘chirib bo‘lmadi"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Xususiyatlarni yuklab bo‘lmadi"</string>
-    <string name="share_via" msgid="8725082736005677161">"Baham ko‘rish"</string>
+    <string name="share_via" msgid="8725082736005677161">"Ulashish"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Fayllar nusxalanmoqda"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Fayllar arxivlanmoqda"</string>
     <string name="extract_notification_title" msgid="5067393961754430469">"Arxivdan chiqarilmoqda"</string>
diff --git a/res/values-vi/inspector_strings.xml b/res/values-vi/inspector_strings.xml
new file mode 100644
index 0000000..c540bff
--- /dev/null
+++ b/res/values-vi/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Thông tin"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Không thể tải thông tin tệp"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Thông tin gỡ lỗi (chỉ dành cho nhà phát triển)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Siêu dữ liệu Raw: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Chi tiết về phương tiện"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Loại tệp này mở bằng"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Tệp này được cung cấp bởi"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Chưa chọn"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Không xác định"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Kích thước"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Tọa độ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Độ cao"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Máy ảnh"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Khẩu độ"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Tốc độ chụp"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Thời lượng"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Chụp vào"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Tiêu cự"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO tương đương"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Nghệ sĩ"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Nhà soạn nhạc"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"Album"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Địa điểm"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Loại luồng"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Kích thước tệp Raw (byte)"</string>
+</resources>
diff --git a/res/values-vi/mimes.xml b/res/values-vi/mimes.xml
new file mode 100644
index 0000000..437211f
--- /dev/null
+++ b/res/values-vi/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"Tệp <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Tệp"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Hình ảnh"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"Hình ảnh <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Âm thanh"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"Âm thanh <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Video"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"Video <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"Lưu trữ <xliff:g id="FILETYPE">%1$s</xliff:g>"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Ứng dụng Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Văn bản thuần"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Tài liệu HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Tài liệu PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Tài liệu Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Bản trình bày PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Bảng tính Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Tài liệu Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Bảng tính Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Bản trình bày Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Bản vẽ Google"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Bảng Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Biểu mẫu Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Bản đồ Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Trang web Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Thư mục"</string>
+</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 4dd695d..4bce8a3 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Nén"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Trích xuất sang…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Đổi tên"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Thuộc tính"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Xem thông tin"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Xem trong <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Cửa sổ mới"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Cắt"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Chuyển"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Loại bỏ"</string>
     <string name="button_retry" msgid="4011461781916631389">"Thử lại"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Xóa"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Hiển thị trong nhà cung cấp"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Chưa được sắp xếp"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Tên"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Tóm tắt"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Loại"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Kích thước"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Đã sửa đổi"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Số trẻ em"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Số mục"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Tăng dần"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Giảm dần"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Hiển thị gốc"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Không thể mở tệp"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Không thể mở tệp trong lưu trữ"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Không thể xóa một số tài liệu"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Không thể tải các thuộc tính"</string>
     <string name="share_via" msgid="8725082736005677161">"Chia sẻ qua"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Đang sao chép tệp"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Nén tệp"</string>
diff --git a/res/values-zh-rCN/inspector_strings.xml b/res/values-zh-rCN/inspector_strings.xml
new file mode 100644
index 0000000..312f3db
--- /dev/null
+++ b/res/values-zh-rCN/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"信息"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"无法加载文件信息"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"调试信息(仅限开发者)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"原始元数据:<xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"媒体详情"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"使用以下应用打开这类文件:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"此文件的提供方:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"未选择"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"未知"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"尺寸"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> 百万像素"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"坐标"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>,<xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"海拔"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"相机"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"光圈"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"快门速度"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"时长"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"拍摄时间"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"焦距"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> 毫米"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO 等效感光度"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"音乐人"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"作曲家"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"专辑"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"位置"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"流式传输类型"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"原始大小(字节)"</string>
+</resources>
diff --git a/res/values-zh-rCN/mimes.xml b/res/values-zh-rCN/mimes.xml
new file mode 100644
index 0000000..eb3a6c1
--- /dev/null
+++ b/res/values-zh-rCN/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> 文件"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"文件"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"图片"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> 图片"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"音频"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> 音频"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"视频"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> 视频"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> 归档文件"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android 应用"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"纯文本"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML 文档"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF 文档"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word 文档"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint 演示文稿"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel 电子表格"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google 文档"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google 电子表格"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google 演示文稿"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google 绘图"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google 表格"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google 表单"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google 地图"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google 网站"</string>
+    <string name="directory_type" msgid="2702987727566226354">"文件夹"</string>
+</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 1aec392..cb990eb 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"压缩"</string>
     <string name="menu_extract" msgid="8171946945982532262">"解压到…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"重命名"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"属性"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"获取信息"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"在“<xliff:g id="SOURCE">%1$s</xliff:g>”中查看"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"新建窗口"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"剪切"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"移动"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"关闭"</string>
     <string name="button_retry" msgid="4011461781916631389">"重试"</string>
+    <string name="button_clear" msgid="5412304437764369441">"清除"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"在提供程序中显示"</string>
     <string name="not_sorted" msgid="7813496644889115530">"未排序"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"名称"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"摘要"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"类型"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"大小"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"上次修改时间"</string>
-    <string name="directory_children" msgid="8115290268549503262">"儿童人数"</string>
+    <string name="directory_items" msgid="6645621978998614003">"项数"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"升序"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"降序"</string>
     <string name="drawer_open" msgid="8071673398187261741">"显示根目录"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"无法打开文件"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"无法打开归档文件"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"无法删除部分文档"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"无法加载属性"</string>
     <string name="share_via" msgid="8725082736005677161">"分享方式"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"正在复制文件"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"正在压缩文件"</string>
diff --git a/res/values-zh-rHK/inspector_strings.xml b/res/values-zh-rHK/inspector_strings.xml
new file mode 100644
index 0000000..8b7e48f
--- /dev/null
+++ b/res/values-zh-rHK/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"資訊"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"無法載入檔案資訊"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"偵錯資料 (只限開發人員)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"原始元數據:<xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"媒體詳情"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"使用以下應用程式開啟這種檔案:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"這個檔案的提供者:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"未選取"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"不明"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"尺寸"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> 百萬像素"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"座標"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>,<xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"高度"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"相機"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"光圈"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"快門速度"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"時間長度"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"拍攝時間"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"焦距"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> 毫米"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO 等效感光度"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"歌手"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"作曲者"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"專輯"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"位置"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"串流類型"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"原始大小 (字節)"</string>
+</resources>
diff --git a/res/values-zh-rHK/mimes.xml b/res/values-zh-rHK/mimes.xml
new file mode 100644
index 0000000..d250e18
--- /dev/null
+++ b/res/values-zh-rHK/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> 檔案"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"檔案"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"圖片"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> 圖片"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"音訊"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> 音訊"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"影片"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> 影片"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> 封存檔案"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android 應用程式"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"純文字"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML 文件"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF 文件"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word 文件"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint 簡報"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel 試算表"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google 文件"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google 試算表"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google 簡報"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google 繪圖"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google 表格"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google 表格"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google 地圖"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google 網站"</string>
+    <string name="directory_type" msgid="2702987727566226354">"資料夾"</string>
+</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 399f1d0..67d3e6a 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"壓縮"</string>
     <string name="menu_extract" msgid="8171946945982532262">"壓縮至…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"重新命名"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"屬性"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"顯示資訊"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"在「<xliff:g id="SOURCE">%1$s</xliff:g>」中查看"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"新視窗"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"剪下"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"移動"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"關閉"</string>
     <string name="button_retry" msgid="4011461781916631389">"再試一次"</string>
+    <string name="button_clear" msgid="5412304437764369441">"清除"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"在供應商的應用程式中顯示"</string>
     <string name="not_sorted" msgid="7813496644889115530">"尚未排序"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"名稱"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"摘要"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"類型"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"大小"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"上次修改時間"</string>
-    <string name="directory_children" msgid="8115290268549503262">"兒童人數"</string>
+    <string name="directory_items" msgid="6645621978998614003">"項目數量"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"遞增"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"遞減"</string>
     <string name="drawer_open" msgid="8071673398187261741">"顯示根目錄"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"無法開啟檔案"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"無法開啟封存中的檔案"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"無法刪除部分文件"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"無法載入屬性"</string>
     <string name="share_via" msgid="8725082736005677161">"透過以下應用程式分享:"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"正在複製檔案"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"正在壓縮檔案"</string>
diff --git a/res/values-zh-rTW/inspector_strings.xml b/res/values-zh-rTW/inspector_strings.xml
new file mode 100644
index 0000000..8c17e39
--- /dev/null
+++ b/res/values-zh-rTW/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"資訊"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"無法載入檔案資訊"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"偵錯資訊 (開發人員專用)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"原始中繼資料:<xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"媒體詳細資料"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"使用以下應用程式開啟這種檔案:"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"這個檔案的提供者:"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"未選取"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"不明"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"尺寸"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g> 百萬像素"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"座標"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>,<xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"高度"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"相機"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"光圈"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"快門速度"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"時間長度"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"拍攝時間"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"焦距"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g> 毫米"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"等效 ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"演出者"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"作曲者"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"專輯"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"位置"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"串流類型"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"原始大小 (位元組)"</string>
+</resources>
diff --git a/res/values-zh-rTW/mimes.xml b/res/values-zh-rTW/mimes.xml
new file mode 100644
index 0000000..cc5cc29
--- /dev/null
+++ b/res/values-zh-rTW/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> 檔案"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"檔案"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"圖片"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> 圖片"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"音訊"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> 音訊"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"影片"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> 影片"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> 封存檔"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android 應用程式"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"純文字"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML 文件"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF 文件"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word 文件"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint 簡報"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel 試算表"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google 文件"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google 試算表"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google 簡報"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google 繪圖"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google 表格"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google 表單"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google 地圖"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google 網站"</string>
+    <string name="directory_type" msgid="2702987727566226354">"資料夾"</string>
+</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index bc55dd6..284a5ff 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"壓縮"</string>
     <string name="menu_extract" msgid="8171946945982532262">"解壓縮到…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"重新命名"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"屬性"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"取得資訊"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"在「<xliff:g id="SOURCE">%1$s</xliff:g>」中查看"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"新視窗"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"剪下"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"移動"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"關閉"</string>
     <string name="button_retry" msgid="4011461781916631389">"再試一次"</string>
+    <string name="button_clear" msgid="5412304437764369441">"清除"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"在供應商的應用程式中顯示"</string>
     <string name="not_sorted" msgid="7813496644889115530">"未排序"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"名稱"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"摘要"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"類型"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"大小"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"上次修改時間"</string>
-    <string name="directory_children" msgid="8115290268549503262">"兒童人數"</string>
+    <string name="directory_items" msgid="6645621978998614003">"項目數量"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"遞增"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"遞減"</string>
     <string name="drawer_open" msgid="8071673398187261741">"顯示根目錄"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"無法開啟檔案"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"無法開啟已封存的檔案"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"無法刪除部分文件"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"無法載入屬性"</string>
     <string name="share_via" msgid="8725082736005677161">"分享方式:"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"複製檔案"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"正在壓縮檔案"</string>
diff --git a/res/values-zu/inspector_strings.xml b/res/values-zu/inspector_strings.xml
new file mode 100644
index 0000000..3cb972d
--- /dev/null
+++ b/res/values-zu/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"Ulwazi"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"Ulwazi lwefayela alikwazanga ukulayishwa"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Ulwazi lokususa iphutha (i-dev kuphela)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Imethadatha e-Raw: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"Imininingwane yemidiya"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Lolu hlobo lwefayela luvuleka nge-"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"Leli fayela linikezelwe yi-"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"Abangakhethiwe"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"Akwaziwa"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"Ubukhulu"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"Ukuxhumanisa"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"Ukuphakama"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"Ikhamera"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"Imbobo"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"Isivinini seshutha"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"Ubude besikhathi"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"Ithathwe ngezi"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"Ubude befokhali"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>mm"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"Okulinganayo kwe-ISO"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"I-ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"Umculi"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"Umqambi"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"I-albhamu"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"Indawo"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"Izinhlobo zokusakaza"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"Usayizi we-Raw (amabhayithi)"</string>
+</resources>
diff --git a/res/values-zu/mimes.xml b/res/values-zu/mimes.xml
new file mode 100644
index 0000000..b8bf096
--- /dev/null
+++ b/res/values-zu/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ifayela"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"Ifayela"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"Isithombe"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> isithombe"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"Umsindo"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> umsindo"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"Ividiyo"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ividiyo"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> ingobo yomlando"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Uhlelo lokusebenza lwe-Android"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"Umbhalo ongenalutho"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"Idokhumenti ye-HTML"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"Idokhumenti ye-PDF"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Idokhumenti ye-Word"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"Iphrezentheshini ye-PowerPoint"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Isipredishithi se-Excel"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Idokhumenti ye-Google"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Isipredishithi se-Google"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Iphrezentheshini ye-Google"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google imidwebo"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Ithebula ye-Google"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Ifomu le-Google"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Imephu ye-Google"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Isayithi le-Google"</string>
+    <string name="directory_type" msgid="2702987727566226354">"Ifolda"</string>
+</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 1d80f8b..3109dc0 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -41,7 +41,7 @@
     <string name="menu_compress" msgid="37539111904724188">"Cindezela"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Khiphela ku…"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Qamba kabusha"</string>
-    <string name="menu_inspector" msgid="8633147986551632467">"Izici"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Thola ulwazi"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"Buka ku-<xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Iwindi elisha"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Sika"</string>
@@ -57,13 +57,15 @@
     <string name="button_move" msgid="8596460499325291272">"Hambisa"</string>
     <string name="button_dismiss" msgid="7235249361023803349">"Cashisa"</string>
     <string name="button_retry" msgid="4011461781916631389">"Zama Futhi"</string>
+    <string name="button_clear" msgid="5412304437764369441">"Sula"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"Bonisa kumhlinzeki"</string>
     <string name="not_sorted" msgid="7813496644889115530">"Akuhlungiwe"</string>
     <string name="sort_dimension_name" msgid="6325591541414177579">"Igama"</string>
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Isifinyezo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Uhlobo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Usayizi"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Kulungisiwe"</string>
-    <string name="directory_children" msgid="8115290268549503262">"Inombolo yezingane"</string>
+    <string name="directory_items" msgid="6645621978998614003">"Inombolo yezinto"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Iyanyuka"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Iyehla"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Bonisa izimpande"</string>
@@ -82,7 +84,6 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Ayikwazanga ukuvula ifayela"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Ayikwazi ukuvula amafayela kuzingobo zomlando"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Ayikwazi ukususa amanye amadokhumenti"</string>
-    <string name="file_inspector_load_error" msgid="1226344446677541109">"Izakhiwo azikwazanga ukulayishwa"</string>
     <string name="share_via" msgid="8725082736005677161">"Abelana nge-"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Ikopisha amafayela"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Icindezela amafayela"</string>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index e7801b9..818e012 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -76,5 +76,8 @@
     <color name="scroll_track">#fff0f0f0</color>
 
     <color name="inspector_value">#ff939393</color>
+    <color name="inspector_link">#6633b5e5</color>
     <color name="inspector_section_title">#ff939393</color>
+    <color name="inspector_section_divider">#E0E0E0</color>
+    <color name="inspector_title_background">#40000000</color>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 978cc5f..763cfc0 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -48,7 +48,7 @@
     <bool name="feature_remote_actions">true</bool>
     <bool name="feature_system_keyboard_navigation">true</bool>
     <bool name="feature_virtual_files_sharing">true</bool>
-    <bool name="feature_inspector">false</bool>
+    <bool name="feature_inspector">true</bool>
     <bool name="feature_debug_mode">false</bool>
 
     <!-- Indicates if internal storage is shown as default or not. -->
diff --git a/res/values/inspector_strings.xml b/res/values/inspector_strings.xml
new file mode 100644
index 0000000..a70a274
--- /dev/null
+++ b/res/values/inspector_strings.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- File properties dialog title. This dialog show fine grained details about a file. -->
+    <string name="inspector_title">Info</string>
+
+    <!-- File properties dialog error shown when information about a file could not be loaded-->
+    <string name="inspector_load_error">File info could not be loaded</string>
+
+    <!-- Title of inspector's debug information section. The contents of this section
+         features detailed "internal" information useful primarily to developers.
+         This section is only visible to developers or people running debug builds. [CHAR LIMIT=48] -->
+    <string name="inspector_debug_section">Debug info (dev only)</string>
+
+    <!-- Title of inspector's debug info metadata sub-section. [CHAR LIMIT=48] -->
+    <string name="inspector_debug_metadata_section">Raw metadata: <xliff:g id="metadataType" example="EXIF">%1$s</xliff:g></string>
+
+    <!-- Title of inspector's media details info section. Shows information related to camera, dimensions, and authors. -->
+    <string name="inspector_metadata_section">Media details</string>
+
+    <!-- File properties dialog section title. In this section we show information about the default handler application for this type of file.-->
+    <string name="handler_app_file_opens_with">This kind of file opens with</string>
+    <!-- File properties dialog section title. In this section we show information about the applicaiton that provides the file.
+         Examples of such applicaitons are: Box, Microsoft OneDrive, and Google Drive, etc)-->
+    <string name="handler_app_belongs_to">This file is supplied by</string>
+
+    <!-- File properties dialog user message if a default app has not been selected-->
+    <string name="handler_app_not_selected">Not selected</string>
+    <!-- File properties dialog user message if the default app is unknown-->
+    <string name="handler_app_unknown">Unknown</string>
+
+    <!-- The height and width of a photo. -->
+    <string name="metadata_dimensions">Dimensions</string>
+    <!-- The width and height of a photo, followed by a the "megapixel rating".
+         Cameras are frequently rated by "megapixels". In U.S. English the "megapixels" rating
+         of a camera is denoted by a number followed by "MP". E.g. 12.2MP or 8MP. -->
+    <string name="metadata_dimensions_format"><xliff:g id="width" example="1280">%1$d</xliff:g> x <xliff:g id="height" example="1024">%2$d</xliff:g> - <xliff:g id="megapixels" example="12.2">%3$,.1f</xliff:g>MP</string>
+    <!-- The location of where a photo was taken. -->
+    <string name="metadata_coordinates">Coordinates</string>
+    <!-- The location a photo was taken in the form of latitude/longitude coordinates. -->
+    <string name="metadata_coordinates_format"><xliff:g id="latitude" example="33.996">%1$,.3f</xliff:g>, <xliff:g id="longitude" example="-118.476">%2$,.3f</xliff:g></string>
+    <!-- The elevation a photo was taken. -->
+    <string name="metadata_altitude">Altitude</string>
+    <!-- The camera make and model. -->
+    <string name="metadata_camera">Camera</string>
+    <!-- The camera make and model. Where make is usually the company, and model is the individual camera model name. -->
+    <string name="metadata_camera_format"><xliff:g id="make" example="Sony">%1$s</xliff:g> <xliff:g id="model" example="Snazzy Snapper">%2$s</xliff:g></string>
+    <!-- The value of a photos aperture. Note that this is probably camera EXIF data.-->
+    <string name="metadata_aperture">Aperture</string>
+    <!-- The value of a photos shutter speed. Note that this is probably camera EXIF data.-->
+    <string name="metadata_shutter_speed">Shutter speed</string>
+    <!-- How long a video/audio file is.-->
+    <string name="metadata_duration">Duration</string>
+    <!-- When a photo was taken. Note that this is probably camera EXIF data.-->
+    <string name="metadata_date_time">Taken on</string>
+    <!-- Message presenting EXIF aperture information in the tradition "f/2.0" format familiar to users. This format is basically an industry standard that shouldn't be translated, so it is marked as not translatable. -->
+    <string name="metadata_aperture_format" translatable="false">f/<xliff:g id="aperture" example="2.0">%1$,.1f</xliff:g></string>
+    <!--The tag for the focal length of a camera. Note that this is probably camera EXIF data-->
+    <string name="metadata_focal_length">Focal length</string>
+    <!--The format for displaying the focal length of a camera. Note that this is probably camera EXIF data-->
+    <string name="metadata_focal_format"><xliff:g id="length" example="24">%1$.2f </xliff:g>mm</string>
+    <!--The tag for the ISO Speed of a camera. Note that this is probably camera EXIF data-->
+    <string name="metadata_iso_speed_ratings">ISO equivalent</string>
+    <!--The format for displaying ISO speed. Note that this is probably camera EXIF data-->
+    <string name="metadata_iso_format">ISO <xliff:g id="iso_speed" example="35">%1$d</xliff:g></string>
+    <!--The title of the audio file, Note this is probably MP3 ID3 tags.-->
+    <string name="metadata_artist">Artist</string>
+    <!--The composer for the audio file, Note this is probably MP3 ID3 tags-->
+    <string name="metadata_composer">Composer</string>
+    <!--The title of the album (i.e. collection of recordings) the song belongs to. Note this is probably MP3 ID3 tags-->
+    <string name="metadata_album">Album</string>
+    <!-- The address nearest to where a photo was taken -->
+    <string name="metadata_address">Location</string>
+
+    <!-- String label for developer/debug file details, specifying which stream types are available. -->
+    <string name="debug_stream_types">Stream types</string>
+    <!-- String label for developer/debug file details, specifying the size of the file in bytes. -->
+    <string name="debug_raw_size">Raw size (bytes)</string>
+    <!-- String label for developer/debug file details, specifying a file's uri/content address. -->
+    <string name="debug_content_uri" translatable="false">Uri</string>
+    <!-- String label for developer/debug file details, specifying document id. -->
+    <string name="debug_document_id" translatable="false">Document id</string>
+    <!-- String label for developer/debug file details, specifying mimetype. -->
+    <string name="debug_raw_mimetype" translatable="false">Raw mimetype</string>
+    <!-- String label for developer/debug file details, specifying that a file is an archive. -->
+    <string name="debug_is_archive" translatable="false">Is archive</string>
+    <!-- String label for developer/debug file details, specifying that a file is a container (like a folder or an archive). -->
+    <string name="debug_is_container" translatable="false">Is container</string>
+    <!-- String label for developer/debug file details, specifying that a file is partial (being downloaded). -->
+    <string name="debug_is_partial" translatable="false">Is partial</string>
+    <!-- String label for developer/debug file details, specifying that a file is virtual (has no byte representation). -->
+    <string name="debug_is_virtual" translatable="false">Is virtual</string>
+    <!-- String label for developer/debug file details, specifying that a file supports creating files within it. -->
+    <string name="debug_supports_create" translatable="false">Supports create</string>
+    <!-- String label for developer/debug file details, specifying that a file is deletable. -->
+    <string name="debug_supports_delete" translatable="false">Supports delete</string>
+    <!-- String label for developer/debug file details, specifying that a file has associated metadata. -->
+    <string name="debug_supports_metadata" translatable="false">Supports metadata</string>
+    <!-- String label for developer/debug file details, specifying that a file can be removed. -->
+    <string name="debug_supports_remove" translatable="false">Supports remove</string>
+    <!-- String label for developer/debug file details, specifying that a file can be renamed. -->
+    <string name="debug_supports_rename" translatable="false">Supports rename</string>
+    <!-- String label for developer/debug file details, specifying that a file supports the "settings" feature. -->
+    <string name="debug_supports_settings" translatable="false">Supports settings</string>
+    <!-- String label for developer/debug file details, specifying that a file has a viewable thumbnail. -->
+    <string name="debug_supports_thumbnail" translatable="false">Supports thumbnail</string>
+    <!-- String label for developer/debug file details, specifying that a file supports the "weblink" feature. -->
+    <string name="debug_supports_weblink" translatable="false">Supports weblink</string>
+    <!-- String label for developer/debug file details, specifying that a file is writable. -->
+    <string name="debug_supports_write" translatable="false">Supports write</string>
+
+</resources>
diff --git a/res/values/mimes.xml b/res/values/mimes.xml
index 6823ed9..0559741 100644
--- a/res/values/mimes.xml
+++ b/res/values/mimes.xml
@@ -16,54 +16,54 @@
   -->
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Generic file type with an extention shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Generic file type with an extention shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="generic_extention_file_type"><xliff:g id="extension" example="APE">%1$s</xliff:g> file</string>
-    <!-- Generic file type without an extention shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Generic file type without an extention shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="generic_file_type">File</string>
-    <!-- Generic image file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Generic image file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="image_file_type">Image</string>
-    <!-- Image file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Image file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="image_extension_file_type"><xliff:g id="fileType" example="JPG">%1$s</xliff:g> image</string>
-    <!-- Generic audio file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Generic audio file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="audio_file_type">Audio</string>
-    <!-- Audio file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Audio file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="audio_extension_file_type"><xliff:g id="fileType" example="MP3">%1$s</xliff:g> audio</string>
-    <!-- Generic video file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Generic video file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="video_file_type">Video</string>
-    <!-- Video file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Video file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="video_extension_file_type"><xliff:g id="fileType" example="AVI">%1$s</xliff:g> video</string>
-    <!-- Archive file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Archive file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="archive_file_type"><xliff:g id="fileType" example="Zip">%1$s</xliff:g> archive</string>
-    <!-- Android application file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Android application file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="apk_file_type">Android application</string>
-    <!-- Plain text file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Plain text file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="txt_file_type">Plain text</string>
-    <!-- HTML file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- HTML file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="html_file_type">HTML document</string>
-    <!-- PDF file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- PDF file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="pdf_file_type">PDF document</string>
-    <!-- Word document file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Word document file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="word_file_type">Word document</string>
-    <!-- PowerPoint presentation file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- PowerPoint presentation file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="ppt_file_type">PowerPoint presentation</string>
-    <!-- Excel spreadsheet file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Excel spreadsheet file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="excel_file_type">Excel spreadsheet</string>
-    <!-- Google document file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google document file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gdoc_file_type">Google document</string>
-    <!-- Google spreadsheet file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google spreadsheet file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gsheet_file_type">Google spreadsheet</string>
-    <!-- Google presentation file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google presentation file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gslides_file_type">Google presentation</string>
-    <!-- Google drawing file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google drawing file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gdraw_file_type">Google drawing</string>
-    <!-- Google table file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google table file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gtable_file_type">Google table</string>
-    <!-- Google form file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google form file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gform_file_type">Google form</string>
-    <!-- Google map file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google map file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gmap_file_type">Google map</string>
-    <!-- Google site file type shown in type column in list view. [CHAR LIMIT=24] -->
+    <!-- Google site file type shown in type column in list view. [CHAR LIMIT=30] -->
     <string name="gsite_file_type">Google site</string>
     <!-- Generic directory type shown when viewing a folder in the properties view -->
     <string name="directory_type">Folder</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a5ecfac..2855ef5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,7 +18,7 @@
     <!-- Title of the Files application [CHAR LIMIT=32] -->
     <string name="files_label">Files</string>
 
-    <!-- Title of the Downloads application, which sometimes Files is known as [CHAR LIMIT=32] -->
+    <!-- Title of the Downloads application, which sometimes Files is known as [CHAR LIMIT=16] -->
     <string name="downloads_label">Downloads</string>
 
     <!-- Title of the documents application [CHAR LIMIT=32] -->
@@ -67,8 +67,8 @@
     <string name="menu_extract">Extract to\u2026</string>
     <!-- Menu item that renames the selected document [CHAR LIMIT=28] -->
     <string name="menu_rename">Rename</string>
-    <!--Menu item that displays properties about the selected document [CHAR LIMIT=28] -->
-    <string name="menu_inspector">Get info</string>
+    <!-- Menu item that displays properties about the selected document [CHAR LIMIT=28] -->
+    <string name="menu_inspect">Get info</string>
     <!-- Menu item that renames the selected document [CHAR LIMIT=28] -->
     <string name="menu_view_in_owner">View in <xliff:g id="source" example="Google Drive">%1$s</xliff:g></string>
 
@@ -103,6 +103,11 @@
     <!-- Button label that hides the error bar [CHAR LIMIT=24] -->
     <string name="button_dismiss">Dismiss</string>
     <string name="button_retry">Try Again</string>
+    <!-- Button label that removes the default application to open a file. -->
+    <string name="button_clear">Clear</string>
+    <!-- Button label that show in the providers service. Many providers have their own app such
+     as google drive. Pressing this button would open in the file in the providers app. -->
+    <string name="button_show_provider">Show in provider</string>
 
     <!-- A string used to show user that currently documents are not sorted in any given order. [CHAR_LIMIT=30] -->
     <string name="not_sorted">Not sorted</string>
@@ -120,26 +125,6 @@
     <!--Table header for number of items in a folder.-->
     <string name="directory_items">Number of items</string>
 
-    <!--File properties dialog section title. In this section we show information about the default handler application for this type of file.-->
-    <string name="handler_app_file_opens_with">This kind of file opens with</string>
-    <!--File properties dialog section title. In this section we show information about a files provider. (e.g. system, drive, dropbox, etc)-->
-    <string name="handler_app_belongs_to">This file belongs to</string>
-
-    <!--File properties dialog button description for clearing the default app. the name of the app
-     will be inserted programmatically inbetween these two strings-->
-    <string name="handler_app_button_info_1">Other apps can open this file type. Clear</string>
-    <string name="handler_app_button_info_2">as the default.</string>
-
-    <!--File properties dialog button label to clear the default app-->
-    <string name="handler_app_clear">Clear</string>
-    <!--File properties dialog button label to show a document in a provider-->
-    <string name="handler_app_show_in">Show in provider</string>
-
-    <!--File properties dialog user message if a default app has not been selected-->
-    <string name="handler_app_not_selected">Not selected</string>
-    <!--File properties dialog user message if the default app is unknown-->
-    <string name="handler_app_unknown">Unknown</string>
-
     <!-- content description to describe ascending sorting used with upward arrow in table header. -->
     <string name="sort_direction_ascending">Ascending</string>
     <!-- content description to describe descending sorting used with downward arrow in table header. -->
@@ -183,9 +168,6 @@
     <!-- Toast shown when some of the selected documents failed to be deleted [CHAR LIMIT=48] -->
     <string name="toast_failed_delete">Unable to delete some documents</string>
 
-    <!-- Toast shown when a files document info fails to load-->
-    <string name="file_inspector_load_error">Properties could not be loaded</string>
-
     <!-- Title of dialog when prompting user to select an app to share documents with [CHAR LIMIT=32] -->
     <string name="share_via">Share via</string>
 
@@ -386,8 +368,4 @@
 
     <!-- Button for continuing a file operation in background, eg. copying, moving or extracting. [CHAR LIMIT=48] -->
     <string name="continue_in_background">Continue in background</string>
-
-    <!-- Title of inspector's debug info section. [CHAR LIMIT=48] -->
-    <string name="inspector_debug_section">Debug info (dev only)</string>
-
 </resources>
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index 0faab6e..44c6342 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -51,15 +51,16 @@
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.AnimationView;
 import com.android.documentsui.dirlist.AnimationView.AnimationType;
-import com.android.documentsui.dirlist.DocumentDetails;
 import com.android.documentsui.dirlist.FocusHandler;
 import com.android.documentsui.files.LauncherActivity;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.GetRootDocumentTask;
 import com.android.documentsui.roots.LoadRootTask;
 import com.android.documentsui.roots.ProvidersAccess;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.ContentLock;
+import com.android.documentsui.selection.MutableSelection;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.sidebar.EjectRootTask;
 import com.android.documentsui.ui.Snackbars;
 
@@ -92,7 +93,7 @@
     protected final ProvidersAccess mProviders;
     protected final DocumentsAccess mDocs;
     protected final FocusHandler mFocusHandler;
-    protected final SelectionManager mSelectionMgr;
+    protected final SelectionHelper mSelectionMgr;
     protected final SearchViewManager mSearchMgr;
     protected final Lookup<String, Executor> mExecutors;
     protected final Injector<?> mInjector;
@@ -101,7 +102,7 @@
 
     private Runnable mDisplayStateChangedListener;
 
-    private DirectoryReloadLock mDirectoryReloadLock;
+    private ContentLock mContentLock;
 
     @Override
     public void registerDisplayStateChangedListener(Runnable l) {
@@ -226,10 +227,11 @@
     }
 
     @Override
-    public boolean openDocument(DocumentDetails doc, @ViewType int type, @ViewType int fallback) {
+    public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
         throw new UnsupportedOperationException("Can't open document.");
     }
 
+    @Override
     public void showInspector(DocumentInfo doc) {
         throw new UnsupportedOperationException("Can't open properties.");
     }
@@ -356,6 +358,13 @@
                         + mState.stack.getRoot());
             }
 
+            final DocumentInfo top = stack.peek();
+            if (top.isArchive()) {
+                // Swap the zip file in original provider and the one provided by ArchiveProvider.
+                stack.pop();
+                stack.push(mDocs.getArchiveDocument(top.derivedUri));
+            }
+
             mState.stack.reset();
             // Update navigator to give horizontal breadcrumb a chance to update documents. It
             // doesn't update its content if the size of document stack doesn't change.
@@ -524,13 +533,15 @@
         loadRoot(Shared.getDefaultRootUri(mActivity));
     }
 
-    protected Selection getStableSelection() {
-        return mSelectionMgr.getSelection(new Selection());
+    protected MutableSelection getStableSelection() {
+        MutableSelection selection = new MutableSelection();
+        mSelectionMgr.copySelection(selection);
+        return selection;
     }
 
     @Override
-    public ActionHandler reset(DirectoryReloadLock reloadLock) {
-        mDirectoryReloadLock = reloadLock;
+    public ActionHandler reset(ContentLock reloadLock) {
+        mContentLock = reloadLock;
         mActivity.getLoaderManager().destroyLoader(LOADER_ID);
         return this;
     }
@@ -578,7 +589,7 @@
                         contentsUri,
                         mState.sortModel,
                         mInjector.fileTypeLookup,
-                        mDirectoryReloadLock,
+                        mContentLock,
                         mSearchMgr.isSearching());
             }
         }
diff --git a/src/com/android/documentsui/ActionHandler.java b/src/com/android/documentsui/ActionHandler.java
index 6b0e077..ba20f34 100644
--- a/src/com/android/documentsui/ActionHandler.java
+++ b/src/com/android/documentsui/ActionHandler.java
@@ -19,7 +19,6 @@
 import android.annotation.IntDef;
 import android.app.PendingIntent;
 import android.content.ContentProvider;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
@@ -29,8 +28,8 @@
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.dirlist.DocumentDetails;
-import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.ContentLock;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -111,7 +110,7 @@
      * If container, then opens the container, otherwise views using the specified type of view.
      * If the primary view type is unavailable, then fallback to the alternative type of view.
      */
-    boolean openDocument(DocumentDetails doc, @ViewType int type, @ViewType int fallback);
+    boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback);
 
     /**
      * This is called when user hovers over a doc for enough time during a drag n' drop, to open a
@@ -158,5 +157,5 @@
      * Allow action handler to be initialized in a new scope.
      * @return this
      */
-    <T extends ActionHandler> T reset(DirectoryReloadLock reloadLock);
+    <T extends ActionHandler> T reset(ContentLock contentLock);
 }
diff --git a/src/com/android/documentsui/ActionModeController.java b/src/com/android/documentsui/ActionModeController.java
index 7c5ad63..aabd672 100644
--- a/src/com/android/documentsui/ActionModeController.java
+++ b/src/com/android/documentsui/ActionModeController.java
@@ -24,7 +24,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.ActionMode;
-import android.view.HapticFeedbackConstants;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -35,22 +34,20 @@
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.Menus;
 import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
 import com.android.documentsui.ui.MessageBuilder;
 
-import java.util.function.Consumer;
-import java.util.function.IntConsumer;
-
 /**
  * A controller that listens to selection changes and manages life cycles of action modes.
  */
-public class ActionModeController
-        implements SelectionManager.Callback, ActionMode.Callback, ActionModeAddons {
+public class ActionModeController extends SelectionObserver
+        implements ActionMode.Callback, ActionModeAddons {
 
     private static final String TAG = "ActionModeController";
 
     private final Activity mActivity;
-    private final SelectionManager mSelectionMgr;
+    private final SelectionHelper mSelectionMgr;
     private final MenuManager mMenuManager;
     private final MessageBuilder mMessages;
 
@@ -62,7 +59,7 @@
 
     public ActionModeController(
             Activity activity,
-            SelectionManager selectionMgr,
+            SelectionHelper selectionMgr,
             MenuManager menuManager,
             MessageBuilder messages) {
 
@@ -74,7 +71,7 @@
 
     @Override
     public void onSelectionChanged() {
-        mSelectionMgr.getSelection(mSelected);
+        mSelectionMgr.copySelection(mSelected);
         if (mSelected.size() > 0) {
             if (mActionMode == null) {
                 if (DEBUG) Log.d(TAG, "Starting action mode.");
@@ -99,27 +96,7 @@
 
     @Override
     public void onSelectionRestored() {
-        mSelectionMgr.getSelection(mSelected);
-        if (mSelected.size() > 0) {
-            if (mActionMode == null) {
-                if (DEBUG) Log.d(TAG, "Starting action mode.");
-                mActionMode = mActivity.startActionMode(this);
-            }
-            updateActionMenu();
-        } else {
-            if (mActionMode != null) {
-                if (DEBUG) Log.d(TAG, "Finishing action mode.");
-                mActionMode.finish();
-            }
-        }
-
-        if (mActionMode != null) {
-            assert(!mSelected.isEmpty());
-            final String title = mMessages.getQuantityString(
-                    R.plurals.elements_selected, mSelected.size());
-            mActionMode.setTitle(title);
-            mActivity.getWindow().setTitle(title);
-        }
+        onSelectionChanged();
     }
 
     // Called when the user exits the action mode
@@ -135,9 +112,7 @@
         mActionMode = null;
         mMenu = null;
 
-        // clear selection
         mSelectionMgr.clearSelection();
-        mSelected.clear();
 
         // Reset window title back to activity title, i.e. Root name
         mActivity.getWindow().setTitle(mActivity.getTitle());
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 290dd63..19457fc 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -425,12 +425,10 @@
         }
 
         mNavigator.update();
+
         // Causes talkback to announce the activity's new title
-        if (mState.stack.isRecents()) {
-            setTitle(mProviders.getRecentsRoot().title);
-        } else {
-            setTitle(mState.stack.getTitle());
-        }
+        setTitle(mState.stack.getTitle());
+
         invalidateOptionsMenu();
     }
 
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 30a447c..64d97f0 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -43,6 +43,7 @@
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.roots.RootCursorWrapper;
+import com.android.documentsui.selection.ContentLock;
 import com.android.documentsui.sorting.SortModel;
 
 import libcore.io.IoUtils;
@@ -74,7 +75,7 @@
             Uri uri,
             SortModel model,
             Lookup<String, String> fileTypeLookup,
-            DirectoryReloadLock lock,
+            ContentLock lock,
             boolean inSearchMode) {
 
         super(context, ProviderExecutor.forAuthority(root.authority));
@@ -226,10 +227,10 @@
     }
 
     private static final class LockingContentObserver extends ContentObserver {
-        private final DirectoryReloadLock mLock;
+        private final ContentLock mLock;
         private final Runnable mContentChangedCallback;
 
-        public LockingContentObserver(DirectoryReloadLock lock, Runnable contentChangedCallback) {
+        public LockingContentObserver(ContentLock lock, Runnable contentChangedCallback) {
             super(new Handler(Looper.getMainLooper()));
             mLock = lock;
             mContentChangedCallback = contentChangedCallback;
@@ -242,7 +243,7 @@
 
         @Override
         public void onChange(boolean selfChange) {
-            mLock.tryUpdate(mContentChangedCallback);
+            mLock.runWhenUnlocked(mContentChangedCallback);
         }
     }
 }
diff --git a/src/com/android/documentsui/DirectoryReloadLock.java b/src/com/android/documentsui/DirectoryReloadLock.java
deleted file mode 100644
index 4299914..0000000
--- a/src/com/android/documentsui/DirectoryReloadLock.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui;
-
-import static com.android.documentsui.base.Shared.VERBOSE;
-
-import android.annotation.MainThread;
-import android.annotation.Nullable;
-import android.util.Log;
-
-import com.android.documentsui.base.Shared;
-import com.android.documentsui.selection.BandController;
-
-/**
- * A lock used by {@link DirectoryLoader} and {@link BandController} to ensure refresh is blocked
- * while Band Selection is active.
- */
-public final class DirectoryReloadLock {
-    private static final String TAG = "DirectoryReloadLock";
-
-    private int mPauseCount = 0;
-    private @Nullable Runnable mCallback;
-
-    /**
-     * Increment the block count by 1
-     */
-    @MainThread
-    public void block() {
-        Shared.checkMainLoop();
-        mPauseCount++;
-        if (VERBOSE) Log.v(TAG, "Block count increments to " + mPauseCount + ".");
-    }
-
-    /**
-     * Decrement the block count by 1; If no other object is trying to block and there exists some
-     * callback, that callback will be run
-     */
-    @MainThread
-    public void unblock() {
-        Shared.checkMainLoop();
-        assert(mPauseCount > 0);
-        mPauseCount--;
-        if (VERBOSE) Log.v(TAG, "Block count decrements to " + mPauseCount + ".");
-        if (mPauseCount == 0 && mCallback != null) {
-            mCallback.run();
-            mCallback = null;
-        }
-    }
-
-    /**
-     * Attempts to run the given Runnable if not-blocked, or else the Runnable is set to be ran next
-     * (replacing any previous set Runnables).
-     */
-    public void tryUpdate(Runnable update) {
-        if (mPauseCount == 0) {
-            update.run();
-        } else {
-            mCallback = update;
-        }
-    }
-}
diff --git a/src/com/android/documentsui/DocsSelectionHelper.java b/src/com/android/documentsui/DocsSelectionHelper.java
new file mode 100644
index 0000000..2c6b63b
--- /dev/null
+++ b/src/com/android/documentsui/DocsSelectionHelper.java
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui;
+
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.widget.RecyclerView;
+
+import com.android.documentsui.selection.DefaultSelectionHelper;
+import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode;
+import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.SelectionHelper;
+
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * DocumentsUI SelectManager implementation that creates delegate instances
+ * each time reset is called.
+ */
+public final class DocsSelectionHelper extends SelectionHelper {
+
+    private final DelegateFactory mFactory;
+    private final @SelectionMode int mSelectionMode;
+
+    private @Nullable SelectionHelper mDelegate;
+
+    @VisibleForTesting
+    DocsSelectionHelper(DelegateFactory factory, @SelectionMode int mode) {
+        mFactory = factory;
+        mSelectionMode = mode;
+    }
+
+    public SelectionHelper reset(
+            RecyclerView.Adapter<?> adapter,
+            StableIdProvider stableIds,
+            SelectionPredicate canSetState) {
+
+        if (mDelegate != null) {
+            mDelegate.clearSelection();
+        }
+
+        mDelegate = mFactory.create(mSelectionMode, adapter, stableIds, canSetState);
+        return this;
+    }
+
+    @Override
+    public void addObserver(SelectionObserver listener) {
+        mDelegate.addObserver(listener);
+    }
+
+    @Override
+    public boolean hasSelection() {
+        return mDelegate.hasSelection();
+    }
+
+    @Override
+    public Selection getSelection() {
+        return mDelegate.getSelection();
+    }
+
+    @Override
+    public void copySelection(Selection dest) {
+        mDelegate.copySelection(dest);
+    }
+
+    @Override
+    public boolean isSelected(String id) {
+        return mDelegate.isSelected(id);
+    }
+
+    @VisibleForTesting
+    public void replaceSelection(Iterable<String> ids) {
+        mDelegate.clearSelection();
+        mDelegate.setItemsSelected(ids, true);
+    }
+
+    @Override
+    public void restoreSelection(Selection other) {
+        mDelegate.restoreSelection(other);
+    }
+
+    @Override
+    public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
+        return mDelegate.setItemsSelected(ids, selected);
+    }
+
+    @Override
+    public void clearSelection() {
+        mDelegate.clearSelection();
+    }
+
+    @Override
+    public boolean select(String modelId) {
+        return mDelegate.select(modelId);
+    }
+
+    @Override
+    public boolean deselect(String modelId) {
+        return mDelegate.deselect(modelId);
+    }
+
+    @Override
+    public void startRange(int pos) {
+        mDelegate.startRange(pos);
+    }
+
+    @Override
+    public void extendRange(int pos) {
+        mDelegate.extendRange(pos);
+    }
+
+    @Override
+    public void extendProvisionalRange(int pos) {
+        mDelegate.extendProvisionalRange(pos);
+    }
+
+    @Override
+    public void clearProvisionalSelection() {
+        mDelegate.clearProvisionalSelection();
+    }
+
+    @Override
+    public void setProvisionalSelection(Set<String> newSelection) {
+        mDelegate.setProvisionalSelection(newSelection);
+    }
+
+    @Override
+    public void mergeProvisionalSelection() {
+        mDelegate.mergeProvisionalSelection();
+    }
+
+    @Override
+    public void endRange() {
+        mDelegate.endRange();
+    }
+
+    @Override
+    public boolean isRangeActive() {
+        return mDelegate.isRangeActive();
+    }
+
+    @Override
+    public void anchorRange(int position) {
+        mDelegate.anchorRange(position);
+    }
+
+    public static DocsSelectionHelper createMultiSelect() {
+        return new DocsSelectionHelper(
+                DelegateFactory.INSTANCE,
+                DefaultSelectionHelper.MODE_MULTIPLE);
+    }
+
+    public static DocsSelectionHelper createSingleSelect() {
+        return new DocsSelectionHelper(
+                DelegateFactory.INSTANCE,
+                DefaultSelectionHelper.MODE_SINGLE);
+    }
+
+    /**
+     * Use of a factory to create selection manager instances allows testable instances to
+     * be inject from tests.
+     */
+    @VisibleForTesting
+    static class DelegateFactory {
+        static final DelegateFactory INSTANCE = new DelegateFactory();
+
+        SelectionHelper create(
+                @SelectionMode int mode,
+                RecyclerView.Adapter<?> adapter,
+                StableIdProvider stableIds,
+                SelectionPredicate canSetState) {
+
+            return new DefaultSelectionHelper(mode, adapter, stableIds, canSetState);
+        }
+    }
+}
diff --git a/src/com/android/documentsui/FocusManager.java b/src/com/android/documentsui/FocusManager.java
index 609d127..097516e 100644
--- a/src/com/android/documentsui/FocusManager.java
+++ b/src/com/android/documentsui/FocusManager.java
@@ -47,8 +47,8 @@
 import com.android.documentsui.dirlist.DocumentHolder;
 import com.android.documentsui.dirlist.DocumentsAdapter;
 import com.android.documentsui.dirlist.FocusHandler;
+import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.Model.Update;
-import com.android.documentsui.selection.SelectionManager;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -61,7 +61,7 @@
     private final ContentScope mScope = new ContentScope();
 
     private final Features mFeatures;
-    private final SelectionManager mSelectionMgr;
+    private final SelectionHelper mSelectionMgr;
     private final DrawerController mDrawer;
     private final Procedure mRootsFocuser;
     private final TitleSearchHelper mSearchHelper;
@@ -70,7 +70,7 @@
 
     public FocusManager(
             Features features,
-            SelectionManager selectionMgr,
+            SelectionHelper selectionMgr,
             DrawerController drawer,
             Procedure rootsFocuser,
             @ColorRes int color) {
@@ -153,6 +153,10 @@
         final int focusPos = (mScope.lastFocusPosition != RecyclerView.NO_POSITION)
                 ? mScope.lastFocusPosition
                 : mScope.layout.findFirstVisibleItemPosition();
+        if (focusPos == RecyclerView.NO_POSITION) {
+            return false;
+        }
+
         focusItem(focusPos);
         return true;
     }
@@ -167,7 +171,7 @@
             return;
         }
 
-        int pos = mScope.adapter.getModelIds().indexOf(mScope.pendingFocusId);
+        int pos = mScope.adapter.getStableIds().indexOf(mScope.pendingFocusId);
         if (pos != -1) {
             focusItem(pos);
         }
@@ -558,7 +562,7 @@
             int itemCount = mScope.adapter.getItemCount();
             List<String> index = new ArrayList<>(itemCount);
             for (int i = 0; i < itemCount; i++) {
-                String modelId = mScope.adapter.getModelId(i);
+                String modelId = mScope.adapter.getStableId(i);
                 Cursor cursor = mScope.model.getItem(modelId);
                 if (modelId != null && cursor != null) {
                     String title = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
diff --git a/src/com/android/documentsui/Injector.java b/src/com/android/documentsui/Injector.java
index 30d1d4b..7f9edd4 100644
--- a/src/com/android/documentsui/Injector.java
+++ b/src/com/android/documentsui/Injector.java
@@ -28,11 +28,12 @@
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.dirlist.DocsStableIdProvider;
 import com.android.documentsui.dirlist.DocumentsAdapter;
 import com.android.documentsui.prefs.ScopedPreferences;
 import com.android.documentsui.queries.SearchViewManager;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionManager.SelectionPredicate;
+import com.android.documentsui.selection.ContentLock;
+import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.ui.DialogController;
 import com.android.documentsui.ui.MessageBuilder;
 import com.android.internal.annotations.VisibleForTesting;
@@ -70,7 +71,7 @@
     public FocusManager focusManager;
 
     @ContentScoped
-    public SelectionManager selectionMgr;
+    public DocsSelectionHelper selectionMgr;
 
     private final Model mModel;
 
@@ -119,9 +120,9 @@
         return focusManager.reset(view, model);
     }
 
-    public SelectionManager getSelectionManager(
-            DocumentsAdapter adapter, SelectionPredicate canSetState) {
-        return selectionMgr.reset(adapter, canSetState);
+    public SelectionHelper getSelectionManager(
+            DocumentsAdapter adapter, SelectionHelper.SelectionPredicate canSetState) {
+        return selectionMgr.reset(adapter, new DocsStableIdProvider(adapter), canSetState);
     }
 
     public final ActionModeController getActionModeController(
@@ -131,20 +132,22 @@
 
     /**
      * Obtains action handler and resets it if necessary.
-     * @param reloadLock the lock held by {@link com.android.documentsui.selection.BandController}
-     *                   to prevent loader from updating result during band selection. May be
-     *                   {@code null} if called from
-     *                   {@link com.android.documentsui.sidebar.RootsFragment}.
+     *
+     * @param contentLock the lock held by
+     *            {@link com.android.documentsui.selection.BandSelectionHelper} and
+     *            {@link com.android.documentsui.selection.GestureSelectionHelper} to prevent
+     *            loader from updating result during band/gesture selection. May be {@code null} if
+     *            called from {@link com.android.documentsui.sidebar.RootsFragment}.
      * @return the action handler
      */
-    public T getActionHandler(@Nullable DirectoryReloadLock reloadLock) {
+    public T getActionHandler(@Nullable ContentLock contentLock) {
 
         // provide our friend, RootsFragment, early access to this special feature!
-        if (reloadLock == null) {
+        if (contentLock == null) {
             return actions;
         }
 
-        return actions.reset(reloadLock);
+        return actions.reset(contentLock);
     }
 
     /**
diff --git a/src/com/android/documentsui/LoadDocStackTask.java b/src/com/android/documentsui/LoadDocStackTask.java
index 1ce4630..af10693 100644
--- a/src/com/android/documentsui/LoadDocStackTask.java
+++ b/src/com/android/documentsui/LoadDocStackTask.java
@@ -60,7 +60,6 @@
 
     @Override
     public @Nullable DocumentStack run(Uri... uris) {
-        // assert(Features.OMC_RUNTIME);
         if (mDocs.isDocumentUri(uris[0])) {
             final Uri docUri;
             if (DocumentsContract.isTreeUri(uris[0])) {
diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java
index a8c9767..01e4619 100644
--- a/src/com/android/documentsui/MenuManager.java
+++ b/src/com/android/documentsui/MenuManager.java
@@ -62,8 +62,8 @@
         updateCopyTo(menu.findItem(R.id.action_menu_copy_to), selection);
         updateCompress(menu.findItem(R.id.action_menu_compress), selection);
         updateExtractTo(menu.findItem(R.id.action_menu_extract_to), selection);
+        updateInspect(menu.findItem(R.id.action_menu_inspect), selection);
         updateViewInOwner(menu.findItem(R.id.action_menu_view_in_owner), selection);
-        updateInspector(menu.findItem(R.id.action_menu_inspector), selection);
 
         Menus.disableHiddenItems(menu);
     }
@@ -78,7 +78,7 @@
                 menu.findItem(R.id.option_menu_list));
         updateAdvanced(menu.findItem(R.id.option_menu_advanced));
         updateDebug(menu.findItem(R.id.option_menu_debug));
-
+        updateInspect(menu.findItem(R.id.option_menu_inspect));
         Menus.disableHiddenItems(menu);
     }
 
@@ -115,7 +115,7 @@
      */
     @VisibleForTesting
     public void updateContextMenuForFiles(Menu menu, SelectionDetails selectionDetails) {
-        assert(selectionDetails != null);
+        assert selectionDetails != null;
 
         MenuItem share = menu.findItem(R.id.dir_menu_share);
         MenuItem open = menu.findItem(R.id.dir_menu_open);
@@ -144,7 +144,7 @@
      */
     @VisibleForTesting
     public void updateContextMenuForDirs(Menu menu, SelectionDetails selectionDetails) {
-        assert(selectionDetails != null);
+        assert selectionDetails != null;
 
         MenuItem openInNewWindow = menu.findItem(R.id.dir_menu_open_in_new_window);
         MenuItem rename = menu.findItem(R.id.dir_menu_rename);
@@ -164,11 +164,12 @@
      */
     @VisibleForTesting
     public void updateContextMenu(Menu menu, SelectionDetails selectionDetails) {
-        assert(selectionDetails != null);
+        assert selectionDetails != null;
 
         MenuItem cut = menu.findItem(R.id.dir_menu_cut_to_clipboard);
         MenuItem copy = menu.findItem(R.id.dir_menu_copy_to_clipboard);
         MenuItem delete = menu.findItem(R.id.dir_menu_delete);
+        MenuItem inspect = menu.findItem(R.id.dir_menu_inspect);
 
         final boolean canCopy =
                 selectionDetails.size() > 0 && !selectionDetails.containsPartialFiles();
@@ -176,6 +177,8 @@
         cut.setEnabled(canCopy && canDelete);
         copy.setEnabled(canCopy);
         delete.setEnabled(canDelete);
+
+        inspect.setEnabled(selectionDetails.size() == 1);
     }
 
     /**
@@ -188,10 +191,12 @@
         MenuItem paste = menu.findItem(R.id.dir_menu_paste_from_clipboard);
         MenuItem selectAll = menu.findItem(R.id.dir_menu_select_all);
         MenuItem createDir = menu.findItem(R.id.dir_menu_create_dir);
+        MenuItem inspect = menu.findItem(R.id.dir_menu_inspect);
 
         paste.setEnabled(mDirDetails.hasItemsToPaste() && mDirDetails.canCreateDoc());
         updateSelectAll(selectAll);
         updateCreateDir(createDir);
+        updateInspect(inspect);
     }
 
     /**
@@ -273,8 +278,19 @@
         rename.setVisible(false);
     }
 
-    protected void updateInspector(MenuItem properties, SelectionDetails selectionDetails) {
-        properties.setVisible(false);
+    /**
+     * This method is called for standard activity option menu as opposed
+     * to when there is a selection.
+     */
+    protected void updateInspect(MenuItem inspector) {
+        inspector.setVisible(false);
+    }
+
+    /**
+     * This method is called for action mode, when a selection exists.
+     */
+    protected void updateInspect(MenuItem inspect, SelectionDetails selectionDetails) {
+        inspect.setVisible(false);
     }
 
     protected void updateViewInOwner(MenuItem view, SelectionDetails selectionDetails) {
diff --git a/src/com/android/documentsui/Metrics.java b/src/com/android/documentsui/Metrics.java
index f421906..b7f756f 100644
--- a/src/com/android/documentsui/Metrics.java
+++ b/src/com/android/documentsui/Metrics.java
@@ -16,14 +16,11 @@
 
 package com.android.documentsui;
 
-import static android.os.Environment.STANDARD_DIRECTORIES;
 import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
 import static com.android.documentsui.base.Shared.DEBUG;
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
-import android.annotation.StringDef;
-import android.app.Activity;
 import android.content.ContentProviderClient;
 import android.content.Context;
 import android.content.Intent;
@@ -45,13 +42,14 @@
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
-/** @hide */
+/**
+ * Methods for logging metrics.
+ */
 public final class Metrics {
     private static final String TAG = "Metrics";
 
@@ -689,102 +687,6 @@
         logHistogram(context, histogram, getOpCode(operationType, PROVIDER_INTRA));
     }
 
-    // Types for logInvalidScopedAccessRequest
-    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS =
-            "docsui_scoped_directory_access_invalid_args";
-    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY =
-            "docsui_scoped_directory_access_invalid_dir";
-    public static final String SCOPED_DIRECTORY_ACCESS_ERROR =
-            "docsui_scoped_directory_access_error";
-
-    @StringDef(value = {
-            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
-            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
-            SCOPED_DIRECTORY_ACCESS_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface InvalidScopedAccess{}
-
-    public static void logInvalidScopedAccessRequest(Context context,
-            @InvalidScopedAccess String type) {
-        switch (type) {
-            case SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS:
-            case SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY:
-            case SCOPED_DIRECTORY_ACCESS_ERROR:
-                logCount(context, type);
-                break;
-            default:
-                Log.wtf(TAG, "invalid InvalidScopedAccess: " + type);
-        }
-    }
-
-    // Types for logValidScopedAccessRequest
-    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED = 0;
-    public static final int SCOPED_DIRECTORY_ACCESS_GRANTED = 1;
-    public static final int SCOPED_DIRECTORY_ACCESS_DENIED = 2;
-    public static final int SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST = 3;
-    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED = 4;
-
-    @IntDef(flag = true, value = {
-            SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED,
-            SCOPED_DIRECTORY_ACCESS_GRANTED,
-            SCOPED_DIRECTORY_ACCESS_DENIED,
-            SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST,
-            SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ScopedAccessGrant {}
-
-    public static void logValidScopedAccessRequest(Activity activity, String directory,
-            @ScopedAccessGrant int type) {
-        int index = -1;
-        if (OpenExternalDirectoryActivity.DIRECTORY_ROOT.equals(directory)) {
-            index = -2;
-        } else {
-            for (int i = 0; i < STANDARD_DIRECTORIES.length; i++) {
-                if (STANDARD_DIRECTORIES[i].equals(directory)) {
-                    index = i;
-                    break;
-                }
-            }
-        }
-        final String packageName = activity.getCallingPackage();
-        switch (type) {
-            case SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_GRANTED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_DENIED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER, index);
-                break;
-            default:
-                Log.wtf(TAG, "invalid ScopedAccessGrant: " + type);
-        }
-    }
-
     /**
      * Logs the action that was started by user.
      * @param context
diff --git a/src/com/android/documentsui/PackageReceiver.java b/src/com/android/documentsui/PackageReceiver.java
index 5cb2827..e917369 100644
--- a/src/com/android/documentsui/PackageReceiver.java
+++ b/src/com/android/documentsui/PackageReceiver.java
@@ -23,10 +23,11 @@
 import android.net.Uri;
 
 import com.android.documentsui.picker.LastAccessedProvider;
-import com.android.documentsui.prefs.LocalPreferences;
+import com.android.documentsui.prefs.ScopedAccessLocalPreferences;
 
 /**
- * Clean up {@link LastAccessedProvider} and {@link LocalPreferences} when packages are removed.
+ * Clean up {@link LastAccessedProvider} and {@link ScopedAccessLocalPreferences} when packages
+ * are removed.
  */
 public class PackageReceiver extends BroadcastReceiver {
     @Override
@@ -44,7 +45,7 @@
                     null,
                     null);
             if (packageName != null) {
-                LocalPreferences.clearPackagePreferences(context, packageName);
+                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
             }
         } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
             if (packageName != null) {
@@ -52,7 +53,7 @@
                         LastAccessedProvider.buildLastAccessed(packageName),
                         LastAccessedProvider.METHOD_PURGE_PACKAGE,
                         packageName, null);
-                LocalPreferences.clearPackagePreferences(context, packageName);
+                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
             }
         }
     }
diff --git a/src/com/android/documentsui/RootsMonitor.java b/src/com/android/documentsui/RootsMonitor.java
index 82b3781..f1200ed 100644
--- a/src/com/android/documentsui/RootsMonitor.java
+++ b/src/com/android/documentsui/RootsMonitor.java
@@ -32,7 +32,6 @@
 import com.android.documentsui.dirlist.AnimationView;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.ProvidersAccess;
-import com.android.documentsui.selection.SelectionManager;
 
 import java.util.Collection;
 
@@ -57,7 +56,7 @@
         mReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                new HandleRootsChangedTask<T>(
+                new HandleRootsChangedTask<>(
                         activity,
                         actions,
                         providers,
diff --git a/src/com/android/documentsui/OpenExternalDirectoryActivity.java b/src/com/android/documentsui/ScopedAccessActivity.java
similarity index 90%
rename from src/com/android/documentsui/OpenExternalDirectoryActivity.java
rename to src/com/android/documentsui/ScopedAccessActivity.java
index 74af224..386e8da 100644
--- a/src/com/android/documentsui/OpenExternalDirectoryActivity.java
+++ b/src/com/android/documentsui/ScopedAccessActivity.java
@@ -19,21 +19,21 @@
 import static android.os.Environment.isStandardDirectory;
 import static android.os.storage.StorageVolume.EXTRA_DIRECTORY_NAME;
 import static android.os.storage.StorageVolume.EXTRA_STORAGE_VOLUME;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ERROR;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_GRANTED;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS;
-import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
-import static com.android.documentsui.Metrics.logInvalidScopedAccessRequest;
-import static com.android.documentsui.Metrics.logValidScopedAccessRequest;
-import static com.android.documentsui.base.Shared.DEBUG;
-import static com.android.documentsui.prefs.LocalPreferences.PERMISSION_ASK_AGAIN;
-import static com.android.documentsui.prefs.LocalPreferences.PERMISSION_NEVER_ASK;
-import static com.android.documentsui.prefs.LocalPreferences.getScopedAccessPermissionStatus;
-import static com.android.documentsui.prefs.LocalPreferences.setScopedAccessPermissionStatus;
+import static com.android.documentsui.ScopedAccessMetrics.DEBUG;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_DENIED;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ERROR;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_GRANTED;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS;
+import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
+import static com.android.documentsui.ScopedAccessMetrics.logInvalidScopedAccessRequest;
+import static com.android.documentsui.ScopedAccessMetrics.logValidScopedAccessRequest;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_ASK_AGAIN;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_NEVER_ASK;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getScopedAccessPermissionStatus;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.setScopedAccessPermissionStatus;
 
 import android.annotation.SuppressLint;
 import android.app.Activity;
@@ -75,10 +75,10 @@
 import java.util.List;
 
 /**
- * Activity responsible for handling {@link Intent#ACTION_OPEN_EXTERNAL_DOCUMENT}.
+ * Activity responsible for handling {@link StorageVolume#createAccessIntent(String)}.
  */
-public class OpenExternalDirectoryActivity extends Activity {
-    private static final String TAG = "OpenExternalDirectory";
+public class ScopedAccessActivity extends Activity {
+    private static final String TAG = "ScopedAccessActivity";
     private static final String FM_TAG = "open_external_directory";
     private static final String EXTRA_FILE = "com.android.documentsui.FILE";
     private static final String EXTRA_APP_LABEL = "com.android.documentsui.APP_LABEL";
@@ -151,7 +151,7 @@
      * Validates the given path (volume + directory) and display the appropriate dialog asking the
      * user to grant access to it.
      */
-    private static boolean showFragment(OpenExternalDirectoryActivity activity, int userId,
+    private static boolean showFragment(ScopedAccessActivity activity, int userId,
             StorageVolume storageVolume, String directoryName) {
         if (DEBUG)
             Log.d(TAG, "showFragment() for volume " + storageVolume.dump() + ", directory "
@@ -228,7 +228,7 @@
         }
 
         // Checks if the user has granted the permission already.
-        final Intent intent = getIntentForExistingPermission(activity, isRoot, internalRoot, file);
+        final Intent intent = getIntentForExistingPermission(activity, internalRoot, file);
         if (intent != null) {
             logValidScopedAccessRequest(activity, directory,
                     SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED);
@@ -261,8 +261,7 @@
 
         final FragmentManager fm = activity.getFragmentManager();
         final FragmentTransaction ft = fm.beginTransaction();
-        final OpenExternalDirectoryDialogFragment fragment =
-                new OpenExternalDirectoryDialogFragment();
+        final ScopedAccessDialogFragment fragment = new ScopedAccessDialogFragment();
         fragment.setArguments(args);
         ft.add(fragment, FM_TAG);
         ft.commitAllowingStateLoss();
@@ -341,8 +340,8 @@
         return intent;
     }
 
-    private static Intent getIntentForExistingPermission(OpenExternalDirectoryActivity activity,
-            boolean isRoot, File root, File file) {
+    private static Intent getIntentForExistingPermission(ScopedAccessActivity activity, File root,
+            File file) {
         final String packageName = activity.getCallingPackage();
         final ContentProviderClient storageClient = activity.getExternalStorageClient();
         final Uri grantedUri = getGrantedUriPermission(activity, storageClient, file);
@@ -369,7 +368,7 @@
         return null;
     }
 
-    public static class OpenExternalDirectoryDialogFragment extends DialogFragment {
+    public static class ScopedAccessDialogFragment extends DialogFragment {
 
         private File mFile;
         private String mVolumeUuid;
@@ -378,7 +377,7 @@
         private boolean mIsRoot;
         private boolean mIsPrimary;
         private CheckBox mDontAskAgain;
-        private OpenExternalDirectoryActivity mActivity;
+        private ScopedAccessActivity mActivity;
         private AlertDialog mDialog;
 
         @Override
@@ -394,7 +393,7 @@
                 mIsRoot = args.getBoolean(EXTRA_IS_ROOT);
                 mIsPrimary= args.getBoolean(EXTRA_IS_PRIMARY);
             }
-            mActivity = (OpenExternalDirectoryActivity) getActivity();
+            mActivity = (ScopedAccessActivity) getActivity();
         }
 
         @Override
@@ -416,7 +415,7 @@
                 // Sanity check.
                 Log.wtf(TAG, "activity references don't match on onCreateDialog(): mActivity = "
                         + mActivity + " , getActivity() = " + getActivity());
-                mActivity = (OpenExternalDirectoryActivity) getActivity();
+                mActivity = (ScopedAccessActivity) getActivity();
             }
             final String directory = mFile.getName();
             final String directoryName = mIsRoot ? DIRECTORY_ROOT : directory;
diff --git a/src/com/android/documentsui/ScopedAccessMetrics.java b/src/com/android/documentsui/ScopedAccessMetrics.java
new file mode 100644
index 0000000..177150e
--- /dev/null
+++ b/src/com/android/documentsui/ScopedAccessMetrics.java
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui;
+
+import static android.os.Environment.STANDARD_DIRECTORIES;
+
+import android.annotation.IntDef;
+import android.annotation.StringDef;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Methods for logging scoped directory access metrics.
+ */
+public final class ScopedAccessMetrics {
+    private static final String TAG = "Metrics";
+
+    public static final boolean DEBUG = Build.IS_DEBUGGABLE;
+
+    // Types for logInvalidScopedAccessRequest
+    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS =
+            "docsui_scoped_directory_access_invalid_args";
+    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY =
+            "docsui_scoped_directory_access_invalid_dir";
+    public static final String SCOPED_DIRECTORY_ACCESS_ERROR =
+            "docsui_scoped_directory_access_error";
+
+    @StringDef(value = {
+            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
+            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
+            SCOPED_DIRECTORY_ACCESS_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InvalidScopedAccess{}
+
+    public static void logInvalidScopedAccessRequest(Context context,
+            @InvalidScopedAccess String type) {
+        switch (type) {
+            case SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS:
+            case SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY:
+            case SCOPED_DIRECTORY_ACCESS_ERROR:
+                logCount(context, type);
+                break;
+            default:
+                Log.wtf(TAG, "invalid InvalidScopedAccess: " + type);
+        }
+    }
+
+    // Types for logValidScopedAccessRequest
+    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED = 0;
+    public static final int SCOPED_DIRECTORY_ACCESS_GRANTED = 1;
+    public static final int SCOPED_DIRECTORY_ACCESS_DENIED = 2;
+    public static final int SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST = 3;
+    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED = 4;
+
+    @IntDef(flag = true, value = {
+            SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED,
+            SCOPED_DIRECTORY_ACCESS_GRANTED,
+            SCOPED_DIRECTORY_ACCESS_DENIED,
+            SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST,
+            SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScopedAccessGrant {}
+
+    public static void logValidScopedAccessRequest(Activity activity, String directory,
+            @ScopedAccessGrant int type) {
+        int index = -1;
+        if (ScopedAccessActivity.DIRECTORY_ROOT.equals(directory)) {
+            index = -2;
+        } else {
+            for (int i = 0; i < STANDARD_DIRECTORIES.length; i++) {
+                if (STANDARD_DIRECTORIES[i].equals(directory)) {
+                    index = i;
+                    break;
+                }
+            }
+        }
+        final String packageName = activity.getCallingPackage();
+        switch (type) {
+            case SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_GRANTED:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_DENIED:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER, index);
+                break;
+            default:
+                Log.wtf(TAG, "invalid ScopedAccessGrant: " + type);
+        }
+    }
+
+    /**
+     * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
+     *
+     * @param context
+     * @param name The counter to increment.
+     */
+    private static void logCount(Context context, String name) {
+        if (DEBUG) Log.d(TAG, name + ": " + 1);
+        MetricsLogger.count(context, name, 1);
+    }
+}
diff --git a/src/com/android/documentsui/ScopedAccessPackageReceiver.java b/src/com/android/documentsui/ScopedAccessPackageReceiver.java
new file mode 100644
index 0000000..995eedc
--- /dev/null
+++ b/src/com/android/documentsui/ScopedAccessPackageReceiver.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import com.android.documentsui.prefs.ScopedAccessLocalPreferences;
+
+/**
+ * Clean up {@link ScopedAccessLocalPreferences} when packages are removed.
+ */
+public class ScopedAccessPackageReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final String action = intent.getAction();
+        final Uri data = intent.getData();
+        final String packageName = data == null ? null : data.getSchemeSpecificPart();
+
+        if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) {
+            if (packageName != null) {
+                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
+            }
+        } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
+            if (packageName != null) {
+                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
+            }
+        }
+    }
+}
diff --git a/src/com/android/documentsui/ScopedAccessProvider.java b/src/com/android/documentsui/ScopedAccessProvider.java
new file mode 100644
index 0000000..2fcbe45
--- /dev/null
+++ b/src/com/android/documentsui/ScopedAccessProvider.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2018 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 com.android.documentsui;
+
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COLUMNS;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COLUMNS;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_DIRECTORY;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_GRANTED;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_PACKAGE;
+import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_VOLUME_UUID;
+
+import static com.android.documentsui.ScopedAccessMetrics.DEBUG;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_ASK_AGAIN;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_NEVER_ASK;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPackages;
+import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPermissions;
+
+import android.app.ActivityManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.documentsui.prefs.ScopedAccessLocalPreferences.Permission;
+import com.android.internal.util.ArrayUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Provider used to manage scoped access directory permissions.
+ *
+ * <p>It fetches data from 2 sources:
+ *
+ * <ul>
+ * <li>{@link com.android.documentsui.prefs.ScopedAccessLocalPreferences} for denied permissions.
+ * <li>{@link ActivityManager} for allowed permissions.
+ * </ul>
+ *
+ * <p>And returns the results in 2 tables:
+ *
+ * <ul>
+ * <li>{@link #TABLE_PACKAGES}: read-only table with the name of all packages
+ * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_PACKAGE}) that
+ * had a scoped access directory permission granted or denied.
+ * <li>{@link #TABLE_PERMISSIONS}: writable table with the name of all packages
+ * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_PACKAGE}) that
+ * had a scoped access directory
+ * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_DIRECTORY})
+ * permission for a volume (column
+ * {@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_VOLUME_UUID}, which
+ * contains the volume UUID or {@code null} if it's the primary partition) granted or denied
+ * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_GRANTED}).
+ * </ul>
+ *
+ * <p><b>Note:</b> the {@code query()} methods return all entries; it does not support selection or
+ * projections.
+ */
+// TODO(b/63720392): add unit tests
+public class ScopedAccessProvider extends ContentProvider {
+
+    private static final String TAG = "ScopedAccessProvider";
+    private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int URI_PACKAGES = 1;
+    private static final int URI_PERMISSIONS = 2;
+
+    public static final String AUTHORITY = "com.android.documentsui.scopedAccess";
+
+    static {
+        sMatcher.addURI(AUTHORITY, TABLE_PACKAGES + "/*", URI_PACKAGES);
+        sMatcher.addURI(AUTHORITY, TABLE_PERMISSIONS + "/*", URI_PERMISSIONS);
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        if (DEBUG) {
+            Log.v(TAG, "query(" + uri + "): proj=" + Arrays.toString(projection)
+                + ", sel=" + selection);
+        }
+        switch (sMatcher.match(uri)) {
+            case URI_PACKAGES:
+                return getPackagesCursor();
+            case URI_PERMISSIONS:
+                return getPermissionsCursor();
+            default:
+                throw new UnsupportedOperationException("Unsupported Uri " + uri);
+        }
+    }
+
+    private Cursor getPackagesCursor() {
+        // First get the packages that were denied
+        final ArraySet<String> pkgs = getAllPackages(getContext());
+
+        if (ArrayUtils.isEmpty(pkgs)) {
+            if (DEBUG) Log.v(TAG, "getPackagesCursor(): ignoring " + pkgs);
+            return null;
+        }
+
+        // TODO(b/63720392): also need to query AM for granted permissions
+
+        // Then create the cursor
+        final MatrixCursor cursor = new MatrixCursor(TABLE_PACKAGES_COLUMNS, pkgs.size());
+        final Object[] column = new Object[1];
+        for (int i = 0; i < pkgs.size(); i++) {
+            final String pkg = pkgs.valueAt(i);
+            column[0] = pkg;
+            cursor.addRow(column);
+        }
+
+        return cursor;
+    }
+
+    // TODO(b/63720392): decide how to handle ROOT_DIRECTORY - convert to null?
+    private Cursor getPermissionsCursor() {
+        // First get the packages that were denied
+        final ArrayList<Permission> rawPermissions = getAllPermissions(getContext());
+
+        if (ArrayUtils.isEmpty(rawPermissions)) {
+            if (DEBUG) Log.v(TAG, "getPermissionsCursor(): ignoring " + rawPermissions);
+            return null;
+        }
+
+        final List<Object[]> permissions = rawPermissions.stream()
+                .filter(permission -> permission.status == PERMISSION_ASK_AGAIN
+                        || permission.status == PERMISSION_NEVER_ASK)
+                .map(permission ->
+                        new Object[] { permission.pkg, permission.uuid, permission.directory,
+                                Integer.valueOf(1) })
+                .collect(Collectors.toList());
+
+        // TODO(b/63720392): also need to query AM for granted permissions
+
+        // Then create the cursor
+        final MatrixCursor cursor = new MatrixCursor(TABLE_PERMISSIONS_COLUMNS, permissions.size());
+        for (int i = 0; i < permissions.size(); i++) {
+            cursor.addRow(permissions.get(i));
+        }
+        return cursor;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        if (sMatcher.match(uri) != URI_PERMISSIONS) {
+            throw new UnsupportedOperationException("insert(): unsupported " + uri);
+        }
+
+        if (DEBUG) Log.v(TAG, "insert(" + uri + "): " + values);
+
+        // TODO(b/63720392): implement
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        if (sMatcher.match(uri) != URI_PERMISSIONS) {
+            throw new UnsupportedOperationException("delete(): unsupported " + uri);
+        }
+
+        if (DEBUG) Log.v(TAG, "delete(" + uri + "): " + selection);
+
+        // TODO(b/63720392): implement
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        if (sMatcher.match(uri) != URI_PERMISSIONS) {
+            throw new UnsupportedOperationException("update(): unsupported " + uri);
+        }
+
+        if (DEBUG) Log.v(TAG, "update(" + uri + "): " + selection + " = " + values);
+
+        // TODO(b/63720392): implement
+        return 0;
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        final String prefix = "  ";
+
+        pw.print("Packages: ");
+        try (Cursor cursor = getPackagesCursor()) {
+            if (cursor == null) {
+                pw.println("N/A");
+            } else {
+                pw.println(cursor.getCount());
+                while (cursor.moveToNext()) {
+                    pw.print(prefix); pw.println(cursor.getString(0));
+                }
+            }
+        }
+
+        pw.print("Permissions: ");
+        try (Cursor cursor = getPermissionsCursor()) {
+            if (cursor == null) {
+                pw.println("N/A");
+            } else {
+                pw.println(cursor.getCount());
+                while (cursor.moveToNext()) {
+                    pw.print(prefix); pw.print(cursor.getString(TABLE_PERMISSIONS_COL_PACKAGE));
+                    pw.print('/');
+                    final String uuid = cursor.getString(TABLE_PERMISSIONS_COL_VOLUME_UUID);
+                    if (uuid != null) {
+                        pw.print(uuid); pw.print('>');
+                    }
+                    pw.print(cursor.getString(TABLE_PERMISSIONS_COL_DIRECTORY));
+                    pw.print(": "); pw.println(cursor.getInt(TABLE_PERMISSIONS_COL_GRANTED) == 1);
+                }
+            }
+        }
+
+        pw.print("Raw permissions: ");
+        final ArrayList<Permission> rawPermissions = getAllPermissions(getContext());
+        if (rawPermissions.isEmpty()) {
+            pw.println("N/A");
+        } else {
+            final int size = rawPermissions.size();
+            pw.println(size);
+            for (int i = 0; i < size; i++) {
+                final Permission permission = rawPermissions.get(i);
+                pw.print(prefix); pw.println(permission);
+            }
+        }
+    }
+}
diff --git a/src/com/android/documentsui/SharedInputHandler.java b/src/com/android/documentsui/SharedInputHandler.java
index f3f2641..68772ab 100644
--- a/src/com/android/documentsui/SharedInputHandler.java
+++ b/src/com/android/documentsui/SharedInputHandler.java
@@ -24,7 +24,7 @@
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Procedure;
 import com.android.documentsui.dirlist.FocusHandler;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.SelectionHelper;
 
 public class SharedInputHandler {
 
@@ -34,11 +34,11 @@
     private final Procedure mSearchCanceler;
     private final Procedure mDirPopper;
     private final Features mFeatures;
-    private final SelectionManager mSelectionMgr;
+    private final SelectionHelper mSelectionMgr;
 
     public SharedInputHandler(
             FocusHandler focusHandler,
-            SelectionManager selectionMgr,
+            SelectionHelper selectionMgr,
             Procedure searchCanceler,
             Procedure dirPopper,
             Features features) {
diff --git a/src/com/android/documentsui/archives/Archive.java b/src/com/android/documentsui/archives/Archive.java
index e3c81e3..14d703c 100644
--- a/src/com/android/documentsui/archives/Archive.java
+++ b/src/com/android/documentsui/archives/Archive.java
@@ -26,6 +26,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.storage.StorageManager;
 import android.provider.DocumentsContract;
+import android.provider.MetadataReader;
 import android.provider.DocumentsContract.Document;
 import android.support.annotation.Nullable;
 import android.system.ErrnoException;
@@ -281,7 +282,10 @@
         final String mimeType = getMimeTypeForEntry(entry);
         row.add(Document.COLUMN_MIME_TYPE, mimeType);
 
-        final int flags = mimeType.startsWith("image/") ? Document.FLAG_SUPPORTS_THUMBNAIL : 0;
+        int flags = mimeType.startsWith("image/") ? Document.FLAG_SUPPORTS_THUMBNAIL : 0;
+        if (MetadataReader.isSupportedMimeType(mimeType)) {
+            flags |= Document.FLAG_SUPPORTS_METADATA;
+        }
         row.add(Document.COLUMN_FLAGS, flags);
     }
 
diff --git a/src/com/android/documentsui/archives/ArchivesProvider.java b/src/com/android/documentsui/archives/ArchivesProvider.java
index 8f0e399..508a1aa 100644
--- a/src/com/android/documentsui/archives/ArchivesProvider.java
+++ b/src/com/android/documentsui/archives/ArchivesProvider.java
@@ -17,38 +17,34 @@
 package com.android.documentsui.archives;
 
 import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.content.res.AssetFileDescriptor;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
 import android.database.Cursor;
-import android.database.MatrixCursor.RowBuilder;
 import android.database.MatrixCursor;
+import android.database.MatrixCursor.RowBuilder;
 import android.graphics.Point;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
-import android.provider.DocumentsContract;
 import android.provider.DocumentsProvider;
+import android.provider.MetadataReader;
 import android.support.annotation.Nullable;
 import android.util.Log;
 
 import com.android.documentsui.R;
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
 
-import java.io.Closeable;
-import java.io.File;
+import libcore.io.IoUtils;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
-import java.util.concurrent.locks.Lock;
 
 /**
  * Provides basic implementation for creating, extracting and accessing
@@ -71,7 +67,7 @@
     };
 
     @GuardedBy("mArchives")
-    private final Map<Key, Loader> mArchives = new HashMap<Key, Loader>();
+    private final Map<Key, Loader> mArchives = new HashMap<>();
 
     @Override
     public Bundle call(String method, String arg, Bundle extras) {
@@ -153,6 +149,32 @@
     }
 
     @Override
+    public @Nullable Bundle getDocumentMetadata(String documentId)
+            throws FileNotFoundException {
+
+        final Archive archive = getLoaderOrThrow(documentId).get();
+        final String mimeType = archive.getDocumentType(documentId);
+
+        if (!MetadataReader.isSupportedMimeType(mimeType)) {
+            return null;
+        }
+
+        InputStream stream = null;
+        try {
+            stream = new ParcelFileDescriptor.AutoCloseInputStream(
+                    openDocument(documentId, "r", null));
+            final Bundle metadata = new Bundle();
+            MetadataReader.getMetadata(metadata, stream, mimeType, null);
+            return metadata;
+        } catch (IOException e) {
+            Log.e(TAG, "An error occurred retrieving the metadata.", e);
+            return null;
+        } finally {
+            IoUtils.closeQuietly(stream);
+        }
+    }
+
+    @Override
     public Cursor queryDocument(String documentId, @Nullable String[] projection)
             throws FileNotFoundException {
         final ArchiveId archiveId = ArchiveId.fromDocumentId(documentId);
diff --git a/src/com/android/documentsui/base/DocumentInfo.java b/src/com/android/documentsui/base/DocumentInfo.java
index 5d9a93c..a13ad98 100644
--- a/src/com/android/documentsui/base/DocumentInfo.java
+++ b/src/com/android/documentsui/base/DocumentInfo.java
@@ -223,6 +223,7 @@
                 + ", isDeleteSupported=" + isDeleteSupported()
                 + ", isCreateSupported=" + isCreateSupported()
                 + ", isRenameSupported=" + isRenameSupported()
+                + ", isMetadataSupported=" + isMetadataSupported()
                 + "} @ "
                 + derivedUri;
     }
@@ -231,30 +232,30 @@
         return (flags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0;
     }
 
-    public boolean isDirectory() {
-        return Document.MIME_TYPE_DIR.equals(mimeType);
-    }
-
-    public boolean isWriteSupported() {
-        return (flags & Document.FLAG_SUPPORTS_WRITE) != 0;
-    }
-
     public boolean isDeleteSupported() {
         return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
     }
 
-    public boolean isRemoveSupported() {
-        return (flags & Document.FLAG_SUPPORTS_REMOVE) != 0;
+    public boolean isMetadataSupported() {
+        return (flags & Document.FLAG_SUPPORTS_METADATA) != 0;
     }
 
     public boolean isMoveSupported() {
         return (flags & Document.FLAG_SUPPORTS_MOVE) != 0;
     }
 
+    public boolean isRemoveSupported() {
+        return (flags & Document.FLAG_SUPPORTS_REMOVE) != 0;
+    }
+
     public boolean isRenameSupported() {
         return (flags & Document.FLAG_SUPPORTS_RENAME) != 0;
     }
 
+    public boolean isSettingsSupported() {
+        return (flags & Document.FLAG_SUPPORTS_SETTINGS) != 0;
+    }
+
     public boolean isThumbnailSupported() {
         return (flags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
     }
@@ -263,6 +264,14 @@
         return (flags & Document.FLAG_WEB_LINKABLE) != 0;
     }
 
+    public boolean isWriteSupported() {
+        return (flags & Document.FLAG_SUPPORTS_WRITE) != 0;
+    }
+
+    public boolean isDirectory() {
+        return Document.MIME_TYPE_DIR.equals(mimeType);
+    }
+
     public boolean isArchive() {
         return ArchivesProvider.isSupportedArchiveType(mimeType);
     }
@@ -284,10 +293,6 @@
         return (flags & Document.FLAG_VIRTUAL_DOCUMENT) != 0;
     }
 
-    public boolean isSettingsSupported() {
-        return (flags & Document.FLAG_SUPPORTS_SETTINGS) != 0;
-    }
-
     public boolean prefersSortByLastModified() {
         return (flags & Document.FLAG_DIR_PREFERS_LAST_MODIFIED) != 0;
     }
diff --git a/src/com/android/documentsui/base/DocumentStack.java b/src/com/android/documentsui/base/DocumentStack.java
index 9b0605c..090bcb1 100644
--- a/src/com/android/documentsui/base/DocumentStack.java
+++ b/src/com/android/documentsui/base/DocumentStack.java
@@ -17,6 +17,7 @@
 package com.android.documentsui.base;
 
 import static com.android.documentsui.base.Shared.DEBUG;
+import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.content.ContentResolver;
 import android.database.Cursor;
@@ -123,13 +124,10 @@
     }
 
     public void push(DocumentInfo info) {
-        boolean alreadyInStack = mList.contains(info);
-        assert (!alreadyInStack);
-        if (!alreadyInStack) {
-            if (DEBUG) Log.d(TAG, "Adding doc to stack: " + info);
-            mList.addLast(info);
-            mStackTouched = true;
-        }
+        checkArgument(!mList.contains(info));
+        if (DEBUG) Log.d(TAG, "Adding doc to stack: " + info);
+        mList.addLast(info);
+        mStackTouched = true;
     }
 
     public DocumentInfo pop() {
diff --git a/src/com/android/documentsui/base/DummyLookup.java b/src/com/android/documentsui/base/DummyLookup.java
new file mode 100644
index 0000000..11a6375
--- /dev/null
+++ b/src/com/android/documentsui/base/DummyLookup.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.base;
+
+/**
+ * Lookup that always returns null.
+ */
+public final class DummyLookup<K, V> implements Lookup<K, V> {
+    @Override
+    public V lookup(K key) {
+        return null;
+    }
+}
diff --git a/src/com/android/documentsui/base/Events.java b/src/com/android/documentsui/base/Events.java
index 67814df..c38f1a4 100644
--- a/src/com/android/documentsui/base/Events.java
+++ b/src/com/android/documentsui/base/Events.java
@@ -16,72 +16,83 @@
 
 package com.android.documentsui.base;
 
-import static com.android.documentsui.base.Shared.DEBUG;
-
 import android.graphics.Point;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.util.Pools;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.documentsui.dirlist.DocumentDetails;
-import com.android.documentsui.dirlist.DocumentHolder;
-
-import javax.annotation.Nullable;
 
 /**
  * Utility code for dealing with MotionEvents.
  */
 public final class Events {
 
-    /**
-     * Returns true if event was triggered by a mouse.
-     */
     public static boolean isMouseEvent(MotionEvent e) {
-        int toolType = e.getToolType(0);
-        return toolType == MotionEvent.TOOL_TYPE_MOUSE;
+        return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
     }
 
-    /**
-     * Returns true if event was triggered by a finger or stylus touch.
-     */
+    public static boolean isActionMove(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_MOVE;
+    }
+
     public static boolean isActionDown(MotionEvent e) {
         return e.getActionMasked() == MotionEvent.ACTION_DOWN;
     }
 
-    /**
-     * Returns true if event was triggered by a finger or stylus touch.
-     */
     public static boolean isActionUp(MotionEvent e) {
         return e.getActionMasked() == MotionEvent.ACTION_UP;
     }
 
-    /**
-     * Returns true if the shift is pressed.
-     */
-    public boolean isShiftPressed(MotionEvent e) {
-        return hasShiftBit(e.getMetaState());
+    public static boolean isMultiPointerActionDown(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN;
+    }
+
+    public static boolean isMultiPointerActionUp(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_POINTER_UP;
+    }
+
+    public static boolean isActionCancel(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_CANCEL;
+    }
+
+    public static boolean isPrimaryButtonPressed(MotionEvent e) {
+        return e.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
+    }
+
+    public static boolean isSecondaryButtonPressed(MotionEvent e) {
+        return e.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
+    }
+
+    public static boolean isTertiaryButtonPressed(MotionEvent e) {
+        return e.isButtonPressed(MotionEvent.BUTTON_TERTIARY);
+    }
+
+    public static boolean isCtrlKeyPressed(MotionEvent e) {
+        return hasBit(e.getMetaState(), KeyEvent.META_CTRL_ON);
+    }
+
+    public static boolean isAltKeyPressed(MotionEvent e) {
+        return hasBit(e.getMetaState(), KeyEvent.META_ALT_ON);
+    }
+
+    public static boolean isShiftKeyPressed(MotionEvent e) {
+        return hasBit(e.getMetaState(), KeyEvent.META_SHIFT_ON);
+    }
+
+    public static boolean isTouchpadScroll(MotionEvent e) {
+        // Touchpad inputs are treated as mouse inputs, and when scrolling, there are no buttons
+        // returned.
+        return isMouseEvent(e) && isActionMove(e) && e.getButtonState() == 0;
+    }
+
+    private static boolean hasBit(int metaState, int bit) {
+        return (metaState & bit) != 0;
+    }
+
+    public static Point getOrigin(MotionEvent e) {
+        return new Point((int) e.getX(), (int) e.getY());
     }
 
     /**
-     * Returns true if the event is a mouse drag event.
-     * @param e
-     * @return
-     */
-    public static boolean isMouseDragEvent(InputEvent e) {
-        return e.isMouseEvent()
-                && e.isActionMove()
-                && e.isPrimaryButtonPressed()
-                && e.isOverDragHotspot();
-    }
-
-    /**
-     * Whether or not the given keyCode represents a navigation keystroke (e.g. up, down, home).
-     *
-     * @param keyCode
-     * @return
+     * @return true if keyCode is a known navigation code (e.g. up, down, home).
      */
     public static boolean isNavigationKeyCode(int keyCode) {
         switch (keyCode) {
@@ -99,320 +110,14 @@
         }
     }
 
-
     /**
-     * Returns true if the "SHIFT" bit is set.
+     * Returns true if the event is a mouse drag event.
+     * @param e
+     * @return
      */
-    public static boolean hasShiftBit(int metaState) {
-        return (metaState & KeyEvent.META_SHIFT_ON) != 0;
-    }
-
-    public static boolean hasCtrlBit(int metaState) {
-        return (metaState & KeyEvent.META_CTRL_ON) != 0;
-    }
-
-    public static boolean hasAltBit(int metaState) {
-        return (metaState & KeyEvent.META_ALT_ON) != 0;
-    }
-
-    /**
-     * A facade over MotionEvent primarily designed to permit for unit testing
-     * of related code.
-     */
-    public interface InputEvent extends AutoCloseable {
-        boolean isMouseEvent();
-        boolean isPrimaryButtonPressed();
-        boolean isSecondaryButtonPressed();
-        boolean isTertiaryButtonPressed();
-        boolean isAltKeyDown();
-        boolean isShiftKeyDown();
-        boolean isCtrlKeyDown();
-
-        /** Returns true if the action is the initial press of a mouse or touch. */
-        boolean isActionDown();
-
-        /** Returns true if the action is the final release of a mouse or touch. */
-        boolean isActionUp();
-
-        /**
-         * Returns true when the action is the initial press of a non-primary (ex. second finger)
-         * pointer.
-         * See {@link MotionEvent#ACTION_POINTER_DOWN}.
-         */
-        boolean isMultiPointerActionDown();
-
-        /**
-         * Returns true when the action is the final of a non-primary (ex. second finger)
-         * pointer.
-         * * See {@link MotionEvent#ACTION_POINTER_UP}.
-         */
-        boolean isMultiPointerActionUp();
-
-        /** Returns true if the action is neither the initial nor the final release of a mouse
-         * or touch. */
-        boolean isActionMove();
-
-        /** Returns true if the action is cancel. */
-        boolean isActionCancel();
-
-        // Eliminate the checked Exception from Autoclosable.
-        @Override
-        public void close();
-
-        Point getOrigin();
-        float getX();
-        float getY();
-        float getRawX();
-        float getRawY();
-        int getPointerCount();
-
-        /** Returns true if there is an item under the finger/cursor. */
-        boolean isOverItem();
-
-        /**
-         * Returns true if there is a model backed item under the finger/cursor.
-         * Resulting calls on the event instance should never return a null
-         * DocumentDetails and DocumentDetails#hasModelId should always return true
-         */
-        boolean isOverModelItem();
-
-        /**
-         * Returns true if the event is over an area that can be dragged via touch.
-         * List items have a white area that is not draggable.
-         */
-        boolean isOverDragHotspot();
-
-        /**
-         * Returns true if the event is a two/three-finger scroll on touchpad.
-         */
-        boolean isTouchpadScroll();
-
-        /** Returns the adapter position of the item under the finger/cursor. */
-        int getItemPosition();
-
-        boolean isOverDocIcon();
-
-        /** Returns the DocumentDetails for the item under the event, or null. */
-        @Nullable DocumentDetails getDocumentDetails();
-    }
-
-    public static final class MotionInputEvent implements InputEvent {
-        private static final String TAG = "MotionInputEvent";
-
-        private static final int UNSET_POSITION = RecyclerView.NO_POSITION - 1;
-
-        private static final Pools.SimplePool<MotionInputEvent> sPool = new Pools.SimplePool<>(1);
-
-        private MotionEvent mEvent;
-        private @Nullable RecyclerView mRecView;
-
-        private int mPosition = UNSET_POSITION;
-        private @Nullable DocumentDetails mDocDetails;
-
-        private MotionInputEvent() {
-            if (DEBUG) Log.i(TAG, "Created a new instance.");
-        }
-
-        public static MotionInputEvent obtain(MotionEvent event, RecyclerView view) {
-            Shared.checkMainLoop();
-
-            MotionInputEvent instance = sPool.acquire();
-            instance = (instance != null ? instance : new MotionInputEvent());
-
-            instance.mEvent = event;
-            instance.mRecView = view;
-
-            return instance;
-        }
-
-        public void recycle() {
-            Shared.checkMainLoop();
-
-            mEvent = null;
-            mRecView = null;
-            mPosition = UNSET_POSITION;
-            mDocDetails = null;
-
-            boolean released = sPool.release(this);
-            // This assert is used to guarantee we won't generate too many instances that can't be
-            // held in the pool, which indicates our pool size is too small.
-            //
-            // Right now one instance is enough because we expect all instances are only used in
-            // main thread.
-            assert(released);
-        }
-
-        @Override
-        public void close() {
-            recycle();
-        }
-
-        @Override
-        public boolean isMouseEvent() {
-            return Events.isMouseEvent(mEvent);
-        }
-
-        @Override
-        public boolean isPrimaryButtonPressed() {
-            return mEvent.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
-        }
-
-        @Override
-        public boolean isSecondaryButtonPressed() {
-            return mEvent.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
-        }
-
-        @Override
-        public boolean isTertiaryButtonPressed() {
-            return mEvent.isButtonPressed(MotionEvent.BUTTON_TERTIARY);
-        }
-
-        @Override
-        public boolean isAltKeyDown() {
-            return Events.hasAltBit(mEvent.getMetaState());
-        }
-
-        @Override
-        public boolean isShiftKeyDown() {
-            return Events.hasShiftBit(mEvent.getMetaState());
-        }
-
-        @Override
-        public boolean isCtrlKeyDown() {
-            return Events.hasCtrlBit(mEvent.getMetaState());
-        }
-
-        @Override
-        public boolean isActionDown() {
-            return mEvent.getActionMasked() == MotionEvent.ACTION_DOWN;
-        }
-
-        @Override
-        public boolean isActionUp() {
-            return mEvent.getActionMasked() == MotionEvent.ACTION_UP;
-        }
-
-        @Override
-        public boolean isMultiPointerActionDown() {
-            return mEvent.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN;
-        }
-
-        @Override
-        public boolean isMultiPointerActionUp() {
-            return mEvent.getActionMasked() == MotionEvent.ACTION_POINTER_UP;
-        }
-
-
-        @Override
-        public boolean isActionMove() {
-            return mEvent.getActionMasked() == MotionEvent.ACTION_MOVE;
-        }
-
-        @Override
-        public boolean isActionCancel() {
-            return mEvent.getActionMasked() == MotionEvent.ACTION_CANCEL;
-        }
-
-        @Override
-        public Point getOrigin() {
-            return new Point((int) mEvent.getX(), (int) mEvent.getY());
-        }
-
-        @Override
-        public float getX() {
-            return mEvent.getX();
-        }
-
-        @Override
-        public float getY() {
-            return mEvent.getY();
-        }
-
-        @Override
-        public float getRawX() {
-            return mEvent.getRawX();
-        }
-
-        @Override
-        public float getRawY() {
-            return mEvent.getRawY();
-        }
-
-        @Override
-        public int getPointerCount() {
-            return mEvent.getPointerCount();
-        }
-
-        @Override
-        public boolean isTouchpadScroll() {
-            // Touchpad inputs are treated as mouse inputs, and when scrolling, there are no buttons
-            // returned.
-            return isMouseEvent() && isActionMove() && mEvent.getButtonState() == 0;
-        }
-
-        @Override
-        public boolean isOverDragHotspot() {
-            return isOverItem() && getDocumentDetails().isInDragHotspot(this);
-        }
-
-        @Override
-        public boolean isOverItem() {
-            return getItemPosition() != RecyclerView.NO_POSITION;
-        }
-
-        @Override
-        public boolean isOverDocIcon() {
-            return isOverItem() && getDocumentDetails().isOverDocIcon(this);
-        }
-
-        @Override
-        public boolean isOverModelItem() {
-            return isOverItem() && getDocumentDetails().hasModelId();
-        }
-
-        @Override
-        public int getItemPosition() {
-            if (mPosition == UNSET_POSITION) {
-                View child = mRecView.findChildViewUnder(mEvent.getX(), mEvent.getY());
-                mPosition = (child != null)
-                        ? mRecView.getChildAdapterPosition(child)
-                        : RecyclerView.NO_POSITION;
-            }
-            return mPosition;
-        }
-
-        @Override
-        public @Nullable DocumentDetails getDocumentDetails() {
-            if (mDocDetails == null) {
-                View childView = mRecView.findChildViewUnder(mEvent.getX(), mEvent.getY());
-                mDocDetails = (childView != null)
-                    ? (DocumentHolder) mRecView.getChildViewHolder(childView)
-                    : null;
-            }
-            if (isOverItem()) {
-                assert(mDocDetails != null);
-            }
-            return mDocDetails;
-        }
-
-        @Override
-        public String toString() {
-            return new StringBuilder()
-                    .append("MotionInputEvent {")
-                    .append("isMouseEvent=").append(isMouseEvent())
-                    .append(" isPrimaryButtonPressed=").append(isPrimaryButtonPressed())
-                    .append(" isSecondaryButtonPressed=").append(isSecondaryButtonPressed())
-                    .append(" isShiftKeyDown=").append(isShiftKeyDown())
-                    .append(" isAltKeyDown=").append(isAltKeyDown())
-                    .append(" action(decoded)=").append(
-                            MotionEvent.actionToString(mEvent.getActionMasked()))
-                    .append(" getOrigin=").append(getOrigin())
-                    .append(" isOverItem=").append(isOverItem())
-                    .append(" getItemPosition=").append(getItemPosition())
-                    .append(" getDocumentDetails=").append(getDocumentDetails())
-                    .append(" getPointerCount=").append(getPointerCount())
-                    .append("}")
-                    .toString();
-        }
+    public static boolean isMouseDragEvent(MotionEvent e) {
+        return isMouseEvent(e)
+                && isActionMove(e)
+                && isPrimaryButtonPressed(e);
     }
 }
diff --git a/src/com/android/documentsui/base/Features.java b/src/com/android/documentsui/base/Features.java
index 7a9936f..7714353 100644
--- a/src/com/android/documentsui/base/Features.java
+++ b/src/com/android/documentsui/base/Features.java
@@ -106,6 +106,10 @@
             return isEnabled(R.bool.feature_content_refresh);
         }
 
+        private boolean isFunPolicyEnabled() {
+            return !mUserMgr.hasUserRestriction(UserManager.DISALLOW_FUN);
+        }
+
         private boolean isDebugPolicyEnabled() {
             return !mUserMgr.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
         }
@@ -120,15 +124,12 @@
             return isEnabled(R.bool.feature_folders_in_search_results);
         }
 
-        private boolean isFunPolicyEnabled() {
-            return !mUserMgr.hasUserRestriction(UserManager.DISALLOW_FUN);
-        }
-
         @Override
         public boolean isGestureScaleEnabled() {
             return isEnabled(R.bool.feature_gesture_scale);
         }
 
+        @Override
         public boolean isInspectorEnabled() {
             return isEnabled(R.bool.feature_inspector);
         }
diff --git a/src/com/android/documentsui/base/Lookup.java b/src/com/android/documentsui/base/Lookup.java
index 7057bfc..34253bb 100644
--- a/src/com/android/documentsui/base/Lookup.java
+++ b/src/com/android/documentsui/base/Lookup.java
@@ -21,8 +21,11 @@
 
 /**
  * A {@link Function}-like interface for looking up information.
+ *
+ * @param K input type (the "key").
+ * @param V output type (the "value").
  */
 @FunctionalInterface
-public interface Lookup<T, R> {
-    @Nullable R lookup(T key);
+public interface Lookup<K, V> {
+    @Nullable V lookup(K key);
 }
diff --git a/src/com/android/documentsui/base/Shared.java b/src/com/android/documentsui/base/Shared.java
index d0ee2de..5d1cb90 100644
--- a/src/com/android/documentsui/base/Shared.java
+++ b/src/com/android/documentsui/base/Shared.java
@@ -34,13 +34,12 @@
 import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.util.Log;
+import android.view.View;
 import android.view.WindowManager;
 
 import com.android.documentsui.R;
 import com.android.documentsui.ui.MessageBuilder;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.List;
@@ -59,6 +58,12 @@
     public static final String ACTION_PICK_COPY_DESTINATION =
             "com.android.documentsui.PICK_COPY_DESTINATION";
 
+    // These values track values declared in MediaDocumentsProvider.
+    public static final String METADATA_KEY_AUDIO = "android.media.metadata.audio";
+    public static final String METADATA_KEY_VIDEO = "android.media.metadata.video";
+    public static final String METADATA_VIDEO_LATITUDE = "android.media.metadata.video:latitude";
+    public static final String METADATA_VIDEO_LONGITUTE = "android.media.metadata.video:longitude";
+
     /**
      * Extra boolean flag for {@link #ACTION_PICK_COPY_DESTINATION}, which
      * specifies if the destination directory needs to create new directory or not.
@@ -261,12 +266,37 @@
         }
     }
 
+    /**
+     * This method exists solely to smooth over the fact that two different types of
+     * views cannot be bound to the same id in different layouts. "What's this crazy-pants
+     * stuff?", you say? Here's an example:
+     *
+     * The main DocumentsUI view (aka "Files app") when running on a phone has a drop-down
+     * "breadcrumb" (file path representation) in both landscape and portrait orientation.
+     * Larger format devices, like a tablet, use a horizontal "Dir1 > Dir2 > Dir3" format
+     * breadcrumb in landscape layouts, but the regular drop-down breadcrumb in portrait
+     * mode.
+     *
+     * Our initial inclination was to give each of those views the same ID (as they both
+     * implement the same "Breadcrumb" interface). But at runtime, when rotating a device
+     * from one orientation to the other, deeeeeeep within the UI toolkit a exception
+     * would happen, because one view instance (drop-down) was being inflated in place of
+     * another (horizontal). I'm writing this code comment significantly after the face,
+     * so I don't recall all of the details, but it had to do with View type-checking the
+     * Parcelable state in onRestore, or something like that. Either way, this isn't
+     * allowed (my patch to fix this was rejected).
+     *
+     * To work around this we have this cute little method that accepts multiple
+     * resource IDs, and along w/ type inference finds our view, no matter which
+     * id it is wearing, and returns it.
+     */
+    @SuppressWarnings("TypeParameterUnusedInFormals")
     public static @Nullable <T> T findView(Activity activity, int... resources) {
         for (int id : resources) {
             @SuppressWarnings("unchecked")
-            T r = (T) activity.findViewById(id);
-            if (r != null) {
-                return r;
+            View view = activity.findViewById(id);
+            if (view != null) {
+                return (T) view;
             }
         }
         return null;
diff --git a/src/com/android/documentsui/base/State.java b/src/com/android/documentsui/base/State.java
index fbfd385..13a28ef 100644
--- a/src/com/android/documentsui/base/State.java
+++ b/src/com/android/documentsui/base/State.java
@@ -20,7 +20,6 @@
 import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.provider.DocumentsContract;
 import android.util.SparseArray;
 
 import com.android.documentsui.services.FileOperationService;
@@ -30,6 +29,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
@@ -139,7 +139,7 @@
     public String toString() {
         return "State{"
                 + "action=" + action
-                + ", acceptMimes=" + acceptMimes
+                + ", acceptMimes=" + Arrays.toString(acceptMimes)
                 + ", allowMultiple=" + allowMultiple
                 + ", localOnly=" + localOnly
                 + ", showDeviceStorageOption=" + showDeviceStorageOption
diff --git a/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java b/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java
index 6bf0d8b..2af3850 100644
--- a/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java
+++ b/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java
@@ -21,10 +21,10 @@
 import android.view.ViewGroup;
 
 import com.android.documentsui.Model;
+import com.android.documentsui.Model.Update;
 import com.android.documentsui.base.EventListener;
 import com.android.documentsui.dirlist.Message.HeaderMessage;
 import com.android.documentsui.dirlist.Message.InflateMessage;
-import com.android.documentsui.Model.Update;
 
 import java.util.List;
 
@@ -238,8 +238,8 @@
     }
 
     @Override
-    public List<String> getModelIds() {
-        return mDelegate.getModelIds();
+    public List<String> getStableIds() {
+        return mDelegate.getStableIds();
     }
 
     @Override
@@ -248,7 +248,7 @@
     }
 
     @Override
-    public String getModelId(int p) {
+    public String getStableId(int p) {
         if (p == mBreakPosition) {
             return null;
         }
@@ -261,12 +261,12 @@
             return null;
         }
 
-        return mDelegate.getModelId(toDelegatePosition(p));
+        return mDelegate.getStableId(toDelegatePosition(p));
     }
 
     @Override
-    public void onItemSelectionChanged(String id) {
-        mDelegate.onItemSelectionChanged(id);
+    public int getPosition(String id) {
+        return toViewPosition(mDelegate.getPosition(id));
     }
 
     // Listener we add to our delegate. This allows us to relay events published
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 9096f63..9814bfc 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -16,7 +16,6 @@
 
 package com.android.documentsui.dirlist;
 
-import static com.android.documentsui.base.DocumentInfo.getCursorInt;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 import static com.android.documentsui.base.Shared.DEBUG;
 import static com.android.documentsui.base.Shared.VERBOSE;
@@ -41,6 +40,7 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
@@ -50,7 +50,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.ContextMenu;
-import android.view.HapticFeedbackConstants;
+import android.view.GestureDetector;
 import android.view.LayoutInflater;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -63,7 +63,6 @@
 import com.android.documentsui.ActionModeController;
 import com.android.documentsui.BaseActivity;
 import com.android.documentsui.BaseActivity.RetainedState;
-import com.android.documentsui.DirectoryReloadLock;
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
@@ -76,10 +75,7 @@
 import com.android.documentsui.base.DocumentFilters;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
-import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.EventListener;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.base.Events.MotionInputEvent;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
@@ -90,11 +86,20 @@
 import com.android.documentsui.clipping.UrisSupplier;
 import com.android.documentsui.dirlist.AnimationView.AnimationType;
 import com.android.documentsui.picker.PickActivity;
-import com.android.documentsui.selection.BandController;
-import com.android.documentsui.selection.GestureSelector;
+import com.android.documentsui.selection.BandSelectionHelper;
+import com.android.documentsui.selection.ContentLock;
+import com.android.documentsui.selection.DefaultBandHost;
+import com.android.documentsui.selection.DefaultBandPredicate;
+import com.android.documentsui.selection.GestureRouter;
+import com.android.documentsui.selection.GestureSelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.MotionInputHandler;
+import com.android.documentsui.selection.MouseInputHandler;
 import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionMetadata;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+import com.android.documentsui.selection.TouchEventRouter;
+import com.android.documentsui.selection.TouchInputHandler;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
@@ -107,8 +112,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
-import javax.annotation.Nullable;
-
 /**
  * Display the documents inside a single directory.
  */
@@ -124,7 +127,7 @@
     public @interface RequestCode {}
     public static final int REQUEST_COPY_DESTINATION = 1;
 
-    private static final String TAG = "DirectoryFragment";
+    static final String TAG = "DirectoryFragment";
     private static final int LOADER_ID = 42;
 
     private static final int CACHE_EVICT_LIMIT = 100;
@@ -143,7 +146,7 @@
 
     @Injected
     @ContentScoped
-    private SelectionManager mSelectionMgr;
+    private SelectionHelper mSelectionMgr;
 
     @Injected
     @ContentScoped
@@ -157,14 +160,14 @@
     @ContentScoped
     private ActionModeController mActionModeController;
 
+    private ItemDetailsLookup mDetailsLookup;
     private SelectionMetadata mSelectionMetadata;
-    private UserInputHandler<InputEvent> mInputHandler;
-    private @Nullable BandController mBandController;
+    private KeyInputHandler mKeyListener;
+    private @Nullable BandSelectionHelper mBandSelector;
     private @Nullable DragHoverListener mDragHoverListener;
     private IconHelper mIconHelper;
     private SwipeRefreshLayout mRefreshLayout;
     private RecyclerView mRecView;
-
     private DocumentsAdapter mAdapter;
     private DocumentClipper mClipper;
     private GridLayoutManager mLayout;
@@ -176,9 +179,11 @@
     private View mProgressBar;
 
     private DirectoryState mLocalState;
-    private DirectoryReloadLock mReloadLock = new DirectoryReloadLock();
 
-    private Runnable mBandSelectStarted;
+    // Blocks loading/reloading of content while user is actively making selection.
+    private ContentLock mContentLock = new ContentLock();
+
+    private Runnable mBandSelectStartedCallback;
 
     // Note, we use !null to indicate that selection was restored (from rotation).
     // So don't fiddle with this field unless you've got the bigger picture in mind.
@@ -201,7 +206,7 @@
         final View view = inflater.inflate(R.layout.fragment_directory, container, false);
 
         mProgressBar = view.findViewById(R.id.progressbar);
-        assert(mProgressBar != null);
+        assert mProgressBar != null;
 
         mRecView = (RecyclerView) view.findViewById(R.id.dir_list);
         mRecView.setRecyclerListener(
@@ -261,8 +266,8 @@
         mModel.removeUpdateListener(mModelUpdateListener);
         mModel.removeUpdateListener(mAdapter.getModelUpdateListener());
 
-        if (mBandController != null) {
-            mBandController.removeBandSelectStartedListener(mBandSelectStarted);
+        if (mBandSelector != null) {
+            mBandSelector.removeOnBandStartedListener(mBandSelectStartedCallback);
         }
 
         super.onDestroyView();
@@ -316,77 +321,99 @@
         mModel.addUpdateListener(mAdapter.getModelUpdateListener());
         mModel.addUpdateListener(mModelUpdateListener);
 
-        mSelectionMgr = mInjector.getSelectionManager(mAdapter, this::canSetSelectionState);
+        SelectionPredicate selectionPredicate =
+                new DocsSelectionPredicate(mInjector.config, mState, mModel, mRecView);
+
+        mSelectionMgr = mInjector.getSelectionManager(mAdapter, selectionPredicate);
         mFocusManager = mInjector.getFocusManager(mRecView, mModel);
-        mActions = mInjector.getActionHandler(mReloadLock);
+        mActions = mInjector.getActionHandler(mContentLock);
 
         mRecView.setAccessibilityDelegateCompat(
                 new AccessibilityEventRouter(mRecView,
                         (View child) -> onAccessibilityClick(child)));
         mSelectionMetadata = new SelectionMetadata(mModel::getItem);
-        mSelectionMgr.addItemCallback(mSelectionMetadata);
+        mSelectionMgr.addObserver(mSelectionMetadata);
+        mDetailsLookup = new DocsItemDetailsLookup(mRecView);
 
-        GestureSelector gestureSel = GestureSelector.create(mSelectionMgr, mRecView, mReloadLock);
+        GestureSelectionHelper gestureHelper =
+                GestureSelectionHelper.create(mSelectionMgr, mRecView, mContentLock);
 
         if (mState.allowMultiple) {
-            mBandController = new BandController(
-                    mRecView,
+            mBandSelector = new BandSelectionHelper(
+                    new DefaultBandHost(mRecView, R.drawable.band_select_overlay),
                     mAdapter,
+                    new DocsStableIdProvider(mAdapter),
                     mSelectionMgr,
-                    mReloadLock,
-                    (int pos) -> {
-                        // The band selection model only operates on documents and directories.
-                        // Exclude other types of adapter items like whitespace and dividers.
-                        RecyclerView.ViewHolder vh = mRecView.findViewHolderForAdapterPosition(pos);
-                        return ModelBackedDocumentsAdapter.isContentType(vh.getItemViewType());
-                    });
-            mBandSelectStarted = mFocusManager::clearFocus;
-            mBandController.addBandSelectStartedListener(mBandSelectStarted);
+                    selectionPredicate,
+                    new DefaultBandPredicate(mDetailsLookup),
+                    mContentLock);
+
+            mBandSelectStartedCallback = mFocusManager::clearFocus;
+            mBandSelector.addOnBandStartedListener(mBandSelectStartedCallback);
         }
 
-        DragStartListener mDragStartListener = mInjector.config.dragAndDropEnabled()
+        DragStartListener dragStartListener = mInjector.config.dragAndDropEnabled()
                 ? DragStartListener.create(
                         mIconHelper,
                         mModel,
                         mSelectionMgr,
                         mSelectionMetadata,
                         mState,
+                        mDetailsLookup,
                         this::getModelId,
                         mRecView::findChildViewUnder,
                         DocumentsApplication.getDragAndDropManager(mActivity))
                 : DragStartListener.DUMMY;
 
-        EventHandler<InputEvent> gestureHandler = mState.allowMultiple
-                ? gestureSel::start
-                : EventHandler.createStub(false);
-
-        mInputHandler = new UserInputHandler<>(
+        // Construction of the input handlers is non trivial, so to keep logic clear,
+        // and code flexible, and DirectoryFragment small, the construction has been
+        // moved off into a separate class.
+        InputHandlers handlers = new InputHandlers(
                 mActions,
-                mFocusManager,
                 mSelectionMgr,
-                (MotionEvent t) -> MotionInputEvent.obtain(t, mRecView),
-                this::canSelect,
-                this::onContextMenuClick,
-                mDragStartListener::onTouchDragEvent,
-                gestureHandler,
-                () -> mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS));
-
-        new ListeningGestureDetector(
-                mInjector.features,
-                this.getContext(),
+                selectionPredicate,
+                mDetailsLookup,
+                mFocusManager,
                 mRecView,
-                mDragStartListener::onMouseDragEvent,
-                mRefreshLayout::setEnabled,
-                gestureSel,
-                mInputHandler,
-                mBandController,
-                this::scaleLayout);
+                mState);
+
+        MouseInputHandler mouseHandler =
+                handlers.createMouseHandler(this::onContextMenuClick);
+
+        TouchInputHandler touchHandler =
+                handlers.createTouchHandler(gestureHelper, dragStartListener);
+
+        GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>(touchHandler);
+        gestureRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mouseHandler);
+
+        // This little guy gets added to each Holder, so that we can be notified of key events
+        // on RecyclerView items.
+        mKeyListener = handlers.createKeyHandler();
+
+        if (Build.IS_DEBUGGABLE) {
+            new ScaleHelper(this.getContext(), mInjector.features, this::scaleLayout)
+                    .attach(mRecView);
+        }
+
+        new RefreshHelper(mRefreshLayout::setEnabled)
+                .attach(mRecView);
+
+        GestureDetector gestureDetector = new GestureDetector(getContext(), gestureRouter);
+
+        TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector, gestureHelper);
+
+        eventRouter.register(
+                MotionEvent.TOOL_TYPE_MOUSE,
+                new MouseDragEventInterceptor(
+                        mDetailsLookup, dragStartListener::onMouseDragEvent, mBandSelector));
+
+        mRecView.addOnItemTouchListener(eventRouter);
 
         mActionModeController = mInjector.getActionModeController(
                 mSelectionMetadata,
                 this::handleMenuItemClick);
 
-        mSelectionMgr.addCallback(mActionModeController);
+        mSelectionMgr.addObserver(mActionModeController);
 
         final ActivityManager am = (ActivityManager) mActivity.getSystemService(
                 Context.ACTIVITY_SERVICE);
@@ -428,7 +455,8 @@
     }
 
     public void retainState(RetainedState state) {
-        state.selection = mSelectionMgr.getSelection(new Selection());
+        state.selection = new Selection();
+        mSelectionMgr.copySelection(state.selection);
     }
 
     @Override
@@ -452,7 +480,8 @@
             // at the same time.
             mInjector.menuManager.inflateContextMenuForContainer(menu, inflater);
         } else {
-            mInjector.menuManager.inflateContextMenuForDocs(menu, inflater, mSelectionMetadata);
+            mInjector.menuManager.inflateContextMenuForDocs(
+                    menu, inflater, mSelectionMetadata);
         }
     }
 
@@ -482,23 +511,21 @@
                 jobId);
     }
 
-    protected boolean onContextMenuClick(InputEvent e) {
-        final View v;
-        final float x, y;
-        if (e.isOverModelItem()) {
-            DocumentHolder doc = (DocumentHolder) e.getDocumentDetails();
+    // TODO: Move to UserInputHander.
+    protected boolean onContextMenuClick(MotionEvent e) {
 
-            v = doc.itemView;
-            x = e.getX() - v.getLeft();
-            y = e.getY() - v.getTop();
-        } else {
-            v = mRecView;
-            x = e.getX();
-            y = e.getY();
+        if (mDetailsLookup.overStableItem(e)) {
+            View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
+            ViewHolder holder = mRecView.getChildViewHolder(childView);
+
+            View view = holder.itemView;
+            float x = e.getX() - view.getLeft();
+            float y = e.getY() - view.getTop();
+            mInjector.menuManager.showContextMenu(this, view, x, y);
+            return true;
         }
 
-        mInjector.menuManager.showContextMenu(this, v, x, y);
-
+        mInjector.menuManager.showContextMenu(this, mRecView, e.getX(), e.getY());
         return true;
     }
 
@@ -526,8 +553,8 @@
         int pad = getDirectoryPadding(mode);
         mRecView.setPadding(pad, pad, pad, pad);
         mRecView.requestLayout();
-        if (mBandController != null) {
-            mBandController.handleLayoutChanged();
+        if (mBandSelector != null) {
+            mBandSelector.reset();
         }
         mIconHelper.setViewMode(mode);
     }
@@ -537,7 +564,8 @@
      * @param mode The new view mode.
      */
     private void scaleLayout(float scale) {
-        assert(Build.IS_DEBUGGABLE);
+        assert Build.IS_DEBUGGABLE;
+
         if (VERBOSE) Log.v(
                 TAG, "Handling scale event: " + scale + ", existing scale: " + mLiveScale);
 
@@ -606,7 +634,8 @@
     }
 
     private boolean handleMenuItemClick(MenuItem item) {
-        Selection selection = mSelectionMgr.getSelection(new Selection());
+        Selection selection = new Selection();
+        mSelectionMgr.copySelection(selection);
 
         switch (item.getItemId()) {
             case R.id.action_menu_open:
@@ -669,11 +698,15 @@
                 transferDocuments(selection, null, FileOperationService.OPERATION_MOVE);
                 return true;
 
-            case R.id.action_menu_inspector:
+            case R.id.action_menu_inspect:
+            case R.id.dir_menu_inspect:
                 mActionModeController.finishActionMode();
-                assert(selection.size() == 1);
-                DocumentInfo doc = mModel.getDocuments(selection).get(0);
-                mActions.showInspector(doc);
+                assert selection.size() <= 1;
+                DocumentInfo doc = selection.isEmpty()
+                        ? mActivity.getCurrentDirectory()
+                        : mModel.getDocuments(selection).get(0);
+
+                        mActions.showInspector(doc);
                 return true;
 
             case R.id.dir_menu_cut_to_clipboard:
@@ -720,8 +753,8 @@
     }
 
     private boolean onAccessibilityClick(View child) {
-        DocumentDetails doc = getDocumentHolder(child);
-        mActions.openDocument(doc, ActionHandler.VIEW_TYPE_PREVIEW,
+        DocumentHolder holder = getDocumentHolder(child);
+        mActions.openItem(holder.getItemDetails(), ActionHandler.VIEW_TYPE_PREVIEW,
                 ActionHandler.VIEW_TYPE_REGULAR);
         return true;
     }
@@ -749,7 +782,7 @@
     private void showChooserForDoc(final Selection selected) {
         Metrics.logUserAction(getContext(), Metrics.USER_ACTION_OPEN);
 
-        assert(selected.size() == 1);
+        assert selected.size() == 1;
         DocumentInfo doc =
                 DocumentInfo.fromDirectoryCursor(mModel.getItem(selected.iterator().next()));
         mActions.showChooserForDoc(doc);
@@ -780,7 +813,7 @@
             throw new RuntimeException("Failed to create uri supplier.", e);
         }
 
-        final DocumentInfo parent = mState.stack.peek();
+        final DocumentInfo parent = mActivity.getCurrentDirectory();
         final FileOperation operation = new FileOperation.Builder()
                 .withOpType(mode)
                 .withSrcParent(parent == null ? null : parent.derivedUri)
@@ -871,7 +904,7 @@
 
         // Batch renaming not supported
         // Rename option is only available in menu when 1 document selected
-        assert(selected.size() == 1);
+        assert selected.size() == 1;
 
         // Model must be accessed in UI thread, since underlying cursor is not threadsafe.
         List<DocumentInfo> docs = mModel.getDocuments(selected);
@@ -882,10 +915,6 @@
         return mModel;
     }
 
-    private boolean isDocumentEnabled(String mimeType, int flags) {
-        return mInjector.config.isDocumentEnabled(mimeType, flags, mState);
-    }
-
     /**
      * Paste selection files from the primary clip into the current window.
      */
@@ -937,7 +966,7 @@
         }
 
         if (v == mRecView) {
-            return mState.stack.peek();
+            return mActivity.getCurrentDirectory();
         }
 
         return null;
@@ -968,31 +997,6 @@
         return null;
     }
 
-    // TODO: Move to activities when Model becomes activity level object.
-    private boolean canSelect(DocumentDetails doc) {
-        return canSetSelectionState(doc.getModelId(), true);
-    }
-
-    // TODO: Move to activities when Model becomes activity level object.
-    private boolean canSetSelectionState(String modelId, boolean nextState) {
-        if (nextState) {
-            // Check if an item can be selected
-            final Cursor cursor = mModel.getItem(modelId);
-            if (cursor == null) {
-                Log.w(TAG, "Couldn't obtain cursor for modelId: " + modelId);
-                return false;
-            }
-
-            final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
-            final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
-            return mInjector.config.canSelectType(docMimeType, docFlags, mState);
-        } else {
-        final DocumentInfo parent = mState.stack.peek();
-            // Right now all selected items can be deselected.
-            return true;
-        }
-    }
-
     public static void showDirectory(
             FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
         if (DEBUG) Log.d(TAG, "Showing directory: " + DocumentInfo.debugString(doc));
@@ -1056,7 +1060,7 @@
             cache.removeUri(mModel.getItemUri(ids[i]));
         }
 
-        final DocumentInfo doc = mState.stack.peek();
+        final DocumentInfo doc = mActivity.getCurrentDirectory();
         mActions.refreshDocument(doc, (boolean refreshSupported) -> {
             if (refreshSupported) {
                 mRefreshLayout.setRefreshing(false);
@@ -1151,7 +1155,7 @@
 
         @Override
         public boolean isSelected(String id) {
-            return mSelectionMgr.getSelection().contains(id);
+            return mSelectionMgr.isSelected(id);
         }
 
         @Override
@@ -1161,7 +1165,7 @@
 
         @Override
         public void initDocumentHolder(DocumentHolder holder) {
-            holder.addKeyEventListener(mInputHandler);
+            holder.addKeyEventListener(mKeyListener);
             holder.itemView.setOnFocusChangeListener(mFocusManager);
         }
 
diff --git a/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java b/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java
new file mode 100644
index 0000000..78c3097
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.documentsui.selection.ItemDetailsLookup;
+
+/**
+ * Access to details of an item associated with a {@link MotionEvent} instance.
+ */
+final class DocsItemDetailsLookup extends ItemDetailsLookup {
+
+    private final RecyclerView mRecView;
+
+    public DocsItemDetailsLookup(RecyclerView view) {
+        mRecView = view;
+    }
+
+    @Override
+    public boolean overItem(MotionEvent e) {
+        return getItemPosition(e) != RecyclerView.NO_POSITION;
+    }
+
+    @Override
+    public boolean overStableItem(MotionEvent e) {
+        return overItem(e) && getItemDetails(e).hasStableId();
+    }
+
+    @Override
+    public boolean inItemDragRegion(MotionEvent e) {
+        return overItem(e) && getItemDetails(e).inDragRegion(e);
+    }
+
+    @Override
+    public boolean inItemSelectRegion(MotionEvent e) {
+        return overItem(e) && getItemDetails(e).inSelectionHotspot(e);
+    }
+
+    @Override
+    public int getItemPosition(MotionEvent e) {
+        View child = mRecView.findChildViewUnder(e.getX(), e.getY());
+        return (child != null)
+                ? mRecView.getChildAdapterPosition(child)
+                : RecyclerView.NO_POSITION;
+    }
+
+    @Override
+    public ItemDetails getItemDetails(MotionEvent e) {
+        @Nullable DocumentHolder holder = getDocumentHolder(e);
+        return holder == null ? null : holder.getItemDetails();
+    }
+
+    private @Nullable DocumentHolder getDocumentHolder(MotionEvent e) {
+        View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
+        if (childView != null) {
+            ViewHolder holder = mRecView.getChildViewHolder(childView);
+            if (holder instanceof DocumentHolder) {
+                return (DocumentHolder) holder;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java b/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java
new file mode 100644
index 0000000..679bd9f
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+import static com.android.documentsui.base.DocumentInfo.getCursorInt;
+import static com.android.documentsui.base.DocumentInfo.getCursorString;
+
+import android.database.Cursor;
+import android.provider.DocumentsContract.Document;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+
+import com.android.documentsui.ActivityConfig;
+import com.android.documentsui.Model;
+import com.android.documentsui.base.State;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+/**
+ * Class embodying the logic as to whether an item (specified by id or position)
+ * can be selected (or not).
+ */
+final class DocsSelectionPredicate extends SelectionPredicate {
+
+    private ActivityConfig mConfig;
+    private Model mModel;
+    private RecyclerView mRecView;
+    private State mState;
+
+    DocsSelectionPredicate(
+            ActivityConfig config, State state, Model model, RecyclerView recView) {
+
+        checkArgument(config != null);
+        checkArgument(state != null);
+        checkArgument(model != null);
+        checkArgument(recView != null);
+
+        mConfig = config;
+        mState = state;
+        mModel = model;
+        mRecView = recView;
+
+    }
+
+    @Override
+    public boolean canSetStateForId(String id, boolean nextState) {
+        if (nextState) {
+            // Check if an item can be selected
+            final Cursor cursor = mModel.getItem(id);
+            if (cursor == null) {
+                Log.w(DirectoryFragment.TAG, "Couldn't obtain cursor for id: " + id);
+                return false;
+            }
+
+            final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+            final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+            return mConfig.canSelectType(docMimeType, docFlags, mState);
+        }
+
+        // Right now all selected items can be deselected.
+        return true;
+    }
+
+    @Override
+    public boolean canSetStateAtPosition(int position, boolean nextState) {
+        // This method features a nextState arg for symmetry.
+        // But, there are no current uses for checking un-selecting state by position.
+        // So rather than have some unsuspecting client think canSetState(int, false)
+        // will ever do anything. Let's just be grumpy about it.
+        assert nextState == true;
+
+        // NOTE: Given that we have logic in some places disallowing selection,
+        // it may be a bug that Band and Gesture based selections don't
+        // also verify something can be unselected.
+
+        // The band selection model only operates on documents and directories.
+        // Exclude other types of adapter items like whitespace and dividers.
+        RecyclerView.ViewHolder vh = mRecView.findViewHolderForAdapterPosition(position);
+        return ModelBackedDocumentsAdapter.isContentType(vh.getItemViewType());
+    }
+
+    @Override
+    public boolean canSelectMultiple() {
+        return mState.allowMultiple;
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/DocsStableIdProvider.java b/src/com/android/documentsui/dirlist/DocsStableIdProvider.java
new file mode 100644
index 0000000..889b82a
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/DocsStableIdProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+
+import java.util.List;
+
+/**
+ * Provides RecyclerView selection code access to stable ids backed
+ * by DocumentsAdapter.
+ */
+public final class DocsStableIdProvider extends StableIdProvider {
+
+    private final DocumentsAdapter mAdapter;
+
+    public DocsStableIdProvider(DocumentsAdapter adapter) {
+        checkArgument(adapter != null);
+        mAdapter = adapter;
+    }
+
+    @Override
+    public String getStableId(int position) {
+        return mAdapter.getStableId(position);
+    }
+
+    @Override
+    public int getPosition(String id) {
+        return mAdapter.getPosition(id);
+    }
+
+    @Override
+    public List<String> getStableIds() {
+        return mAdapter.getStableIds();
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/DocumentDetails.java b/src/com/android/documentsui/dirlist/DocumentDetails.java
deleted file mode 100644
index a321e64..0000000
--- a/src/com/android/documentsui/dirlist/DocumentDetails.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import com.android.documentsui.base.Events.InputEvent;
-
-/**
- * Interface providing a loose coupling between DocumentHolder.
- */
-public interface DocumentDetails {
-    boolean hasModelId();
-    String getModelId();
-    int getAdapterPosition();
-    boolean isInSelectionHotspot(InputEvent event);
-    boolean isInDragHotspot(InputEvent event);
-
-    /**
-     * Given a mouse input event, this method does a hit-test to see if the cursor
-     * is currently positioned over the document icon or checkbox in the case where
-     * the document is selected.
-     */
-    boolean isOverDocIcon(InputEvent event);
-}
diff --git a/src/com/android/documentsui/dirlist/DocumentHolder.java b/src/com/android/documentsui/dirlist/DocumentHolder.java
index d7f7ce5..e1345f2 100644
--- a/src/com/android/documentsui/dirlist/DocumentHolder.java
+++ b/src/com/android/documentsui/dirlist/DocumentHolder.java
@@ -16,33 +16,24 @@
 
 package com.android.documentsui.dirlist;
 
-import android.annotation.ColorInt;
 import android.content.Context;
 import android.database.Cursor;
-import android.graphics.Rect;
-import android.os.Build;
 import android.support.v7.widget.RecyclerView;
-import android.text.TextUtils;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 
-import com.android.documentsui.R;
-import com.android.documentsui.base.DebugFlags;
-import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Events.InputEvent;
 import com.android.documentsui.base.Shared;
-import com.android.documentsui.ui.DocumentDebugInfo;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 import javax.annotation.Nullable;
 
 public abstract class DocumentHolder
-        extends RecyclerView.ViewHolder
-        implements View.OnKeyListener, DocumentDetails {
+        extends RecyclerView.ViewHolder implements View.OnKeyListener {
 
     static final float DISABLED_ALPHA = 0.3f;
 
@@ -50,12 +41,11 @@
 
     protected @Nullable String mModelId;
 
-    private final View mSelectionHotspot;
-    private @Nullable DocumentDebugInfo mDebugInfo;
-
     // See #addKeyEventListener for details on the need for this field.
     private KeyboardEventListener mKeyEventListener;
 
+    private final DocumentItemDetails mDetails;
+
     public DocumentHolder(Context context, ViewGroup parent, int layout) {
         this(context, inflateLayout(context, parent, layout));
     }
@@ -66,8 +56,7 @@
         itemView.setOnKeyListener(this);
 
         mContext = context;
-
-        mSelectionHotspot = itemView.findViewById(R.id.icon_check);
+        mDetails = new DocumentItemDetails();
     }
 
     /**
@@ -78,12 +67,6 @@
      */
     public abstract void bind(Cursor cursor, String modelId);
 
-    @Override
-    public boolean hasModelId() {
-        return !TextUtils.isEmpty(mModelId);
-    }
-
-    @Override
     public String getModelId() {
         return mModelId;
     }
@@ -111,7 +94,7 @@
     @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         assert(mKeyEventListener != null);
-        return mKeyEventListener.onKey(this,  keyCode,  event);
+        return mKeyEventListener.onKey(getItemDetails(),  keyCode,  event);
     }
 
     /**
@@ -127,28 +110,18 @@
         mKeyEventListener = listener;
     }
 
-    @Override
-    public boolean isInSelectionHotspot(InputEvent event) {
-        // Do everything in global coordinates - it makes things simpler.
-        int[] coords = new int[2];
-        mSelectionHotspot.getLocationOnScreen(coords);
-        Rect rect = new Rect(coords[0], coords[1], coords[0] + mSelectionHotspot.getWidth(),
-                coords[1] + mSelectionHotspot.getHeight());
-
-        // If the tap occurred within the icon rect, consider it a selection.
-        return rect.contains((int) event.getRawX(), (int) event.getRawY());
-    }
-
-    @Override
-    public boolean isInDragHotspot(InputEvent event) {
+    public boolean inDragRegion(MotionEvent event) {
         return false;
     }
 
-    @Override
-    public boolean isOverDocIcon(InputEvent event) {
+    public boolean inSelectRegion(MotionEvent event) {
         return false;
     }
 
+    public ItemDetails getItemDetails() {
+        return mDetails;
+    }
+
     static void setEnabledRecursive(View itemView, boolean enabled) {
         if (itemView == null || itemView.isEnabled() == enabled) {
             return;
@@ -163,6 +136,7 @@
         }
     }
 
+    @SuppressWarnings("TypeParameterUnusedInFormals")
     private static <V extends View> V inflateLayout(Context context, ViewGroup parent, int layout) {
         final LayoutInflater inflater = LayoutInflater.from(context);
         return (V) inflater.inflate(layout, parent, false);
@@ -172,20 +146,31 @@
         return view.animate().setDuration(Shared.CHECK_ANIMATION_DURATION).alpha(alpha);
     }
 
-    /**
-     * Implement this in order to be able to respond to events coming from DocumentHolders.
-     * TODO: Make this bubble up logic events rather than having imperative commands.
-     */
-    interface KeyboardEventListener {
+    private final class DocumentItemDetails extends ItemDetails {
 
-        /**
-         * Handles key events on the document holder.
-         *
-         * @param doc The target DocumentHolder.
-         * @param keyCode Key code for the event.
-         * @param event KeyEvent for the event.
-         * @return Whether the event was handled.
-         */
-        public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event);
+        @Override
+        public int getPosition() {
+            return DocumentHolder.this.getAdapterPosition();
+        }
+
+        @Override
+        public String getStableId() {
+            return DocumentHolder.this.getModelId();
+        }
+
+        @Override
+        public int getItemViewType() {
+            return DocumentHolder.this.getItemViewType();
+        }
+
+        @Override
+        public boolean inDragRegion(MotionEvent e) {
+            return DocumentHolder.this.inDragRegion(e);
+        }
+
+        @Override
+        public boolean inSelectionHotspot(MotionEvent e) {
+            return DocumentHolder.this.inSelectRegion(e);
+        }
     }
 }
diff --git a/src/com/android/documentsui/dirlist/DocumentsAdapter.java b/src/com/android/documentsui/dirlist/DocumentsAdapter.java
index 82f2524..f940814 100644
--- a/src/com/android/documentsui/dirlist/DocumentsAdapter.java
+++ b/src/com/android/documentsui/dirlist/DocumentsAdapter.java
@@ -33,7 +33,7 @@
 import java.util.List;
 
 /**
- * DocumentsAdapter provides glue between a directory Model, and RecylcerView. We've
+ * DocumentsAdapter provides glue between a directory Model, and RecyclerView. We've
  * abstracted this a bit in order to decompose some specialized support
  * for adding dummy layout objects (@see SectionBreakDocumentsAdapter). Handling of the
  * dummy layout objects was error prone when interspersed with the core mode / adapter code.
@@ -41,8 +41,7 @@
  * @see ModelBackedDocumentsAdapter
  * @see DirectoryAddonsAdapter
  */
-public abstract class DocumentsAdapter
-        extends RecyclerView.Adapter<DocumentHolder> {
+public abstract class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder> {
     // Item types used by ModelBackedDocumentsAdapter
     public static final int ITEM_TYPE_DOCUMENT = 1;
     public static final int ITEM_TYPE_DIRECTORY = 2;
@@ -51,28 +50,10 @@
     public static final int ITEM_TYPE_HEADER_MESSAGE = Integer.MAX_VALUE - 1;
     public static final int ITEM_TYPE_INFLATED_MESSAGE = Integer.MAX_VALUE - 2;
 
-    // Payloads for notifyItemChange to distinguish between selection and other events.
-    static final String SELECTION_CHANGED_MARKER = "Selection-Changed";
-
-    /**
-     * Returns a list of model IDs of items currently in the adapter.
-     *
-     * @return A list of Model IDs.
-     */
-    public abstract List<String> getModelIds();
-
     public abstract int getAdapterPosition(String modelId);
-
-    /**
-     * Triggers item-change notifications by stable ID (as opposed to position).
-     * Passing an unrecognized ID will result in a warning in logcat, but no other error.
-     */
-    public abstract void onItemSelectionChanged(String id);
-
-    /**
-     * @return The model ID of the item at the given adapter position.
-     */
-    public abstract String getModelId(int position);
+    public abstract String getStableId(int adapterPosition);
+    public abstract List<String> getStableIds();
+    public abstract int getPosition(String id);
 
     abstract EventListener<Model.Update> getModelUpdateListener();
 
@@ -85,17 +66,13 @@
         throw new UnsupportedOperationException();
     }
 
-    public boolean hasModelIds() {
-        return !getModelIds().isEmpty();
-    }
-
     static boolean isDirectory(Cursor cursor) {
         final String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
         return Document.MIME_TYPE_DIR.equals(mimeType);
     }
 
     boolean isDirectory(Model model, int position) {
-        String modelId = getModelIds().get(position);
+        String modelId = getStableIds().get(position);
         Cursor cursor = model.getItem(modelId);
         return isDirectory(cursor);
     }
diff --git a/src/com/android/documentsui/dirlist/DragHost.java b/src/com/android/documentsui/dirlist/DragHost.java
index 987303a..787431c 100644
--- a/src/com/android/documentsui/dirlist/DragHost.java
+++ b/src/com/android/documentsui/dirlist/DragHost.java
@@ -32,7 +32,7 @@
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.State;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.ui.DialogController;
 
 import java.util.function.Predicate;
@@ -45,7 +45,7 @@
     private static final String TAG = "dirlist.DragHost";
 
     private final T mActivity;
-    private final SelectionManager mSelectionMgr;
+    private final SelectionHelper mSelectionMgr;
     private final ActionHandler mActions;
     private final State mState;
     private final DialogController mDialogs;
@@ -56,7 +56,7 @@
     DragHost(
             T activity,
             DragAndDropManager dragAndDropManager,
-            SelectionManager selectionMgr,
+            SelectionHelper selectionMgr,
             ActionHandler actions,
             State state,
             DialogController dialogs,
diff --git a/src/com/android/documentsui/dirlist/DragHoverListener.java b/src/com/android/documentsui/dirlist/DragHoverListener.java
index 63d93ec..7babe26 100644
--- a/src/com/android/documentsui/dirlist/DragHoverListener.java
+++ b/src/com/android/documentsui/dirlist/DragHoverListener.java
@@ -24,9 +24,9 @@
 
 import com.android.documentsui.ItemDragListener;
 import com.android.documentsui.ItemDragListener.DragHost;
-import com.android.documentsui.ui.ViewAutoScroller;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollActionDelegate;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollDistanceDelegate;
+import com.android.documentsui.selection.ViewAutoScroller;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
 
 import java.util.function.BooleanSupplier;
 import java.util.function.IntSupplier;
@@ -66,14 +66,15 @@
             Predicate<View> isScrollView,
             BooleanSupplier scrollUpSupplier,
             BooleanSupplier scrollDownSupplier,
-            ViewAutoScroller.ScrollActionDelegate actionDelegate) {
+            ViewAutoScroller.ScrollerCallbacks scrollCallbacks) {
+
         mDragHandler = dragHandler;
         mHeight = heightSupplier;
         mIsScrollView = isScrollView;
         mCanScrollUp = scrollUpSupplier;
         mCanScrollDown = scrollDownSupplier;
 
-        ScrollDistanceDelegate distanceDelegate = new ScrollDistanceDelegate() {
+        ScrollHost scrollHost = new ScrollHost() {
             @Override
             public Point getCurrentPosition() {
                 return mCurrentPosition;
@@ -90,13 +91,14 @@
             }
         };
 
-        mDragScroller = new ViewAutoScroller(distanceDelegate, actionDelegate);
+        mDragScroller = new ViewAutoScroller(scrollHost, scrollCallbacks);
     }
 
     static DragHoverListener create(
             ItemDragListener<? extends DragHost> dragHandler,
             View scrollView) {
-        ScrollActionDelegate actionDelegate = new ScrollActionDelegate() {
+
+        ScrollerCallbacks scrollCallbacks = new ScrollerCallbacks() {
             @Override
             public void scrollBy(int dy) {
                 scrollView.scrollBy(0, dy);
@@ -113,13 +115,15 @@
                 scrollView.removeCallbacks(r);
             }
         };
+
         DragHoverListener listener = new DragHoverListener(
                 dragHandler,
                 scrollView::getHeight,
                 (view) -> (scrollView == view),
                 () -> scrollView.canScrollVertically(-1),
                 () -> scrollView.canScrollVertically(1),
-                actionDelegate);
+                scrollCallbacks);
+
         return listener;
     }
 
diff --git a/src/com/android/documentsui/dirlist/DragStartListener.java b/src/com/android/documentsui/dirlist/DragStartListener.java
index 1651603..9d03925 100644
--- a/src/com/android/documentsui/dirlist/DragStartListener.java
+++ b/src/com/android/documentsui/dirlist/DragStartListener.java
@@ -17,10 +17,12 @@
 package com.android.documentsui.dirlist;
 
 import static com.android.documentsui.base.Shared.DEBUG;
+import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.net.Uri;
 import android.support.annotation.VisibleForTesting;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.View;
 
 import com.android.documentsui.DragAndDropManager;
@@ -28,10 +30,11 @@
 import com.android.documentsui.Model;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Events;
-import com.android.documentsui.base.Events.InputEvent;
 import com.android.documentsui.base.State;
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.MutableSelection;
 import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.SelectionHelper;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -42,44 +45,47 @@
 /**
  * Listens for potential "drag-like" events and kick-start dragging as needed. Also allows external
  * direct call to {@code #startDrag(RecyclerView, View)} if explicit start is needed, such as long-
- * pressing on an item via touch. (e.g. {@link UserInputHandler#onLongPress(InputEvent)} via touch.)
+ * pressing on an item via touch. (e.g. InputEventDispatcher#onLongPress(MotionEvent)} via touch.
  */
 interface DragStartListener {
 
     static final DragStartListener DUMMY = new DragStartListener() {
         @Override
-        public boolean onMouseDragEvent(InputEvent event) {
+        public boolean onMouseDragEvent(MotionEvent event) {
             return false;
         }
         @Override
-        public boolean onTouchDragEvent(InputEvent event) {
+        public boolean onTouchDragEvent(MotionEvent event) {
             return false;
         }
     };
 
-    boolean onMouseDragEvent(InputEvent event);
-    boolean onTouchDragEvent(InputEvent event);
+    boolean onMouseDragEvent(MotionEvent event);
+    boolean onTouchDragEvent(MotionEvent event);
 
     @VisibleForTesting
-    class ActiveListener implements DragStartListener {
+    class RuntimeDragStartListener implements DragStartListener {
 
         private static String TAG = "DragStartListener";
 
         private final IconHelper mIconHelper;
         private final State mState;
-        private final SelectionManager mSelectionMgr;
+        private final ItemDetailsLookup mDetailsLookup;
+        private final SelectionHelper mSelectionMgr;
         private final SelectionDetails mSelectionDetails;
         private final ViewFinder mViewFinder;
         private final Function<View, String> mIdFinder;
         private final Function<Selection, List<DocumentInfo>> mDocsConverter;
         private final DragAndDropManager mDragAndDropManager;
 
+
         // use DragStartListener.create
         @VisibleForTesting
-        public ActiveListener(
+        public RuntimeDragStartListener(
                 IconHelper iconHelper,
                 State state,
-                SelectionManager selectionMgr,
+                ItemDetailsLookup detailsLookup,
+                SelectionHelper selectionMgr,
                 SelectionDetails selectionDetails,
                 ViewFinder viewFinder,
                 Function<View, String> idFinder,
@@ -88,6 +94,7 @@
 
             mIconHelper = iconHelper;
             mState = state;
+            mDetailsLookup = detailsLookup;
             mSelectionMgr = selectionMgr;
             mSelectionDetails = selectionDetails;
             mViewFinder = viewFinder;
@@ -97,20 +104,22 @@
         }
 
         @Override
-        public final boolean onMouseDragEvent(InputEvent event) {
-            assert(Events.isMouseDragEvent(event));
+        public final boolean onMouseDragEvent(MotionEvent event) {
+            checkArgument(Events.isMouseDragEvent(event));
+            checkArgument(mDetailsLookup.inItemDragRegion(event));
+
             return startDrag(mViewFinder.findView(event.getX(), event.getY()), event);
         }
 
         @Override
-        public final boolean onTouchDragEvent(InputEvent event) {
+        public final boolean onTouchDragEvent(MotionEvent event) {
             return startDrag(mViewFinder.findView(event.getX(), event.getY()), event);
         }
 
         /**
          * May be called externally when drag is initiated from other event handling code.
          */
-        private boolean startDrag(@Nullable View view, InputEvent event) {
+        private boolean startDrag(@Nullable View view, MotionEvent event) {
 
             if (view == null) {
                 if (DEBUG) Log.d(TAG, "Ignoring drag event, null view.");
@@ -145,21 +154,22 @@
         }
 
         /**
-         * Given the InputEvent (for CTRL case) and modelId of the view associated with the
+         * Given the MotionEvent (for CTRL case) and modelId of the view associated with the
          * coordinates of the event, return a valid selection for drag and drop operation
          */
         @VisibleForTesting
-        Selection getSelectionToBeCopied(String modelId, InputEvent event) {
-            Selection selection = new Selection();
+        MutableSelection getSelectionToBeCopied(String modelId, MotionEvent event) {
+            MutableSelection selection = new MutableSelection();
             // If CTRL-key is held down and there's other existing selection, add item to
             // selection (if not already selected)
-            if (event.isCtrlKeyDown() && !mSelectionMgr.getSelection().contains(modelId)
-                    && mSelectionMgr.hasSelection()) {
-                mSelectionMgr.toggleSelection(modelId);
+            if (Events.isCtrlKeyPressed(event)
+                    && mSelectionMgr.hasSelection()
+                    && !mSelectionMgr.isSelected(modelId)) {
+                mSelectionMgr.select(modelId);
             }
 
-            if (mSelectionMgr.getSelection().contains(modelId)) {
-                mSelectionMgr.getSelection(selection);
+            if (mSelectionMgr.isSelected(modelId)) {
+                mSelectionMgr.copySelection(selection);
             } else {
                 selection.add(modelId);
                 mSelectionMgr.clearSelection();
@@ -171,16 +181,18 @@
     static DragStartListener create(
             IconHelper iconHelper,
             Model model,
-            SelectionManager selectionMgr,
+            SelectionHelper selectionMgr,
             SelectionDetails selectionDetails,
             State state,
+            ItemDetailsLookup detailsLookup,
             Function<View, String> idFinder,
             ViewFinder viewFinder,
             DragAndDropManager dragAndDropManager) {
 
-        return new ActiveListener(
+        return new RuntimeDragStartListener(
                 iconHelper,
                 state,
+                detailsLookup,
                 selectionMgr,
                 selectionDetails,
                 viewFinder,
diff --git a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
index cf793db..5d02957 100644
--- a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
+++ b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
@@ -22,15 +22,12 @@
 import android.database.Cursor;
 import android.graphics.Rect;
 import android.provider.DocumentsContract.Document;
+import android.view.MotionEvent;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.documentsui.R;
-import com.android.documentsui.base.DebugFlags;
-import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.roots.RootCursorWrapper;
 
 final class GridDirectoryHolder extends DocumentHolder {
 
@@ -62,13 +59,13 @@
     }
 
     @Override
-    public boolean isInDragHotspot(InputEvent event) {
+    public boolean inDragRegion(MotionEvent event) {
         // Entire grid box should be draggable
         return true;
     }
 
     @Override
-    public boolean isOverDocIcon(InputEvent event) {
+    public boolean inSelectRegion(MotionEvent event) {
         Rect iconRect = new Rect();
         mIconMime.getGlobalVisibleRect(iconRect);
 
diff --git a/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/src/com/android/documentsui/dirlist/GridDocumentHolder.java
index e96d09f..95be1b9 100644
--- a/src/com/android/documentsui/dirlist/GridDocumentHolder.java
+++ b/src/com/android/documentsui/dirlist/GridDocumentHolder.java
@@ -25,15 +25,14 @@
 import android.graphics.Rect;
 import android.provider.DocumentsContract.Document;
 import android.text.format.Formatter;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.documentsui.R;
-import com.android.documentsui.base.DebugFlags;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Events.InputEvent;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.roots.RootCursorWrapper;
 
@@ -112,13 +111,13 @@
     }
 
     @Override
-    public boolean isInDragHotspot(InputEvent event) {
+    public boolean inDragRegion(MotionEvent event) {
      // Entire grid box should be draggable
         return true;
     }
 
     @Override
-    public boolean isOverDocIcon(InputEvent event) {
+    public boolean inSelectRegion(MotionEvent event) {
         Rect iconRect = new Rect();
         mIconMimeSm.getGlobalVisibleRect(iconRect);
 
diff --git a/src/com/android/documentsui/dirlist/InputHandlers.java b/src/com/android/documentsui/dirlist/InputHandlers.java
new file mode 100644
index 0000000..43143d4
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/InputHandlers.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.base.EventHandler;
+import com.android.documentsui.base.State;
+import com.android.documentsui.selection.GestureSelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.MouseInputHandler;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.TouchInputHandler;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+/**
+ * Helper class dedicated to building gesture input handlers. The construction
+ * of the various input handlers is non trivial. To keep logic clear,
+ * code flexible, and DirectoryFragment small(er), the construction has been
+ * isolated here in a separate class.
+ */
+final class InputHandlers {
+
+    private ActionHandler mActions;
+    private SelectionHelper mSelectionHelper;
+    private SelectionPredicate mSelectionPredicate;
+    private ItemDetailsLookup mDetailsLookup;
+    private FocusHandler mFocusHandler;
+    private RecyclerView mRecView;
+    private State mState;
+
+    InputHandlers(
+            ActionHandler actions,
+            SelectionHelper selectionHelper,
+            SelectionPredicate selectionPredicate,
+            ItemDetailsLookup detailsLookup,
+            FocusHandler focusHandler,
+            RecyclerView recView,
+            State state) {
+
+        checkArgument(actions != null);
+        checkArgument(selectionHelper != null);
+        checkArgument(selectionPredicate != null);
+        checkArgument(detailsLookup != null);
+        checkArgument(focusHandler != null);
+        checkArgument(recView != null);
+        checkArgument(state != null);
+
+        mActions = actions;
+        mSelectionHelper = selectionHelper;
+        mSelectionPredicate = selectionPredicate;
+        mDetailsLookup = detailsLookup;
+        mFocusHandler = focusHandler;
+        mRecView = recView;
+        mState = state;
+    }
+
+    KeyInputHandler createKeyHandler() {
+        KeyInputHandler.Callbacks callbacks = new KeyInputHandler.Callbacks() {
+            @Override
+            public boolean isInteractiveItem(ItemDetails item, KeyEvent e) {
+                switch (item.getItemViewType()) {
+                    case DocumentsAdapter.ITEM_TYPE_HEADER_MESSAGE:
+                    case DocumentsAdapter.ITEM_TYPE_INFLATED_MESSAGE:
+                    case DocumentsAdapter.ITEM_TYPE_SECTION_BREAK:
+                        return false;
+                    case DocumentsAdapter.ITEM_TYPE_DOCUMENT:
+                    case DocumentsAdapter.ITEM_TYPE_DIRECTORY:
+                        return true;
+                    default:
+                        throw new RuntimeException(
+                                "Unsupported item type: " + item.getItemViewType());
+                }
+            }
+
+            @Override
+            public boolean onItemActivated(ItemDetails item, KeyEvent e) {
+                // Handle enter key events
+                switch (e.getKeyCode()) {
+                    case KeyEvent.KEYCODE_ENTER:
+                    case KeyEvent.KEYCODE_DPAD_CENTER:
+                    case KeyEvent.KEYCODE_BUTTON_A:
+                        return mActions.openItem(
+                                item,
+                                ActionHandler.VIEW_TYPE_REGULAR,
+                                ActionHandler.VIEW_TYPE_PREVIEW);
+                    case KeyEvent.KEYCODE_SPACE:
+                        return mActions.openItem(
+                                item,
+                                ActionHandler.VIEW_TYPE_PREVIEW,
+                                ActionHandler.VIEW_TYPE_NONE);
+                }
+
+                return false;
+            }
+
+            @Override
+            public boolean onFocusItem(ItemDetails details, int keyCode, KeyEvent event) {
+                ViewHolder holder =
+                        mRecView.findViewHolderForAdapterPosition(details.getPosition());
+                if (holder instanceof DocumentHolder) {
+                    return mFocusHandler.handleKey((DocumentHolder) holder, keyCode, event);
+                }
+                return false;
+            }
+
+            @Override
+            public void onPerformHapticFeedback() {
+                mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+            }
+        };
+
+        return new KeyInputHandler(mSelectionHelper, mSelectionPredicate, callbacks);
+    }
+
+    MouseInputHandler createMouseHandler(
+            EventHandler<MotionEvent> showContextMenuCallback) {
+
+        checkArgument(showContextMenuCallback != null);
+
+        MouseInputHandler.Callbacks callbacks = new MouseInputHandler.Callbacks() {
+            @Override
+            public boolean onItemActivated(ItemDetails item, MotionEvent e) {
+                return mActions.openItem(
+                        item,
+                        ActionHandler.VIEW_TYPE_REGULAR,
+                        ActionHandler.VIEW_TYPE_PREVIEW);
+            }
+
+            @Override
+            public boolean onContextClick(MotionEvent e) {
+                return showContextMenuCallback.accept(e);
+            }
+
+            @Override
+            public void onPerformHapticFeedback() {
+                mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+            }
+
+            @Override
+            public void focusItem(ItemDetails item) {
+                mFocusHandler.focusDocument(item.getStableId());
+            }
+
+            @Override
+            public void clearFocus() {
+                mFocusHandler.clearFocus();
+            }
+
+            @Override
+            public boolean hasFocusedItem() {
+                return mFocusHandler.hasFocusedItem();
+            }
+
+            @Override
+            public int getFocusedPosition() {
+                return mFocusHandler.getFocusPosition();
+            }
+        };
+
+        return new MouseInputHandler(mSelectionHelper, mDetailsLookup, callbacks);
+    }
+
+    /**
+     * Factory method for input touch delegate. Exists to reduce complexity in the
+     * calling scope.
+     * @param gestureHelper
+     */
+    TouchInputHandler createTouchHandler(
+            GestureSelectionHelper gestureHelper, DragStartListener dragStartListener) {
+        checkArgument(dragStartListener != null);
+
+        TouchInputHandler.Callbacks callbacks = new TouchInputHandler.Callbacks() {
+            @Override
+            public boolean onItemActivated(ItemDetails item, MotionEvent e) {
+                return mActions.openItem(
+                        item,
+                        ActionHandler.VIEW_TYPE_PREVIEW,
+                        ActionHandler.VIEW_TYPE_REGULAR);
+            }
+
+            @Override
+            public boolean onDragInitiated(MotionEvent e) {
+                return dragStartListener.onTouchDragEvent(e);
+            }
+
+            @Override
+            public void onPerformHapticFeedback() {
+                mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+            }
+
+            @Override
+            public void focusItem(ItemDetails item) {
+                mFocusHandler.focusDocument(item.getStableId());
+            }
+
+            @Override
+            public void clearFocus() {
+                mFocusHandler.clearFocus();
+            }
+        };
+
+        return new TouchInputHandler(
+                mSelectionHelper, mDetailsLookup, mSelectionPredicate, gestureHelper, callbacks);
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/KeyInputHandler.java b/src/com/android/documentsui/dirlist/KeyInputHandler.java
new file mode 100644
index 0000000..b70438a
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/KeyInputHandler.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import android.view.KeyEvent;
+
+import com.android.documentsui.base.Events;
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.MotionInputHandler;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.selection.MotionInputHandler.Callbacks;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+import javax.annotation.Nullable;
+
+/**
+ * Class that handles keyboard events on RecyclerView items. The input handler
+ * must be attached directly to a RecyclerView item since, unlike DOM, events
+ * don't appear bubble up.
+ */
+public final class KeyInputHandler extends KeyboardEventListener {
+
+    private final SelectionHelper mSelectionHelper;
+    private final SelectionPredicate mSelectionPredicate;
+    private final Callbacks mCallbacks;
+
+    public KeyInputHandler(
+            SelectionHelper selectionHelper,
+            SelectionPredicate selectionPredicate,
+            Callbacks callbacks) {
+
+        mSelectionHelper = selectionHelper;
+        mSelectionPredicate = selectionPredicate;
+        mCallbacks = callbacks;
+    }
+
+    @Override
+    public boolean onKey(@Nullable ItemDetails details, int keyCode, KeyEvent event) {
+        // Only handle key-down events. This is simpler, consistent with most other UIs, and
+        // enables the handling of repeated key events from holding down a key.
+        if (event.getAction() != KeyEvent.ACTION_DOWN) {
+            return false;
+        }
+
+        // Ignore tab key events.  Those should be handled by the top-level key handler.
+        if (keyCode == KeyEvent.KEYCODE_TAB) {
+            return false;
+        }
+
+        // Ignore events sent to Addon Holders.
+        if (details != null) {
+            int itemType = details.getItemViewType();
+            if (itemType == DocumentsAdapter.ITEM_TYPE_HEADER_MESSAGE
+                    || itemType == DocumentsAdapter.ITEM_TYPE_INFLATED_MESSAGE
+                    || itemType == DocumentsAdapter.ITEM_TYPE_SECTION_BREAK) {
+                return false;
+            }
+        }
+
+        if (mCallbacks.onFocusItem(details, keyCode, event)) {
+            // Handle range selection adjustments. Extending the selection will adjust the
+            // bounds of the in-progress range selection. Each time an unshifted navigation
+            // event is received, the range selection is restarted.
+            if (shouldExtendSelection(details, event)) {
+                if (!mSelectionHelper.isRangeActive()) {
+                    // Start a range selection if one isn't active
+                    mSelectionHelper.startRange(details.getPosition());
+                }
+                mSelectionHelper.extendRange(details.getPosition());
+            } else {
+                mSelectionHelper.endRange();
+                mSelectionHelper.clearSelection();
+            }
+            return true;
+        }
+
+        // we don't yet have a mechanism to handle opening/previewing multiple documents at once
+        if (mSelectionHelper.getSelection().size() > 1) {
+            return false;
+        }
+
+        return mCallbacks.onItemActivated(details, event);
+    }
+
+    private boolean shouldExtendSelection(ItemDetails item, KeyEvent event) {
+        if (!Events.isNavigationKeyCode(event.getKeyCode()) || !event.isShiftPressed()) {
+            return false;
+        }
+
+        return mSelectionPredicate.canSetStateForId(item.getStableId(), true);
+    }
+
+    public static abstract class Callbacks extends MotionInputHandler.Callbacks {
+        public abstract boolean isInteractiveItem(ItemDetails item, KeyEvent e);
+        public abstract boolean onItemActivated(ItemDetails item, KeyEvent e);
+        public boolean onFocusItem(ItemDetails details, int keyCode, KeyEvent event) {
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/dirlist/KeyboardEventListener.java b/src/com/android/documentsui/dirlist/KeyboardEventListener.java
new file mode 100644
index 0000000..fb1fc0a
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/KeyboardEventListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import android.view.KeyEvent;
+
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+
+/**
+ * KeyboardListener is implemented by {@link KeyInputHandler}. The handler
+ * must be called from RecyclerView.Holders in response to keyboard events.
+ */
+public abstract class KeyboardEventListener {
+
+    /**
+     * Handles key events on the view holder.
+     *
+     * @param details The target ItemHolder.
+     * @param keyCode Key code for the event.
+     * @param event KeyEvent for the event.
+     *
+     * @return Whether the event was handled.
+     */
+    public abstract boolean onKey(ItemDetails details, int keyCode, KeyEvent event);
+}
diff --git a/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/src/com/android/documentsui/dirlist/ListDocumentHolder.java
index 42be8f9..f97410a 100644
--- a/src/com/android/documentsui/dirlist/ListDocumentHolder.java
+++ b/src/com/android/documentsui/dirlist/ListDocumentHolder.java
@@ -23,6 +23,7 @@
 import android.database.Cursor;
 import android.graphics.Rect;
 import android.text.format.Formatter;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
@@ -31,7 +32,6 @@
 
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Events.InputEvent;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.roots.RootCursorWrapper;
@@ -114,7 +114,7 @@
     }
 
     @Override
-    public boolean isInDragHotspot(InputEvent event) {
+    public boolean inDragRegion(MotionEvent event) {
         // If itemView is activated = selected, then whole region is interactive
         if (itemView.isActivated()) {
             return true;
@@ -139,7 +139,7 @@
     }
 
     @Override
-    public boolean isOverDocIcon(InputEvent event) {
+    public boolean inSelectRegion(MotionEvent event) {
         Rect iconRect = new Rect();
         mIconLayout.getGlobalVisibleRect(iconRect);
 
@@ -177,7 +177,13 @@
             // Note, we don't show any details for any directory...ever.
             hasDetails = false;
         } else {
-            if (mDoc.summary != null) {
+            // Show summary if the file is partial. Otherwise, there tends
+            // to be a bunch of confusing junk in the summary field
+            // as populated by Downlaods (and others). So to make things
+            // simpler and clearer for the user in list view, we only
+            // show the summary if the file is partial >
+            // which we believe to mean actively downloading.
+            if (mDoc.isPartial() && mDoc.summary != null) {
                 hasDetails = true;
                 mSummary.setText(mDoc.summary);
                 mSummary.setVisibility(View.VISIBLE);
diff --git a/src/com/android/documentsui/dirlist/ListeningGestureDetector.java b/src/com/android/documentsui/dirlist/ListeningGestureDetector.java
deleted file mode 100644
index cc81d3f..0000000
--- a/src/com/android/documentsui/dirlist/ListeningGestureDetector.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import static com.android.documentsui.base.Shared.VERBOSE;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.os.Build;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-
-import com.android.documentsui.base.BooleanConsumer;
-import com.android.documentsui.base.EventHandler;
-import com.android.documentsui.base.Events;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.base.Events.MotionInputEvent;
-import com.android.documentsui.base.Features;
-import com.android.documentsui.selection.BandController;
-import com.android.documentsui.selection.GestureSelector;
-
-import java.util.function.Consumer;
-
-//Receives event meant for both directory and empty view, and either pass them to
-//{@link UserInputHandler} for simple gestures (Single Tap, Long-Press), or intercept them for
-//other types of gestures (drag n' drop)
-final class ListeningGestureDetector extends GestureDetector implements OnItemTouchListener {
-
-    private static final String TAG = "ListeningGestureDetector";
-
-    private final Features mFeatures;
-    private final GestureSelector mGestureSelector;
-    private final EventHandler<InputEvent> mMouseDragListener;
-    private final BooleanConsumer mRefreshLayoutEnabler;
-    private final BandController mBandController;
-    private final MouseDelegate mMouseDelegate = new MouseDelegate();
-    private final TouchDelegate mTouchDelegate = new TouchDelegate();
-
-    // Currently only initialized on IS_DEBUGGABLE builds.
-    private final @Nullable ScaleGestureDetector mScaleDetector;
-
-    public ListeningGestureDetector(
-            Features features,
-            Context context,
-            RecyclerView recView,
-            EventHandler<InputEvent> mouseDragListener,
-            BooleanConsumer refreshLayoutEnabler,
-            GestureSelector gestureSelector,
-            UserInputHandler<? extends InputEvent> handler,
-            @Nullable BandController bandController,
-            Consumer<Float> scaleHandler) {
-
-        super(context, handler);
-
-        mFeatures = features;
-        mMouseDragListener = mouseDragListener;
-        mRefreshLayoutEnabler = refreshLayoutEnabler;
-        mGestureSelector = gestureSelector;
-        mBandController = bandController;
-        recView.addOnItemTouchListener(this);
-
-        mScaleDetector = !Build.IS_DEBUGGABLE
-                ? null
-                : new ScaleGestureDetector(
-                        context,
-                        new ScaleGestureDetector.SimpleOnScaleGestureListener() {
-                            @Override
-                            public boolean onScale(ScaleGestureDetector detector) {
-                                if (VERBOSE) Log.v(TAG,
-                                        "Received scale event: " + detector.getScaleFactor());
-                                scaleHandler.accept(detector.getScaleFactor());
-                                return true;
-                            }
-                        });
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
-        boolean handled = false;
-
-        // TODO: Re-wire event handling so that we're not dispatching
-        //     events to to scaledetector's #onTouchEvent from this
-        //     #onInterceptTouchEvent touch event.
-        if (mFeatures.isGestureScaleEnabled()
-                && mScaleDetector != null) {
-            mScaleDetector.onTouchEvent(e);
-        }
-
-        try (InputEvent event = MotionInputEvent.obtain(e, rv)) {
-            if (event.isMouseEvent()) {
-                if (event.isActionDown()) {
-                    mRefreshLayoutEnabler.accept(false);
-                }
-                handled |= mMouseDelegate.onInterceptTouchEvent(event);
-            } else {
-                // If user has started some gesture while RecyclerView is not at the top, disable
-                // refresh
-                if (event.isActionDown() && rv.computeVerticalScrollOffset() != 0) {
-                    mRefreshLayoutEnabler.accept(false);
-                }
-                handled |= mTouchDelegate.onInterceptTouchEvent(event);
-            }
-
-
-            if (event.isActionUp()) {
-                mRefreshLayoutEnabler.accept(true);
-            }
-        }
-
-        // Forward all events to UserInputHandler.
-        // This is necessary since UserInputHandler needs to always see the first DOWN event. Or
-        // else all future UP events will be tossed.
-        handled |= onTouchEvent(e);
-
-        return handled;
-    }
-
-    @Override
-    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
-        try (InputEvent event = MotionInputEvent.obtain(e, rv)) {
-            if (Events.isMouseEvent(e)) {
-                mMouseDelegate.onTouchEvent(event);
-            } else {
-                mTouchDelegate.onTouchEvent(rv, event);
-            }
-
-            if (event.isActionUp()) {
-                mRefreshLayoutEnabler.accept(true);
-            }
-        }
-
-        // Note: even though this event is being handled as part of gestures such as drag and band,
-        // continue forwarding to the GestureDetector. The detector needs to see the entire cluster
-        // of events in order to properly interpret other gestures, such as long press.
-        onTouchEvent(e);
-    }
-
-    private class MouseDelegate {
-        boolean onInterceptTouchEvent(InputEvent e) {
-            if (Events.isMouseDragEvent(e)) {
-                return mMouseDragListener.accept(e);
-            } else if (mBandController != null &&
-                    (mBandController.shouldStart(e) || mBandController.shouldStop(e))) {
-                return mBandController.onInterceptTouchEvent(e);
-            }
-            return false;
-        }
-
-        void onTouchEvent(InputEvent e) {
-            if (mBandController != null) {
-                mBandController.onTouchEvent(e);
-            }
-        }
-    }
-
-    private class TouchDelegate {
-        boolean onInterceptTouchEvent(InputEvent e) {
-            // Gesture Selector needs to be constantly fed events, so that when a long press does
-            // happen, we would have the last DOWN event that occurred to keep track of our anchor
-            // point
-            return mGestureSelector.onInterceptTouchEvent(e);
-        }
-
-        // TODO: Make this take just an InputEvent, no RecyclerView
-        void onTouchEvent(RecyclerView rv, InputEvent e) {
-            mGestureSelector.onTouchEvent(rv, e);
-        }
-    }
-
-    @Override
-    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
-}
diff --git a/src/com/android/documentsui/dirlist/MessageHolder.java b/src/com/android/documentsui/dirlist/MessageHolder.java
index a9a722d..f445347 100644
--- a/src/com/android/documentsui/dirlist/MessageHolder.java
+++ b/src/com/android/documentsui/dirlist/MessageHolder.java
@@ -17,12 +17,10 @@
 package com.android.documentsui.dirlist;
 
 import android.content.Context;
+import android.view.MotionEvent;
 import android.view.ViewGroup;
 import android.widget.Space;
 
-import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Events.InputEvent;
-
 /**
  * Base class for all non-Document Holder classes.
  */
@@ -36,12 +34,7 @@
     }
 
     @Override
-    public boolean isInSelectionHotspot(InputEvent event) {
+    public boolean inDragRegion(MotionEvent event) {
         return false;
     }
-
-    @Override
-    public boolean isInDragHotspot(InputEvent event) {
-        return false;
-    }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java b/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
index 921917c..99bb63c 100644
--- a/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
+++ b/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
@@ -23,14 +23,16 @@
 
 import android.database.Cursor;
 import android.provider.DocumentsContract.Document;
+import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 import android.view.ViewGroup;
 
 import com.android.documentsui.Model;
+import com.android.documentsui.Model.Update;
 import com.android.documentsui.base.EventListener;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.State;
-import com.android.documentsui.Model.Update;
+import com.android.documentsui.selection.SelectionHelper;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -109,7 +111,7 @@
 
     @Override
     public void onBindViewHolder(DocumentHolder holder, int position, List<Object> payload) {
-        if (payload.contains(SELECTION_CHANGED_MARKER)) {
+        if (payload.contains(SelectionHelper.SELECTION_CHANGED_MARKER)) {
             final boolean selected = mEnv.isSelected(mModelIds.get(position));
             holder.setSelected(selected, true);
         } else {
@@ -156,7 +158,7 @@
     }
 
     @Override
-    public String getModelId(int adapterPosition) {
+    public String getStableId(int adapterPosition) {
         return mModelIds.get(adapterPosition);
     }
 
@@ -166,11 +168,17 @@
     }
 
     @Override
-    public List<String> getModelIds() {
+    public List<String> getStableIds() {
         return mModelIds;
     }
 
     @Override
+    public int getPosition(String id) {
+        int position = mModelIds.indexOf(id);
+        return position >= 0 ? position : RecyclerView.NO_POSITION;
+    }
+
+    @Override
     public int getItemViewType(int position) {
         return isDirectory(mEnv.getModel(), position)
                 ? ITEM_TYPE_DIRECTORY
@@ -189,15 +197,4 @@
         }
         return false;
     }
-
-    @Override
-    public void onItemSelectionChanged(String id) {
-        int position = mModelIds.indexOf(id);
-
-        if (position >= 0) {
-            notifyItemChanged(position, SELECTION_CHANGED_MARKER);
-        } else {
-            Log.w(TAG, "Item change notification received for unknown item: " + id);
-        }
-    }
 }
diff --git a/src/com/android/documentsui/dirlist/MouseDragEventInterceptor.java b/src/com/android/documentsui/dirlist/MouseDragEventInterceptor.java
new file mode 100644
index 0000000..fa40c26
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/MouseDragEventInterceptor.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.view.MotionEvent;
+
+import com.android.documentsui.base.EventHandler;
+import com.android.documentsui.base.Events;
+import com.android.documentsui.selection.BandSelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.TouchEventRouter;
+
+/**
+ * OnItemTouchListener that helps enable support for drag/drop functionality
+ * in DirectoryFragment.
+ *
+ * <p>This class takes an OnItemTouchListener that is presumably the
+ * one provided by {@link BandSelectionHelper#getListener()}, and
+ * is used in conjunction with the {@link TouchEventRouter}.
+ *
+ * <p>See DirectoryFragment for more details on how this is glued
+ * into DocumetnsUI event handling to make the magic happen.
+ */
+class MouseDragEventInterceptor implements OnItemTouchListener {
+
+    private final ItemDetailsLookup mEventDetailsLookup;
+    private final EventHandler<MotionEvent> mMouseDragListener;
+    private final @Nullable OnItemTouchListener mDelegate;
+
+    public MouseDragEventInterceptor(
+            ItemDetailsLookup eventDetailsLookup,
+            EventHandler<MotionEvent> mouseDragListener,
+            @Nullable OnItemTouchListener delegate) {
+
+        checkArgument(eventDetailsLookup != null);
+        checkArgument(mouseDragListener != null);
+
+        mEventDetailsLookup = eventDetailsLookup;
+        mMouseDragListener = mouseDragListener;
+        mDelegate = delegate;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+        if (Events.isMouseDragEvent(e) && mEventDetailsLookup.inItemDragRegion(e)) {
+            return mMouseDragListener.accept(e);
+        } else if (mDelegate != null) {
+            return mDelegate.onInterceptTouchEvent(rv, e);
+        }
+        return false;
+    }
+
+    @Override
+    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+        if (mDelegate != null) {
+            mDelegate.onTouchEvent(rv, e);
+        }
+    }
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+}
diff --git a/src/com/android/documentsui/dirlist/RefreshHelper.java b/src/com/android/documentsui/dirlist/RefreshHelper.java
new file mode 100644
index 0000000..a1a5662
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/RefreshHelper.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import static android.support.v4.util.Preconditions.checkState;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.view.MotionEvent;
+
+import com.android.documentsui.base.BooleanConsumer;
+import com.android.documentsui.base.Events;
+
+/**
+ * Class providing support for gluing gesture scaling of the ui into RecyclerView + DocsUI.
+ */
+final class RefreshHelper {
+
+    private final BooleanConsumer mRefreshLayoutEnabler;
+
+    private boolean mAttached;
+
+    public RefreshHelper(BooleanConsumer refreshLayoutEnabler) {
+        mRefreshLayoutEnabler = refreshLayoutEnabler;
+    }
+
+    private boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+        if (Events.isMouseEvent(e)) {
+            if (Events.isActionDown(e)) {
+                mRefreshLayoutEnabler.accept(false);
+            }
+        } else {
+            // If user has started some gesture while RecyclerView is not at the top, disable
+            // refresh
+            if (Events.isActionDown(e) && rv.computeVerticalScrollOffset() != 0) {
+                mRefreshLayoutEnabler.accept(false);
+            }
+        }
+
+        if (Events.isActionUp(e)) {
+            mRefreshLayoutEnabler.accept(true);
+        }
+
+        return false;
+    }
+
+    private void onTouchEvent(RecyclerView rv, MotionEvent e) {
+        if (Events.isActionUp(e)) {
+            mRefreshLayoutEnabler.accept(true);
+        }
+    }
+
+    void attach(RecyclerView view) {
+        checkState(!mAttached);
+
+        view.addOnItemTouchListener(
+                new OnItemTouchListener() {
+                    @Override
+                    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+                        RefreshHelper.this.onTouchEvent(rv, e);
+                    }
+
+                    @Override
+                    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+                        return RefreshHelper.this.onInterceptTouchEvent(rv, e);
+                    }
+
+                    @Override
+                    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+        });
+
+        mAttached = true;
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
index db9d399..8025a65 100644
--- a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
+++ b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -107,6 +107,7 @@
                         return false;
                     }
                 });
+        mEditText.requestFocus();
         return dialog;
     }
 
diff --git a/src/com/android/documentsui/dirlist/ScaleHelper.java b/src/com/android/documentsui/dirlist/ScaleHelper.java
new file mode 100644
index 0000000..d927fcd
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/ScaleHelper.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.dirlist;
+
+import static android.support.v4.util.Preconditions.checkState;
+import static com.android.documentsui.base.Shared.VERBOSE;
+
+import android.content.Context;
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+
+import com.android.documentsui.base.Features;
+
+import java.util.function.Consumer;
+
+/**
+ * Class providing support for gluing gesture scaling of the ui into RecyclerView + DocsUI.
+ */
+final class ScaleHelper {
+
+    private static final String TAG = "ScaleHelper";
+
+    private final Context mContext;
+    private final Features mFeatures;
+    private final Consumer<Float> mScaleCallback;
+
+    private @Nullable ScaleGestureDetector mScaleDetector;
+
+    public ScaleHelper(Context context, Features features, Consumer<Float> scaleCallback) {
+        mContext = context;
+        mFeatures = features;
+        mScaleCallback = scaleCallback;
+    }
+
+    private boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+        // Checking feature is deferred to runtime so the feature can be enabled
+        // after this class has been setup.
+        if (mFeatures.isGestureScaleEnabled() && mScaleDetector != null) {
+            mScaleDetector.onTouchEvent(e);
+        }
+
+        return false;
+    }
+
+    void attach(RecyclerView view) {
+        checkState(Build.IS_DEBUGGABLE);
+        checkState(mScaleDetector == null);
+
+        mScaleDetector = new ScaleGestureDetector(
+            mContext,
+            new ScaleGestureDetector.SimpleOnScaleGestureListener() {
+                @Override
+                public boolean onScale(ScaleGestureDetector detector) {
+                    if (VERBOSE) Log.v(TAG,
+                            "Received scale event: " + detector.getScaleFactor());
+                    mScaleCallback.accept(detector.getScaleFactor());
+                    return true;
+                }
+            });
+
+        view.addOnItemTouchListener(
+                new OnItemTouchListener() {
+                    @Override
+                    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+                        return ScaleHelper.this.onInterceptTouchEvent(rv, e);
+                    }
+
+                    @Override
+                    public void onTouchEvent(RecyclerView rv, MotionEvent e) {}
+
+                    @Override
+                    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+        });
+    }
+}
diff --git a/src/com/android/documentsui/selection/SelectionMetadata.java b/src/com/android/documentsui/dirlist/SelectionMetadata.java
similarity index 89%
rename from src/com/android/documentsui/selection/SelectionMetadata.java
rename to src/com/android/documentsui/dirlist/SelectionMetadata.java
index df0f1d6..3ac3a07 100644
--- a/src/com/android/documentsui/selection/SelectionMetadata.java
+++ b/src/com/android/documentsui/dirlist/SelectionMetadata.java
@@ -14,14 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.selection;
+package com.android.documentsui.dirlist;
 
 import static com.android.documentsui.base.DocumentInfo.getCursorInt;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
@@ -30,14 +27,19 @@
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.base.MimeTypes;
 import com.android.documentsui.roots.RootCursorWrapper;
+import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
 
 import java.util.function.Function;
 
 /**
- * A class that holds metadata
+ * A class that aggregates document metadata describing the selection. It can answer questions
+ * like: Can the selection be deleted? and Does the selection contain a folder?
+ *
+ * <p>By collecting information in real-time as the selection changes the need to
+ * traverse the entire selection in order to answer questions is eliminated.
  */
-public class SelectionMetadata
-        implements MenuManager.SelectionDetails, SelectionManager.ItemCallback {
+public class SelectionMetadata extends SelectionObserver
+        implements MenuManager.SelectionDetails {
 
     private static final String TAG = "SelectionMetadata";
     private final static int FLAG_CAN_DELETE =
diff --git a/src/com/android/documentsui/dirlist/UserInputHandler.java b/src/com/android/documentsui/dirlist/UserInputHandler.java
deleted file mode 100644
index f33284b..0000000
--- a/src/com/android/documentsui/dirlist/UserInputHandler.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import static com.android.documentsui.base.Shared.DEBUG;
-import static com.android.documentsui.base.Shared.VERBOSE;
-
-import android.support.annotation.VisibleForTesting;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import com.android.documentsui.ActionHandler;
-import com.android.documentsui.base.EventHandler;
-import com.android.documentsui.base.Events;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.selection.SelectionManager;
-
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-import javax.annotation.Nullable;
-
-/**
- * Grand unified-ish gesture/event listener for items in the directory list.
- */
-public final class UserInputHandler<T extends InputEvent>
-        extends GestureDetector.SimpleOnGestureListener
-        implements DocumentHolder.KeyboardEventListener {
-
-    private static final String TAG = "UserInputHandler";
-
-    private ActionHandler mActions;
-    private final FocusHandler mFocusHandler;
-    private final SelectionManager mSelectionMgr;
-    private final Function<MotionEvent, T> mEventConverter;
-    private final Predicate<DocumentDetails> mSelectable;
-
-    private final EventHandler<InputEvent> mContextMenuClickHandler;
-
-    private final EventHandler<InputEvent> mTouchDragListener;
-    private final EventHandler<InputEvent> mGestureSelectHandler;
-    private final Runnable mPerformHapticFeedback;
-
-    private final TouchInputDelegate mTouchDelegate;
-    private final MouseInputDelegate mMouseDelegate;
-    private final KeyInputHandler mKeyListener;
-
-    public UserInputHandler(
-            ActionHandler actions,
-            FocusHandler focusHandler,
-            SelectionManager selectionMgr,
-            Function<MotionEvent, T> eventConverter,
-            Predicate<DocumentDetails> selectable,
-            EventHandler<InputEvent> contextMenuClickHandler,
-            EventHandler<InputEvent> touchDragListener,
-            EventHandler<InputEvent> gestureSelectHandler,
-            Runnable performHapticFeedback) {
-
-        mActions = actions;
-        mFocusHandler = focusHandler;
-        mSelectionMgr = selectionMgr;
-        mEventConverter = eventConverter;
-        mSelectable = selectable;
-        mContextMenuClickHandler = contextMenuClickHandler;
-        mTouchDragListener = touchDragListener;
-        mGestureSelectHandler = gestureSelectHandler;
-        mPerformHapticFeedback = performHapticFeedback;
-
-        mTouchDelegate = new TouchInputDelegate();
-        mMouseDelegate = new MouseInputDelegate();
-        mKeyListener = new KeyInputHandler();
-    }
-
-    @Override
-    public boolean onDown(MotionEvent e) {
-        try (T event = mEventConverter.apply(e)) {
-            return onDown(event);
-        }
-    }
-
-    @VisibleForTesting
-    boolean onDown(T event) {
-        return event.isMouseEvent()
-                ? mMouseDelegate.onDown(event)
-                : mTouchDelegate.onDown(event);
-    }
-
-    @Override
-    public boolean onScroll(MotionEvent e1, MotionEvent e2,
-            float distanceX, float distanceY) {
-        try (T event = mEventConverter.apply(e2)) {
-            return onScroll(event);
-        }
-    }
-
-    @VisibleForTesting
-    boolean onScroll(T event) {
-        return event.isMouseEvent()
-                ? mMouseDelegate.onScroll(event)
-                : mTouchDelegate.onScroll(event);
-    }
-
-    @Override
-    public boolean onSingleTapUp(MotionEvent e) {
-        try (T event = mEventConverter.apply(e)) {
-            return onSingleTapUp(event);
-        }
-    }
-
-    @VisibleForTesting
-    boolean onSingleTapUp(T event) {
-        return event.isMouseEvent()
-                ? mMouseDelegate.onSingleTapUp(event)
-                : mTouchDelegate.onSingleTapUp(event);
-    }
-
-    @Override
-    public boolean onSingleTapConfirmed(MotionEvent e) {
-        try (T event = mEventConverter.apply(e)) {
-            return onSingleTapConfirmed(event);
-        }
-    }
-
-    @VisibleForTesting
-    boolean onSingleTapConfirmed(T event) {
-        return event.isMouseEvent()
-                ? mMouseDelegate.onSingleTapConfirmed(event)
-                : mTouchDelegate.onSingleTapConfirmed(event);
-    }
-
-    @Override
-    public boolean onDoubleTap(MotionEvent e) {
-        try (T event = mEventConverter.apply(e)) {
-            return onDoubleTap(event);
-        }
-    }
-
-    @VisibleForTesting
-    boolean onDoubleTap(T event) {
-        return event.isMouseEvent()
-                ? mMouseDelegate.onDoubleTap(event)
-                : mTouchDelegate.onDoubleTap(event);
-    }
-
-    @Override
-    public void onLongPress(MotionEvent e) {
-        try (T event = mEventConverter.apply(e)) {
-            onLongPress(event);
-        }
-    }
-
-    @VisibleForTesting
-    void onLongPress(T event) {
-        if (event.isMouseEvent()) {
-            mMouseDelegate.onLongPress(event);
-        } else {
-            mTouchDelegate.onLongPress(event);
-        }
-    }
-
-    // Only events from RecyclerView are fed into UserInputHandler#onDown.
-    // ListeningGestureDetector#onTouch directly calls this method to support context menu in empty
-    // view
-    boolean onRightClick(MotionEvent e) {
-        try (T event = mEventConverter.apply(e)) {
-            return mMouseDelegate.onRightClick(event);
-        }
-    }
-
-    @Override
-    public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event) {
-        return mKeyListener.onKey(doc, keyCode, event);
-    }
-
-    private boolean selectDocument(DocumentDetails doc) {
-        assert(doc != null);
-        assert(doc.hasModelId());
-        mSelectionMgr.toggleSelection(doc.getModelId());
-        mSelectionMgr.setSelectionRangeBegin(doc.getAdapterPosition());
-
-        // we set the focus on this doc so it will be the origin for keyboard events or shift+clicks
-        // if there is only a single item selected, otherwise clear focus
-        if (mSelectionMgr.getSelection().size() == 1) {
-            mFocusHandler.focusDocument(doc.getModelId());
-        } else {
-            mFocusHandler.clearFocus();
-        }
-        return true;
-    }
-
-    private boolean focusDocument(DocumentDetails doc) {
-        assert(doc != null);
-        assert(doc.hasModelId());
-
-        mSelectionMgr.clearSelection();
-        mFocusHandler.focusDocument(doc.getModelId());
-        return true;
-    }
-
-    private void extendSelectionRange(DocumentDetails doc) {
-        mSelectionMgr.snapRangeSelection(doc.getAdapterPosition());
-        mFocusHandler.focusDocument(doc.getModelId());
-    }
-
-    boolean isRangeExtension(T event) {
-        return event.isShiftKeyDown() && mSelectionMgr.isRangeSelectionActive();
-    }
-
-    private boolean shouldClearSelection(T event, DocumentDetails doc) {
-        return !event.isCtrlKeyDown()
-                && !doc.isInSelectionHotspot(event)
-                && !doc.isOverDocIcon(event)
-                && !isSelected(doc);
-    }
-
-    private boolean isSelected(DocumentDetails doc) {
-        return mSelectionMgr.getSelection().contains(doc.getModelId());
-    }
-
-    private static final String TTAG = "TouchInputDelegate";
-    private final class TouchInputDelegate {
-
-        boolean onDown(T event) {
-            if (VERBOSE) Log.v(TTAG, "Delegated onDown event.");
-            return false;
-        }
-
-        // Don't consume so the RecyclerView will get the event and will get touch-based scrolling
-        boolean onScroll(T event) {
-            if (VERBOSE) Log.v(TTAG, "Delegated onScroll event.");
-            return false;
-        }
-
-        boolean onSingleTapUp(T event) {
-            if (VERBOSE) Log.v(TTAG, "Delegated onSingleTapUp event.");
-            if (!event.isOverModelItem()) {
-                if (DEBUG) Log.d(TTAG, "Tap not associated w/ model item. Clearing selection.");
-                mSelectionMgr.clearSelection();
-                return false;
-            }
-
-            DocumentDetails doc = event.getDocumentDetails();
-            if (mSelectionMgr.hasSelection()) {
-                if (isRangeExtension(event)) {
-                    extendSelectionRange(doc);
-                } else if (mSelectionMgr.getSelection().contains(doc.getModelId())) {
-                    mSelectionMgr.toggleSelection(doc.getModelId());
-                } else {
-                    selectDocument(doc);
-                }
-
-                return true;
-            }
-
-            // Touch events select if they occur in the selection hotspot,
-            // otherwise they activate.
-            return doc.isInSelectionHotspot(event)
-                    ? selectDocument(doc)
-                    : mActions.openDocument(doc, ActionHandler.VIEW_TYPE_PREVIEW,
-                            ActionHandler.VIEW_TYPE_REGULAR);
-        }
-
-        boolean onSingleTapConfirmed(T event) {
-            if (VERBOSE) Log.v(TTAG, "Delegated onSingleTapConfirmed event.");
-            return false;
-        }
-
-        boolean onDoubleTap(T event) {
-            if (VERBOSE) Log.v(TTAG, "Delegated onDoubleTap event.");
-            return false;
-        }
-
-        final void onLongPress(T event) {
-            if (VERBOSE) Log.v(TTAG, "Delegated onLongPress event.");
-            if (!event.isOverModelItem()) {
-                if (DEBUG) Log.d(TTAG, "Ignoring LongPress on non-model-backed item.");
-                return;
-            }
-
-            DocumentDetails doc = event.getDocumentDetails();
-            boolean handled = false;
-            if (isRangeExtension(event)) {
-                extendSelectionRange(doc);
-                handled = true;
-            } else {
-                if (!mSelectionMgr.getSelection().contains(doc.getModelId())) {
-                    selectDocument(doc);
-                    // If we cannot select it, we didn't apply anchoring - therefore should not
-                    // start gesture selection
-                    if (mSelectable.test(doc)) {
-                        mGestureSelectHandler.accept(event);
-                        handled = true;
-                    }
-                } else {
-                    // We only initiate drag and drop on long press for touch to allow regular
-                    // touch-based scrolling
-                    mTouchDragListener.accept(event);
-                    handled = true;
-                }
-            }
-            if (handled) {
-                mPerformHapticFeedback.run();
-            }
-        }
-    }
-
-    private static final String MTAG = "MouseInputDelegate";
-    private final class MouseInputDelegate {
-        // The event has been handled in onSingleTapUp
-        private boolean mHandledTapUp;
-        // true when the previous event has consumed a right click motion event
-        private boolean mHandledOnDown;
-
-        boolean onDown(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onDown event.");
-            if (event.isSecondaryButtonPressed()
-                    || (event.isAltKeyDown() && event.isPrimaryButtonPressed())) {
-                mHandledOnDown = true;
-                return onRightClick(event);
-            }
-
-            return false;
-        }
-
-        // Don't scroll content window in response to mouse drag
-        boolean onScroll(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onScroll event.");
-            // If it's two-finger trackpad scrolling, we want to scroll
-            return !event.isTouchpadScroll();
-        }
-
-        boolean onSingleTapUp(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onSingleTapUp event.");
-
-            // See b/27377794. Since we don't get a button state back from UP events, we have to
-            // explicitly save this state to know whether something was previously handled by
-            // DOWN events or not.
-            if (mHandledOnDown) {
-                if (VERBOSE) Log.v(MTAG, "Ignoring onSingleTapUp, previously handled in onDown.");
-                mHandledOnDown = false;
-                return false;
-            }
-
-            if (!event.isOverModelItem()) {
-                if (DEBUG) Log.d(MTAG, "Tap not associated w/ model item. Clearing selection.");
-                mSelectionMgr.clearSelection();
-                mFocusHandler.clearFocus();
-                return false;
-            }
-
-            if (event.isTertiaryButtonPressed()) {
-                if (DEBUG) Log.d(MTAG, "Ignoring middle click");
-                return false;
-            }
-
-            DocumentDetails doc = event.getDocumentDetails();
-            if (mSelectionMgr.hasSelection()) {
-                if (isRangeExtension(event)) {
-                    extendSelectionRange(doc);
-                } else {
-                    if (shouldClearSelection(event, doc)) {
-                        mSelectionMgr.clearSelection();
-                    }
-                    if (isSelected(doc)) {
-                        mSelectionMgr.toggleSelection(doc.getModelId());
-                        mFocusHandler.clearFocus();
-                    } else {
-                        selectOrFocusItem(event);
-                    }
-                }
-                mHandledTapUp = true;
-                return true;
-            }
-
-            return false;
-        }
-
-        boolean onSingleTapConfirmed(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onSingleTapConfirmed event.");
-            if (mHandledTapUp) {
-                if (VERBOSE) Log.v(MTAG, "Ignoring onSingleTapConfirmed, previously handled in onSingleTapUp.");
-                mHandledTapUp = false;
-                return false;
-            }
-
-            if (mSelectionMgr.hasSelection()) {
-                return false;  // should have been handled by onSingleTapUp.
-            }
-
-            if (!event.isOverItem()) {
-                if (DEBUG) Log.d(MTAG, "Ignoring Confirmed Tap on non-item.");
-                return false;
-            }
-
-            if (event.isTertiaryButtonPressed()) {
-                if (DEBUG) Log.d(MTAG, "Ignoring middle click");
-                return false;
-            }
-
-            @Nullable DocumentDetails doc = event.getDocumentDetails();
-            if (doc == null || !doc.hasModelId()) {
-                Log.w(MTAG, "Ignoring Confirmed Tap. No document details associated w/ event.");
-                return false;
-            }
-
-            if (mFocusHandler.hasFocusedItem() && event.isShiftKeyDown()) {
-                mSelectionMgr.formNewSelectionRange(mFocusHandler.getFocusPosition(),
-                        doc.getAdapterPosition());
-            } else {
-                selectOrFocusItem(event);
-            }
-            return true;
-        }
-
-        boolean onDoubleTap(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onDoubleTap event.");
-            mHandledTapUp = false;
-
-            if (!event.isOverModelItem()) {
-                if (DEBUG) Log.d(MTAG, "Ignoring DoubleTap on non-model-backed item.");
-                return false;
-            }
-
-            if (event.isTertiaryButtonPressed()) {
-                if (DEBUG) Log.d(MTAG, "Ignoring middle click");
-                return false;
-            }
-
-            DocumentDetails doc = event.getDocumentDetails();
-            return mActions.openDocument(doc, ActionHandler.VIEW_TYPE_REGULAR,
-                    ActionHandler.VIEW_TYPE_PREVIEW);
-        }
-
-        final void onLongPress(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onLongPress event.");
-            return;
-        }
-
-        private boolean onRightClick(T event) {
-            if (VERBOSE) Log.v(MTAG, "Delegated onRightClick event.");
-            if (event.isOverModelItem()) {
-                DocumentDetails doc = event.getDocumentDetails();
-                if (!mSelectionMgr.getSelection().contains(doc.getModelId())) {
-                    mSelectionMgr.clearSelection();
-                    selectDocument(doc);
-                }
-            }
-
-            // We always delegate final handling of the event,
-            // since the handler might want to show a context menu
-            // in an empty area or some other weirdo view.
-            return mContextMenuClickHandler.accept(event);
-        }
-
-        private void selectOrFocusItem(T event) {
-            if (event.isOverDocIcon() || event.isCtrlKeyDown()) {
-                selectDocument(event.getDocumentDetails());
-            } else {
-                focusDocument(event.getDocumentDetails());
-            }
-        }
-    }
-
-    private final class KeyInputHandler {
-        // TODO: Refactor FocusManager to depend only on DocumentDetails so we can eliminate
-        // difficult to test dependency on DocumentHolder.
-
-        boolean onKey(@Nullable DocumentHolder doc, int keyCode, KeyEvent event) {
-            // Only handle key-down events. This is simpler, consistent with most other UIs, and
-            // enables the handling of repeated key events from holding down a key.
-            if (event.getAction() != KeyEvent.ACTION_DOWN) {
-                return false;
-            }
-
-            // Ignore tab key events.  Those should be handled by the top-level key handler.
-            if (keyCode == KeyEvent.KEYCODE_TAB) {
-                return false;
-            }
-
-            // Ignore events sent to Addon Holders.
-            if (doc != null) {
-                int itemType = doc.getItemViewType();
-                if (itemType == DocumentsAdapter.ITEM_TYPE_HEADER_MESSAGE
-                        || itemType == DocumentsAdapter.ITEM_TYPE_INFLATED_MESSAGE
-                        || itemType == DocumentsAdapter.ITEM_TYPE_SECTION_BREAK) {
-                    return false;
-                }
-            }
-
-            if (mFocusHandler.handleKey(doc, keyCode, event)) {
-                // Handle range selection adjustments. Extending the selection will adjust the
-                // bounds of the in-progress range selection. Each time an unshifted navigation
-                // event is received, the range selection is restarted.
-                if (shouldExtendSelection(doc, event)) {
-                    if (!mSelectionMgr.isRangeSelectionActive()) {
-                        // Start a range selection if one isn't active
-                        mSelectionMgr.startRangeSelection(doc.getAdapterPosition());
-                    }
-                    mSelectionMgr.snapRangeSelection(mFocusHandler.getFocusPosition());
-                } else {
-                    mSelectionMgr.endRangeSelection();
-                    mSelectionMgr.clearSelection();
-                }
-                return true;
-            }
-
-            // we don't yet have a mechanism to handle opening/previewing multiple documents at once
-            if (mSelectionMgr.getSelection().size() > 1) {
-                return false;
-            }
-
-            // Handle enter key events
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_ENTER:
-                case KeyEvent.KEYCODE_DPAD_CENTER:
-                case KeyEvent.KEYCODE_BUTTON_A:
-                    return mActions.openDocument(doc, ActionHandler.VIEW_TYPE_REGULAR,
-                            ActionHandler.VIEW_TYPE_PREVIEW);
-                case KeyEvent.KEYCODE_SPACE:
-                    return mActions.openDocument(doc, ActionHandler.VIEW_TYPE_PREVIEW,
-                            ActionHandler.VIEW_TYPE_NONE);
-            }
-
-            return false;
-        }
-
-        private boolean shouldExtendSelection(DocumentDetails doc, KeyEvent event) {
-            if (!Events.isNavigationKeyCode(event.getKeyCode()) || !event.isShiftPressed()) {
-                return false;
-            }
-
-            return mSelectable.test(doc);
-        }
-    }
-}
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 922f0c0..715e6c9 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -25,7 +25,9 @@
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Build;
 import android.provider.DocumentsContract;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.DragEvent;
 
@@ -56,12 +58,13 @@
 import com.android.documentsui.clipping.DocumentClipper;
 import com.android.documentsui.clipping.UrisSupplier;
 import com.android.documentsui.dirlist.AnimationView;
-import com.android.documentsui.dirlist.DocumentDetails;
 import com.android.documentsui.files.ActionHandler.Addons;
 import com.android.documentsui.inspector.InspectorActivity;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.ProvidersAccess;
+import com.android.documentsui.selection.MutableSelection;
 import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperations;
@@ -187,12 +190,12 @@
     }
 
     @Override
-    public boolean openDocument(DocumentDetails details, @ViewType int type,
+    public boolean openItem(ItemDetails details, @ViewType int type,
             @ViewType int fallback) {
-        DocumentInfo doc = mModel.getDocument(details.getModelId());
+        DocumentInfo doc = mModel.getDocument(details.getStableId());
         if (doc == null) {
             Log.w(TAG,
-                    "Can't view item. No Document available for modeId: " + details.getModelId());
+                    "Can't view item. No Document available for modeId: " + details.getStableId());
             return false;
         }
 
@@ -218,7 +221,7 @@
     }
 
     private Selection getSelectedOrFocused() {
-        final Selection selection = this.getStableSelection();
+        final MutableSelection selection = this.getStableSelection();
         if (selection.isEmpty()) {
             String focusModelId = mFocusHandler.getFocusModelId();
             if (focusModelId != null) {
@@ -508,6 +511,14 @@
             return;
         }
 
+        // For APKs, even if the type is preview, we send an ACTION_VIEW intent to allow
+        // PackageManager to install it.  This allows users to install APKs from any root.
+        // The Downloads special case is handled above in #manageDocument.
+        if (MimeTypes.isApkType(doc.mimeType)) {
+            viewDocument(doc);
+            return;
+        }
+
         switch (type) {
           case VIEW_TYPE_REGULAR:
             if (viewDocument(doc)) {
@@ -678,11 +689,26 @@
     public void showInspector(DocumentInfo doc) {
         Metrics.logUserAction(mActivity, Metrics.USER_ACTION_INSPECTOR);
         Intent intent = new Intent(mActivity, InspectorActivity.class);
+        intent.setData(doc.derivedUri);
+
+        // permit the display of debug info about the file.
         intent.putExtra(
                 Shared.EXTRA_SHOW_DEBUG,
-                mFeatures.isDebugSupportEnabled()
-                        || DebugFlags.getDocumentDetailsEnabled());
-        intent.setData(doc.derivedUri);
+                mFeatures.isDebugSupportEnabled() &&
+                        (Build.IS_DEBUGGABLE || DebugFlags.getDocumentDetailsEnabled()));
+
+        // The "root document" (top level folder in a root) don't usually have a
+        // human friendly display name. That's because we've never shown the root
+        // folder's name to anyone.
+        // For that reason when the doc being inspected is the root folder,
+        // we override the displayName of the doc w/ the Root's name instead.
+        // The Root's name is shown to the user in the sidebar.
+        if (doc.isDirectory() && mState.stack.size() == 1 && mState.stack.get(0).equals(doc)) {
+            RootInfo root = mActivity.getCurrentRoot();
+            // Recents root title isn't defined, but inspector is disabled for recents root folder.
+            assert !TextUtils.isEmpty(root.title);
+            intent.putExtra(Intent.EXTRA_TITLE, root.title);
+        }
         mActivity.startActivity(intent);
     }
 
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 50ba2ff..a6efbb0 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -21,14 +21,13 @@
 import android.app.ActivityManager.TaskDescription;
 import android.app.FragmentManager;
 import android.content.Intent;
-import android.content.Context;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.CallSuper;
@@ -39,6 +38,7 @@
 
 import com.android.documentsui.ActionModeController;
 import com.android.documentsui.BaseActivity;
+import com.android.documentsui.DocsSelectionHelper;
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
@@ -57,7 +57,6 @@
 import com.android.documentsui.dirlist.AnimationView.AnimationType;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.prefs.ScopedPreferences;
-import com.android.documentsui.selection.SelectionManager;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.sidebar.RootsFragment;
 import com.android.documentsui.ui.DialogController;
@@ -105,7 +104,7 @@
         super.onCreate(icicle);
 
         DocumentClipper clipper = DocumentsApplication.getDocumentClipper(this);
-        mInjector.selectionMgr = new SelectionManager(SelectionManager.MODE_MULTIPLE);
+        mInjector.selectionMgr = DocsSelectionHelper.createMultiSelect();
 
         mInjector.focusManager = new FocusManager(
                 mInjector.features,
@@ -352,6 +351,9 @@
             case R.id.option_menu_select_all:
                 mInjector.actions.selectAllFiles();
                 break;
+            case R.id.option_menu_inspect:
+                mInjector.actions.showInspector(getCurrentDirectory());
+                break;
             default:
                 return super.onOptionsItemSelected(item);
         }
diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java
index 4754c6d..60cf11b 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -29,23 +29,23 @@
 import android.view.View;
 
 import com.android.documentsui.R;
+import com.android.documentsui.MenuManager.SelectionDetails;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.queries.SearchViewManager;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.SelectionHelper;
 
 import java.util.List;
-import java.util.function.Function;
 import java.util.function.IntFunction;
 
 public final class MenuManager extends com.android.documentsui.MenuManager {
 
     private final Features mFeatures;
     private final Context mContext;
-    private final SelectionManager mSelectionManager;
+    private final SelectionHelper mSelectionManager;
     private final Lookup<String, Uri> mUriLookup;
     private final Lookup<String, String> mAppNameLookup;
 
@@ -55,10 +55,12 @@
             State displayState,
             DirectoryDetails dirDetails,
             Context context,
-            SelectionManager selectionManager,
+            SelectionHelper selectionManager,
             Lookup<String, String> appNameLookup,
             Lookup<String, Uri> uriLookup) {
+
         super(searchManager, displayState, dirDetails);
+
         mFeatures = features;
         mContext = context;
         mSelectionManager = selectionManager;
@@ -265,10 +267,16 @@
     }
 
     @Override
-    protected void updateInspector(MenuItem properties, SelectionDetails selectionDetails) {
+    protected void updateInspect(MenuItem inspect) {
+        inspect.setVisible(mFeatures.isInspectorEnabled());
+        inspect.setEnabled(mFeatures.isInspectorEnabled() && !mState.stack.isRecents());
+    }
+
+    @Override
+    protected void updateInspect(MenuItem inspect, SelectionDetails selectionDetails) {
         boolean visible = mFeatures.isInspectorEnabled();
-        properties.setVisible(visible);
-        properties.setEnabled(visible && selectionDetails.size() == 1);
+        inspect.setVisible(visible);
+        inspect.setEnabled(visible && selectionDetails.size() <= 1);
     }
 
     @Override
diff --git a/src/com/android/documentsui/files/QuickViewIntentBuilder.java b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
index 7eef89a..8511065 100644
--- a/src/com/android/documentsui/files/QuickViewIntentBuilder.java
+++ b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
@@ -62,6 +62,7 @@
     private static final String[] FULL_FEATURES = {
             QuickViewConstants.FEATURE_VIEW,
             QuickViewConstants.FEATURE_EDIT,
+            QuickViewConstants.FEATURE_DELETE,
             QuickViewConstants.FEATURE_SEND,
             QuickViewConstants.FEATURE_DOWNLOAD,
             QuickViewConstants.FEATURE_PRINT
diff --git a/src/com/android/documentsui/inspector/DateUtils.java b/src/com/android/documentsui/inspector/DateUtils.java
new file mode 100644
index 0000000..c4138ed
--- /dev/null
+++ b/src/com/android/documentsui/inspector/DateUtils.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import android.text.format.DateFormat;
+import java.util.Locale;
+
+/**
+ * Helper methods for dealing with dates.
+ */
+final class DateUtils {
+    /**
+     * This small helper method combines two different DateFormat subclasses in order to format
+     * both the date and the time based on user locale.
+     * @param date Unix timestamp
+     * @return formatted String of date
+     */
+    static String formatDate(long date) {
+        String format = DateFormat.getBestDateTimePattern(Locale.getDefault(),
+                "MMM dd, yyyy, hh:mm");
+        return DateFormat.format(format, date).toString();
+    }
+}
diff --git a/src/com/android/documentsui/inspector/DebugView.java b/src/com/android/documentsui/inspector/DebugView.java
index 581e754..03427e5 100644
--- a/src/com/android/documentsui/inspector/DebugView.java
+++ b/src/com/android/documentsui/inspector/DebugView.java
@@ -15,18 +15,38 @@
  */
 package com.android.documentsui.inspector;
 
+import android.annotation.StringRes;
 import android.content.Context;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
 import android.util.AttributeSet;
+import android.widget.TextView;
 
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.DummyLookup;
+import com.android.documentsui.base.Lookup;
+import com.android.documentsui.inspector.InspectorController.DebugDisplay;
 
-import java.util.function.Consumer;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
- * Organizes and Displays the basic details about a file
+ * Organizes and Displays the debug information about a file. This view
+ * should only be made visible when build is debuggable and system policies
+ * allow debug "stuff".
  */
-public class DebugView extends TableView implements Consumer<DocumentInfo> {
+public class DebugView extends TableView implements DebugDisplay {
+
+    private final Context mContext;
+    private final Resources mRes;
+    private Lookup<String, Executor> mExecutors = new DummyLookup<>();
 
     public DebugView(Context context) {
         this(context, null);
@@ -38,29 +58,88 @@
 
     public DebugView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
+        mContext = context;
+        mRes = context.getResources();
+    }
+
+    void init(Lookup<String, Executor> executors) {
+        assert executors != null;
+        setBackgroundColor(0xFFFFFFFF);  // it's just debug. We do what we want!
+        mExecutors = executors;
     }
 
     @Override
     public void accept(DocumentInfo info) {
-        setTitle(this, R.string.inspector_debug_section);
+        setTitle(R.string.inspector_debug_section, false);
 
-        put("Content uri", info.derivedUri);
-        put("Document id", info.documentId);
-        put("Mimetype: ", info.mimeType);
-        put("Is archive", info.isArchive());
-        put("Is container", info.isContainer());
-        put("Is partial", info.isPartial());
-        put("Is virtual", info.isVirtual());
-        put("Supports create", info.isCreateSupported());
-        put("Supports delete", info.isDeleteSupported());
-        put("Supports rename", info.isRenameSupported());
-        put("Supports settings", info.isSettingsSupported());
-        put("Supports thumbnail", info.isThumbnailSupported());
-        put("Supports weblink", info.isWeblinkSupported());
-        put("Supports write", info.isWriteSupported());
+        put(R.string.debug_content_uri, info.derivedUri.toString());
+        put(R.string.debug_document_id, info.documentId);
+        put(R.string.debug_raw_mimetype, info.mimeType);
+        put(R.string.debug_stream_types, "-");
+        put(R.string.debug_raw_size, NumberFormat.getInstance().format(info.size));
+        put(R.string.debug_is_archive, info.isArchive());
+        put(R.string.debug_is_container, info.isContainer());
+        put(R.string.debug_is_partial, info.isPartial());
+        put(R.string.debug_is_virtual, info.isVirtual());
+        put(R.string.debug_supports_create, info.isCreateSupported());
+        put(R.string.debug_supports_delete, info.isDeleteSupported());
+        put(R.string.debug_supports_metadata, info.isMetadataSupported());
+        put(R.string.debug_supports_remove, info.isRemoveSupported());
+        put(R.string.debug_supports_rename, info.isRenameSupported());
+        put(R.string.debug_supports_settings, info.isSettingsSupported());
+        put(R.string.debug_supports_thumbnail, info.isThumbnailSupported());
+        put(R.string.debug_supports_weblink, info.isWeblinkSupported());
+        put(R.string.debug_supports_write, info.isWriteSupported());
+
+        // Load Document stream types of the file. For virtual files, this should be
+        // something other than the primary type of the file.
+        Executor executor = mExecutors.lookup(info.derivedUri.getAuthority());
+        if (executor != null) {
+            new AsyncTask<Void, Void, String[]>() {
+                @Override
+                protected String[] doInBackground(Void... params) {
+                    return mContext.getContentResolver().getStreamTypes(info.derivedUri, "*/*");
+                }
+
+                @Override
+                protected void onPostExecute(String[] streamTypes) {
+                    put(R.string.debug_stream_types,
+                            streamTypes != null ? Arrays.toString(streamTypes) : "[]");
+                }
+            }.executeOnExecutor(executor, (Void[]) null);
+        }
     }
 
-    private void put(String key, Object value) {
-        put(key, String.valueOf(value));
+    @Override
+    public void accept(Bundle metadata) {
+        if (metadata == null) {
+            return;
+        }
+
+        String[] types = metadata.getStringArray(DocumentsContract.METADATA_TYPES);
+        if (types == null) {
+            return;
+        }
+
+        for (String type : types) {
+            dumpMetadata(type, metadata.getBundle(type));
+        }
+    }
+
+    private void dumpMetadata(String type, Bundle bundle) {
+        String title = mContext.getResources().getString(
+                R.string.inspector_debug_metadata_section);
+        putTitle(String.format(title, type), true);
+        List<String> keys = new ArrayList<>(bundle.keySet());
+        Collections.sort(keys);
+        for (String key : keys) {
+            put(key, String.valueOf(bundle.get(key)));
+        }
+    }
+
+    private void put(@StringRes int key, boolean value) {
+        KeyValueRow row = put(mRes.getString(key), String.valueOf(value));
+        TextView valueView = ((TextView) row.findViewById(R.id.table_row_value));
+        valueView.setTextColor(value ? 0xFF006400 : 0xFF9A2020);
     }
 }
diff --git a/src/com/android/documentsui/inspector/DetailsView.java b/src/com/android/documentsui/inspector/DetailsView.java
index 5497068..75b3cac 100644
--- a/src/com/android/documentsui/inspector/DetailsView.java
+++ b/src/com/android/documentsui/inspector/DetailsView.java
@@ -16,7 +16,6 @@
 package com.android.documentsui.inspector;
 
 import android.content.Context;
-import android.text.format.DateFormat;
 import android.text.format.Formatter;
 import android.util.AttributeSet;
 
@@ -44,26 +43,33 @@
     }
 
     @Override
-    public void accept(DocumentInfo info) {
+    public void accept(DocumentInfo doc) {
 
         Lookup<String, String> fileTypeLookup =
                 DocumentsApplication.getFileTypeLookup(getContext());
 
-        put(R.string.sort_dimension_file_type, fileTypeLookup.lookup(info.mimeType));
+        String mimeType = fileTypeLookup.lookup(doc.mimeType);
+
+        put(R.string.sort_dimension_file_type, mimeType);
 
         // TODO: Each of these rows need to be removed if the condition is false and previously
         // set.
-        if (info.size > 0) {
-            put(R.string.sort_dimension_size, Formatter.formatFileSize(getContext(), info.size));
+        if (doc.size >= 0 && !doc.isDirectory()) {
+            put(R.string.sort_dimension_size, Formatter.formatFileSize(getContext(), doc.size));
         }
 
-        if (info.lastModified > 0) {
-            put(R.string.sort_dimension_date,
-                    DateFormat.getDateFormat(getContext()).format(info.lastModified));
+        if (doc.lastModified > 0) {
+            put(R.string.sort_dimension_date, DateUtils.formatDate(doc.lastModified));
         }
 
-        if (info.summary != null) {
-            put(R.string.sort_dimension_summary, info.summary);
+        // We only show summary field when doc is partial (meaning an active download).
+        // The rest of the time "summary" tends to be less than useful. For example
+        // after a download is completed DownloadsProvider include the orig filename
+        // in the summary field. This is confusing to folks in-and-if-itself, but
+        // after the file is renamed, it creates even more confusion (since it still
+        // shows the original). For that reason, and others. We only display on partial files.
+        if (doc.isPartial() && doc.summary != null) {
+            put(R.string.sort_dimension_summary, doc.summary);
         }
     }
 
diff --git a/src/com/android/documentsui/inspector/GpsCoordinatesTextClassifier.java b/src/com/android/documentsui/inspector/GpsCoordinatesTextClassifier.java
new file mode 100644
index 0000000..a0a95a2
--- /dev/null
+++ b/src/com/android/documentsui/inspector/GpsCoordinatesTextClassifier.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.LocaleList;
+import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextSelection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Checks if a TextView has a latitude and longitude. If so shows the default maps app to open
+ * those coordinates.
+ *
+ * Example - textView.setTextClassifier(new GpsCoordinatesTextClassifier(context, intent));
+ */
+final class GpsCoordinatesTextClassifier implements TextClassifier {
+
+    // Checks for latitude and longitude points, latitude ranges -90.0 to 90.0 and longitude
+    // ranges -180.0 to 180.0 Valid entries can be of the format "0,0", "0, 0" and "0.0, 0.0"
+    // in the mentioned range.
+    private static final String geoPattern
+        = "-?(90(\\.0*)?|[1-8]?[0-9](\\.[0-9]*)?), *-?(180("
+        + "\\.0*)?|([1][0-7][0-9]|[0-9]?[0-9])(\\.[0-9]*)?)";
+    private static final Pattern sGeoPattern = Pattern.compile(geoPattern);
+
+    private final TextClassifier mSystemClassifier;
+    private final PackageManager mPackageManager;
+
+    public GpsCoordinatesTextClassifier(PackageManager pm, TextClassifier classifier) {
+        assert pm != null;
+        assert classifier != null;
+        mPackageManager = pm;
+        mSystemClassifier = classifier;
+    }
+
+    public static GpsCoordinatesTextClassifier create(Context context) {
+        return new GpsCoordinatesTextClassifier(
+                context.getPackageManager(),
+                context.getSystemService(TextClassificationManager.class).getTextClassifier());
+    }
+
+    // TODO: add support for local specific formatting
+    @Override
+    public TextClassification classifyText(
+            CharSequence text, int start, int end, LocaleList localeList) {
+
+        CharSequence sequence = text.subSequence(start, end);
+        if (isGeoSequence(sequence)) {
+
+            Intent intent = new Intent(Intent.ACTION_VIEW)
+                .setData(Uri.parse(String.format("geo:0,0?q=%s", sequence)));
+
+            final ResolveInfo info = mPackageManager.resolveActivity(intent, 0);
+            if (info != null) {
+
+                return new TextClassification.Builder()
+                        .setText(sequence.toString())
+                        .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
+                        .setIcon(info.loadIcon(mPackageManager))
+                        .setLabel(info.loadLabel(mPackageManager).toString())
+                        .setIntent(intent)
+                        .build();
+            }
+        }
+
+        // return default if text was not latitude, longitude or we couldn't find an application
+        // to handle the geo intent.
+        return mSystemClassifier.classifyText(text, start, end, localeList);
+    }
+
+    @Override
+    public TextSelection suggestSelection(
+        CharSequence context, int start, int end, LocaleList localeList) {
+
+        // Show map action menu popup when entire TextView is selected.
+        final int[] boundaries = {0, context.length()};
+
+        if (boundaries != null) {
+            return new TextSelection.Builder(boundaries[0], boundaries[1])
+                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
+                .build();
+        }
+        return mSystemClassifier.suggestSelection(context, start, end, localeList);
+    }
+
+    private static boolean isGeoSequence(CharSequence text) {
+        return sGeoPattern.matcher(text).matches();
+    }
+}
diff --git a/src/com/android/documentsui/inspector/HeaderTextSelector.java b/src/com/android/documentsui/inspector/HeaderTextSelector.java
new file mode 100644
index 0000000..5530fbe
--- /dev/null
+++ b/src/com/android/documentsui/inspector/HeaderTextSelector.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.text.Spannable;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+
+/**
+ * Selects all or part of a textview.
+ */
+ public final class HeaderTextSelector implements ActionMode.Callback {
+
+    private final TextView mText;
+    private final Selector mSelector;
+
+    public HeaderTextSelector(TextView text, Selector selector) {
+        checkArgument(text != null);
+        checkArgument(selector != null);
+        mText = text;
+        mSelector = selector;
+    }
+
+    // An action mode is created when the user selects text. This method is called where
+    // we force it to select only the filename in the header. Meaning the name of the file would
+    // be selected but the extension would not.
+    @Override
+    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
+        CharSequence value = mText.getText();
+        if (value instanceof Spannable) {
+            mSelector.select((Spannable) value, 0, getLengthOfFilename(value));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
+        return true;
+    }
+
+    @Override
+    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
+        return false;
+    }
+
+    @Override
+    public void onDestroyActionMode(ActionMode actionMode) {}
+
+    /**
+     * Gets the length of the inspector header for selection.
+     *
+     * Example:
+     * filename.txt returns the end index needed to select "filename".
+     *
+     * @return the index of the last character in the filename
+     */
+    private static int getLengthOfFilename(CharSequence text) {
+        String title = text.toString();
+        if (title != null) {
+            int index = title.indexOf('.');
+            if (index > 0) {
+                return index;
+            }
+        }
+
+        return text.length();
+    }
+
+    public interface Selector {
+        void select(Spannable text, int start, int stop);
+    }
+}
diff --git a/src/com/android/documentsui/inspector/HeaderView.java b/src/com/android/documentsui/inspector/HeaderView.java
index 835af77..c411082 100644
--- a/src/com/android/documentsui/inspector/HeaderView.java
+++ b/src/com/android/documentsui/inspector/HeaderView.java
@@ -20,6 +20,8 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.drawable.Drawable;
+import android.text.Selection;
+import android.text.Spannable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -29,18 +31,20 @@
 import android.widget.TextView;
 
 import com.android.documentsui.ProviderExecutor;
+import com.android.documentsui.R;
 import com.android.documentsui.ThumbnailLoader;
 import com.android.documentsui.base.Display;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.R;
+import com.android.documentsui.inspector.InspectorController.HeaderDisplay;
+
 import java.util.function.Consumer;
 
+import javax.annotation.Nullable;
+
 /**
  * Organizes and displays the title and thumbnail for a given document
  */
-public final class HeaderView extends RelativeLayout implements Consumer<DocumentInfo> {
-
-    private static final String TAG = HeaderView.class.getCanonicalName();
+public final class HeaderView extends RelativeLayout implements HeaderDisplay {
 
     private final Context mContext;
     private final View mHeader;
@@ -68,63 +72,55 @@
         int width = (int) Display.screenWidth((Activity)context);
         int height = mContext.getResources().getDimensionPixelSize(R.dimen.inspector_header_height);
         mImageDimensions = new Point(width, height);
+        addView(mHeader);
     }
 
     @Override
-    public void accept(DocumentInfo info) {
-        if (!hasHeader()) {
-            addView(mHeader);
-        }
-
-        if (!hasHeaderImage()) {
-            if (info.isDirectory()) {
-                loadFileIcon(info);
-            } else {
-                loadHeaderImage(info);
-            }
-        }
-        mTitle.setText(info.displayName);
+    public void accept(DocumentInfo info, String displayName) {
+        loadHeaderImage(info);
+        mTitle.setText(displayName);
+        mTitle.setCustomSelectionActionModeCallback(
+                new HeaderTextSelector(mTitle, this::selectText));
     }
 
-    private boolean hasHeader() {
-        for (int i = 0; i < getChildCount(); i++) {
-            if (getChildAt(i).equals(mHeader)) {
-                return true;
-            }
-        }
-        return false;
+    private void selectText(Spannable text, int start, int stop) {
+        Selection.setSelection(text, start, stop);
     }
 
-    private void loadFileIcon(DocumentInfo info) {
-        Drawable mimeIcon = mContext.getContentResolver()
-            .getTypeDrawable(info.mimeType);
-        mThumbnail.setScaleType(ScaleType.FIT_CENTER);
-        mThumbnail.setImageDrawable(mimeIcon);
-    }
-
-    private void loadHeaderImage(DocumentInfo info) {
-
-        Consumer<Bitmap> callback = new Consumer<Bitmap>() {
-            @Override
-            public void accept(Bitmap bitmap) {
-                if (bitmap != null) {
-                    mThumbnail.setScaleType(ScaleType.CENTER_CROP);
-                    mThumbnail.setImageBitmap(bitmap);
-                } else {
-                    loadFileIcon(info);
+    private void loadHeaderImage(DocumentInfo doc) {
+        if (!doc.isThumbnailSupported()) {
+            showImage(doc, null);
+        } else {
+            Consumer<Bitmap> callback = new Consumer<Bitmap>() {
+                @Override
+                public void accept(Bitmap thumbnail) {
+                    showImage(doc, thumbnail);
                 }
-                mThumbnail.animate().alpha(1.0f).start();
-            }
-        };
-
-        // load the thumbnail async.
-        final ThumbnailLoader task = new ThumbnailLoader(info.derivedUri, mThumbnail,
-            mImageDimensions, info.lastModified, callback, false);
-        task.executeOnExecutor(ProviderExecutor.forAuthority(info.derivedUri.getAuthority()),
-            info.derivedUri);
+            };
+            // load the thumbnail async.
+            final ThumbnailLoader task = new ThumbnailLoader(doc.derivedUri, mThumbnail,
+                    mImageDimensions, doc.lastModified, callback, false);
+            task.executeOnExecutor(ProviderExecutor.forAuthority(doc.derivedUri.getAuthority()),
+                    doc.derivedUri);
+        }
     }
 
-    private boolean hasHeaderImage() {
-        return mThumbnail.getAlpha() == 1.0f;
+    /**
+     * Shows the supplied image, falling back to a mimetype icon if the image is null.
+     */
+    private void showImage(DocumentInfo info, @Nullable Bitmap thumbnail) {
+        if (thumbnail != null) {
+            mThumbnail.resetPaddingToInitialValues();
+            mThumbnail.setScaleType(ScaleType.CENTER_CROP);
+            mThumbnail.setImageBitmap(thumbnail);
+        } else {
+            mThumbnail.setPadding(0, 0, 0, mTitle.getHeight());
+
+            Drawable mimeIcon =
+                    mContext.getContentResolver().getTypeDrawable(info.mimeType);
+            mThumbnail.setScaleType(ScaleType.FIT_CENTER);
+            mThumbnail.setImageDrawable(mimeIcon);
+        }
+        mThumbnail.animate().alpha(1.0f).start();
     }
 }
\ No newline at end of file
diff --git a/src/com/android/documentsui/inspector/InspectorActivity.java b/src/com/android/documentsui/inspector/InspectorActivity.java
index 44af735..d02c43b 100644
--- a/src/com/android/documentsui/inspector/InspectorActivity.java
+++ b/src/com/android/documentsui/inspector/InspectorActivity.java
@@ -33,7 +33,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_ACTION_BAR);
-        setContentView(R.layout.document_inspector_activity);
+        setContentView(R.layout.inspector_activity);
 
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
         setActionBar(toolbar);
@@ -45,10 +45,7 @@
 
         if (mFragment == null) {
             Intent intent = getIntent();
-
             mFragment = InspectorFragment.newInstance(intent);
-
-
             fragmentManager.beginTransaction()
                     .add(R.id.fragment_container, mFragment)
                     .commit();
diff --git a/src/com/android/documentsui/inspector/InspectorController.java b/src/com/android/documentsui/inspector/InspectorController.java
index 2b1c4b4..79612f9 100644
--- a/src/com/android/documentsui/inspector/InspectorController.java
+++ b/src/com/android/documentsui/inspector/InspectorController.java
@@ -15,59 +15,69 @@
  */
 package com.android.documentsui.inspector;
 
-import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_SETTINGS;
 import static com.android.internal.util.Preconditions.checkArgument;
 
+import android.annotation.StringRes;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 import android.view.View;
 import android.view.View.OnClickListener;
+
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.ProviderExecutor;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Lookup;
+import com.android.documentsui.base.Shared;
 import com.android.documentsui.inspector.actions.Action;
 import com.android.documentsui.inspector.actions.ClearDefaultAppAction;
 import com.android.documentsui.inspector.actions.ShowInProviderAction;
 import com.android.documentsui.roots.ProvidersAccess;
 import com.android.documentsui.ui.Snackbars;
-import java.util.concurrent.Executor;
+
 import java.util.function.Consumer;
 /**
  * A controller that coordinates retrieving document information and sending it to the view.
  */
 public final class InspectorController {
 
-    private final Loader mLoader;
-    private final Consumer<DocumentInfo> mHeader;
+    private final DataSupplier mLoader;
+    private final HeaderDisplay mHeader;
     private final DetailsDisplay mDetails;
+    private final MediaDisplay mMedia;
     private final ActionDisplay mShowProvider;
     private final ActionDisplay mAppDefaults;
-    private final Consumer<DocumentInfo> mDebugView;
-    private final boolean mShowDebug;
+    private final DebugDisplay mDebugView;
     private final Context mContext;
     private final PackageManager mPackageManager;
     private final ProvidersAccess mProviders;
-    private final Runnable mShowSnackbar;
-    private final Lookup<String, Executor> mExecutors;
+    private final Runnable mErrorSnackbar;
+    private Bundle mArgs;
 
     /**
      * InspectorControllerTest relies on this controller.
      */
     @VisibleForTesting
-    public InspectorController(Context context, Loader loader, PackageManager pm,
-            ProvidersAccess providers, boolean showDebug, Consumer<DocumentInfo> header,
-            DetailsDisplay details, ActionDisplay showProvider, ActionDisplay appDefaults,
-            Consumer<DocumentInfo> debugView, Lookup<String, Executor> executors,
-            Runnable showSnackbar) {
+    public InspectorController(
+            Context context,
+            DataSupplier loader,
+            PackageManager pm,
+            ProvidersAccess providers,
+            HeaderDisplay header,
+            DetailsDisplay details,
+            MediaDisplay media,
+            ActionDisplay showProvider,
+            ActionDisplay appDefaults,
+            DebugDisplay debugView,
+            Bundle args,
+            Runnable errorRunnable) {
 
         checkArgument(context != null);
         checkArgument(loader != null);
@@ -75,46 +85,57 @@
         checkArgument(providers != null);
         checkArgument(header != null);
         checkArgument(details != null);
+        checkArgument(media != null);
         checkArgument(showProvider != null);
         checkArgument(appDefaults != null);
         checkArgument(debugView != null);
-        checkArgument(showSnackbar != null);
-        checkArgument(executors != null);
+        checkArgument(args != null);
+        checkArgument(errorRunnable != null);
 
         mContext = context;
         mLoader = loader;
         mPackageManager = pm;
-        mShowDebug = showDebug;
         mProviders = providers;
         mHeader = header;
         mDetails = details;
+        mMedia = media;
         mShowProvider = showProvider;
         mAppDefaults = appDefaults;
+        mArgs = args;
         mDebugView = debugView;
-        mExecutors = executors;
-        mShowSnackbar = showSnackbar;
+
+        mErrorSnackbar = errorRunnable;
     }
 
-    public InspectorController(Activity activity, Loader loader, View layout, boolean showDebug) {
-
+    /**
+     * @param activity
+     * @param loader
+     * @param layout
+     * @param args Bundle of arguments passed to our host {@link InspectorFragment}. These
+     *     can include extras that enable debug mode ({@link Shared#EXTRA_SHOW_DEBUG}
+     *     and override the file title (@link {@link Intent#EXTRA_TITLE}).
+     */
+    public InspectorController(Activity activity, DataSupplier loader, View layout, Bundle args) {
         this(activity,
-                loader,
-                activity.getPackageManager(),
-                DocumentsApplication.getProvidersCache (activity),
-                showDebug,
-                (HeaderView) layout.findViewById(R.id.inspector_header_view),
-                (DetailsView) layout.findViewById(R.id.inspector_details_view),
-                (ActionDisplay) layout.findViewById(R.id.inspector_show_in_provider_view),
-                (ActionDisplay) layout.findViewById(R.id.inspector_app_defaults_view),
-                (DebugView) layout.findViewById(R.id.inspector_debug_view),
-                ProviderExecutor::forAuthority,
-                () -> {
-                    // using a runnable to support unit testing this feature.
-                    Snackbars.showInspectorError(activity);
-                }
+            loader,
+            activity.getPackageManager(),
+            DocumentsApplication.getProvidersCache (activity),
+            (HeaderView) layout.findViewById(R.id.inspector_header_view),
+            (DetailsView) layout.findViewById(R.id.inspector_details_view),
+            (MediaView) layout.findViewById(R.id.inspector_media_view),
+            (ActionDisplay) layout.findViewById(R.id.inspector_show_in_provider_view),
+            (ActionDisplay) layout.findViewById(R.id.inspector_app_defaults_view),
+            (DebugView) layout.findViewById(R.id.inspector_debug_view),
+            args,
+            () -> {
+                // using a runnable to support unit testing this feature.
+                Snackbars.showInspectorError(activity);
+            }
         );
-        if (showDebug) {
-            layout.findViewById(R.id.inspector_debug_view).setVisibility(View.VISIBLE);
+
+        if (args.getBoolean(Shared.EXTRA_SHOW_DEBUG)) {
+            DebugView view = (DebugView) layout.findViewById(R.id.inspector_debug_view);
+            view.init(ProviderExecutor::forAuthority);
         }
     }
 
@@ -129,13 +150,11 @@
     /**
      * Updates the view with documentInfo.
      */
-    @Nullable
-    public void updateView(@Nullable DocumentInfo docInfo) {
-
+    private void updateView(@Nullable DocumentInfo docInfo) {
         if (docInfo == null) {
-            mShowSnackbar.run();
+            mErrorSnackbar.run();
         } else {
-            mHeader.accept(docInfo);
+            mHeader.accept(docInfo, mArgs.getString(Intent.EXTRA_TITLE, docInfo.displayName));
             mDetails.accept(docInfo);
 
             if (docInfo.isDirectory()) {
@@ -147,28 +166,62 @@
                     Action showProviderAction =
                         new ShowInProviderAction(mContext, mPackageManager, docInfo, mProviders);
                     mShowProvider.init(
-                            showProviderAction,
-                            (view) -> {
-                                showInProvider(docInfo.derivedUri);
-                            });
+                        showProviderAction,
+                        (view) -> {
+                            showInProvider(docInfo.derivedUri);
+                        });
                 }
 
                 Action defaultAction =
-                        new ClearDefaultAppAction(mContext, mPackageManager, docInfo);
+                    new ClearDefaultAppAction(mContext, mPackageManager, docInfo);
 
                 mAppDefaults.setVisible(defaultAction.canPerformAction());
                 if (defaultAction.canPerformAction()) {
                     mAppDefaults.init(
-                            defaultAction,
-                            (View) -> {
-                                clearDefaultApp(defaultAction.getPackageName());
-                            });
+                        defaultAction,
+                        (View) -> {
+                            clearDefaultApp(defaultAction.getPackageName());
+                        });
                 }
             }
 
-            if (mShowDebug) {
+            if (docInfo.isMetadataSupported()) {
+                mLoader.getDocumentMetadata(
+                        docInfo.derivedUri,
+                        (Bundle bundle) -> {
+                            onDocumentMetadataLoaded(docInfo, bundle);
+                        });
+            }
+            mMedia.setVisible(!mMedia.isEmpty());
+
+            if (mArgs.getBoolean(Shared.EXTRA_SHOW_DEBUG)) {
                 mDebugView.accept(docInfo);
             }
+            mDebugView.setVisible(mArgs.getBoolean(Shared.EXTRA_SHOW_DEBUG)
+                    && !mDebugView.isEmpty());
+        }
+    }
+
+    private void onDocumentMetadataLoaded(DocumentInfo doc, @Nullable Bundle metadata) {
+        if (metadata == null) {
+            return;
+        }
+
+        Runnable geoClickListener = null;
+        if (MetadataUtils.hasGeoCoordinates(metadata)) {
+            float[] coords = MetadataUtils.getGeoCoordinates(metadata);
+            final Intent intent = createGeoIntent(coords[0], coords[1], doc.displayName);
+            if (hasHandler(intent)) {
+                geoClickListener = () -> {
+                    startActivity(intent);
+                };
+            }
+        }
+
+        mMedia.accept(doc, metadata, geoClickListener);
+
+        if (mArgs.getBoolean(Shared.EXTRA_SHOW_DEBUG)) {
+            mDebugView.accept(metadata);
         }
     }
 
@@ -181,6 +234,31 @@
         mDetails.setChildrenCount(count);
     }
 
+    private void startActivity(Intent intent) {
+        assert hasHandler(intent);
+        mContext.startActivity(intent);
+    }
+
+    /**
+     * checks that we can handle a geo-intent.
+     */
+    private boolean hasHandler(Intent intent) {
+        return mPackageManager.resolveActivity(intent, 0) != null;
+    }
+
+    /**
+     * Creates a geo-intent for opening a location in maps.
+     *
+     * @see https://developer.android.com/guide/components/intents-common.html#Maps
+     */
+    private static Intent createGeoIntent(
+            float latitude, float longitude, @Nullable String label) {
+        label = Uri.encode(label == null ? "" : label);
+        String data = "geo:0,0?q=" + latitude + " " + longitude + "(" + label + ")";
+        Uri uri = Uri.parse(data);
+        return new Intent(Intent.ACTION_VIEW, uri);
+    }
+
     /**
      * Shows the selected document in it's content provider.
      *
@@ -210,9 +288,10 @@
     }
 
     /**
-     * Interface for loading document metadata.
+     * Interface for loading all the various forms of document data. This primarily
+     * allows us to easily supply test data in tests.
      */
-    public interface Loader {
+    public interface DataSupplier {
 
         /**
          * Starts the Asynchronous process of loading file data.
@@ -235,12 +314,28 @@
          * Deletes all loader id's when android lifecycle ends.
          */
         void reset();
+
+        /**
+         * @param uri
+         * @param callback
+         */
+        void getDocumentMetadata(Uri uri, Consumer<Bundle> callback);
     }
 
     /**
      * This interface is for unit testing.
      */
-    public interface ActionDisplay {
+    public interface Display {
+        /**
+         * Makes the action visible.
+         */
+        void setVisible(boolean visible);
+    }
+
+    /**
+     * This interface is for unit testing.
+     */
+    public interface ActionDisplay extends Display {
 
         /**
          * Initializes the view based on the action.
@@ -249,11 +344,6 @@
          */
         void init(Action action, OnClickListener listener);
 
-        /**
-         * Makes the action visible.
-         */
-        void setVisible(boolean visible);
-
         void setActionHeader(String header);
 
         void setAppIcon(Drawable icon);
@@ -266,10 +356,63 @@
     /**
      * Provides details about a file.
      */
+    public interface HeaderDisplay {
+        void accept(DocumentInfo info, String displayName);
+    }
+
+    /**
+     * Provides basic details about a file.
+     */
     public interface DetailsDisplay {
 
         void accept(DocumentInfo info);
 
         void setChildrenCount(int count);
     }
+
+    /**
+     * Provides details about a media file.
+     */
+    public interface MediaDisplay extends Display {
+        void accept(DocumentInfo info, Bundle metadata, @Nullable Runnable geoClickListener);
+
+        /**
+         * Returns true if there are now rows in the display. Does not consider the title.
+         */
+        boolean isEmpty();
+    }
+
+    /**
+     * Provides details about a media file.
+     */
+    public interface DebugDisplay extends Display {
+        void accept(DocumentInfo info);
+        void accept(Bundle metadata);
+
+        /**
+         * Returns true if there are now rows in the display. Does not consider the title.
+         */
+        boolean isEmpty();
+    }
+
+    /**
+     * Displays a table of image metadata.
+     */
+    public interface TableDisplay extends Display {
+
+        /**
+         * Adds a row in the table.
+         */
+        void put(@StringRes int keyId, CharSequence value);
+
+        /**
+         * Adds a row in the table and makes it clickable.
+         */
+        void put(@StringRes int keyId, CharSequence value, OnClickListener callback);
+
+        /**
+         * Returns true if there are now rows in the display. Does not consider the title.
+         */
+        boolean isEmpty();
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/documentsui/inspector/InspectorFragment.java b/src/com/android/documentsui/inspector/InspectorFragment.java
index ef7c3b1..b2fd155 100644
--- a/src/com/android/documentsui/inspector/InspectorFragment.java
+++ b/src/com/android/documentsui/inspector/InspectorFragment.java
@@ -27,8 +27,7 @@
 import android.widget.ScrollView;
 
 import com.android.documentsui.R;
-import com.android.documentsui.base.Shared;
-import com.android.documentsui.inspector.InspectorController.Loader;
+import com.android.documentsui.inspector.InspectorController.DataSupplier;
 
 /**
  * Displays the Properties view in Files.
@@ -47,12 +46,11 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
         Bundle savedInstanceState) {
-        final Loader loader = new DocumentLoader(getActivity(), getLoaderManager());
+        final DataSupplier loader = new RuntimeDataSupplier(getActivity(), getLoaderManager());
 
-        mView = (ScrollView) inflater.inflate(R.layout.document_inspector_fragment,
+        mView = (ScrollView) inflater.inflate(R.layout.inspector_fragment,
                 container, false);
-        boolean showDebug = (boolean) getArguments().get(Shared.EXTRA_SHOW_DEBUG);
-        mController = new InspectorController(getActivity(), loader, mView, showDebug);
+        mController = new InspectorController(getActivity(), loader, mView, getArguments());
         return mView;
     }
 
@@ -70,16 +68,17 @@
     }
 
     /**
-     * Creates a fragment and sets a Uri as an argument.
+     * Creates a fragment with the appropriate args.
      */
     public static InspectorFragment newInstance(Intent intent) {
-        Uri uri = intent.getData();
-        boolean showDebug = intent.getBooleanExtra(Shared.EXTRA_SHOW_DEBUG, false);
 
+        Bundle extras = intent.getExtras();
+        extras = extras != null ? extras : Bundle.EMPTY;
+        Bundle args = extras.deepCopy();
+
+        Uri uri = intent.getData();
         checkArgument(uri.getScheme().equals("content"));
-        Bundle args = new Bundle();
         args.putParcelable(DOC_URI_ARG, uri);
-        args.putBoolean(Shared.EXTRA_SHOW_DEBUG, showDebug);
 
         InspectorFragment fragment = new InspectorFragment();
         fragment.setArguments(args);
diff --git a/src/com/android/documentsui/inspector/KeyValueRow.java b/src/com/android/documentsui/inspector/KeyValueRow.java
index 45a6e05..48801d5 100644
--- a/src/com/android/documentsui/inspector/KeyValueRow.java
+++ b/src/com/android/documentsui/inspector/KeyValueRow.java
@@ -15,12 +15,17 @@
  */
 package com.android.documentsui.inspector;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
 import android.annotation.StringRes;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
+import android.graphics.Paint;
+import android.support.annotation.Nullable;
+import android.text.Selection;
+import android.text.Spannable;
 import android.util.AttributeSet;
+import android.view.View;
+import android.view.textclassifier.TextClassifier;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
@@ -32,6 +37,8 @@
 public class KeyValueRow extends LinearLayout {
 
     private final Resources mRes;
+    private @Nullable ColorStateList mDefaultTextColor;
+    private @Nullable TextClassifier mClassifier;
 
     public KeyValueRow(Context context) {
         this(context, null);
@@ -43,15 +50,18 @@
 
     public KeyValueRow(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-
         mRes = context.getResources();
     }
 
+    public void setTextClassifier(TextClassifier classifier) {
+        mClassifier = classifier;
+    }
+
     /**
      * Sets the raw value of the key. Only localized values
      * should be passed.
      */
-    public void setKey(String key) {
+    public void setKey(CharSequence key) {
         ((TextView) findViewById(R.id.table_row_key)).setText(key);
     }
 
@@ -59,7 +69,38 @@
         setKey(mRes.getString(id));
     }
 
-    public void setValue(String value) {
-        ((TextView) findViewById(R.id.table_row_value)).setText(value);
+    public void setValue(CharSequence value) {
+        TextView text = ((TextView) findViewById(R.id.table_row_value));
+        text.setText(value);
+        text.setTextClassifier(mClassifier);
+        text.setOnLongClickListener((View view) -> {
+
+            CharSequence textValue = text.getText();
+            if (textValue instanceof Spannable) {
+                Spannable spn = (Spannable) textValue;
+                Selection.selectAll(spn);
+            }
+            // we still want the default selection arrows and menu after we specified to select
+            // all text in the TextView.
+            return false;
+        });
+    }
+
+    @Override
+    public void setOnClickListener(OnClickListener callback) {
+        TextView clickable = ((TextView) findViewById(R.id.table_row_value));
+        mDefaultTextColor = clickable.getTextColors();
+        clickable.setTextColor(R.color.inspector_link);
+        clickable.setPaintFlags(clickable.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+        clickable.setOnClickListener(callback);
+    }
+
+    public void removeOnClickListener() {
+        TextView reset = ((TextView) findViewById(R.id.table_row_value));
+        if (mDefaultTextColor != null) {
+            reset.setTextColor(mDefaultTextColor);
+        }
+        reset.setPaintFlags(reset.getPaintFlags() & ~Paint.UNDERLINE_TEXT_FLAG);
+        reset.setOnClickListener(null);
     }
 }
diff --git a/src/com/android/documentsui/inspector/MediaView.java b/src/com/android/documentsui/inspector/MediaView.java
new file mode 100644
index 0000000..b2ae758
--- /dev/null
+++ b/src/com/android/documentsui/inspector/MediaView.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.location.Address;
+import android.location.Geocoder;
+import android.media.ExifInterface;
+import android.media.MediaMetadata;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.annotation.VisibleForTesting;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+
+import com.android.documentsui.R;
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.inspector.InspectorController.MediaDisplay;
+import com.android.documentsui.inspector.InspectorController.TableDisplay;
+
+import java.io.IOException;
+import java.util.function.Consumer;
+
+import javax.annotation.Nullable;
+
+/**
+ * Organizes and Displays the debug information about a file. This view
+ * should only be made visible when build is debuggable and system policies
+ * allow debug "stuff".
+ */
+public class MediaView extends TableView implements MediaDisplay {
+
+    private final Resources mResources;
+    private final Context mContext;
+
+    public MediaView(Context context) {
+        this(context, null);
+    }
+
+    public MediaView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public MediaView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        mContext = context;
+        mResources = context.getResources();
+    }
+
+    @Override
+    public void accept(DocumentInfo doc, Bundle metadata, @Nullable Runnable geoClickListener) {
+        setTitle(R.string.inspector_metadata_section, true);
+
+        Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
+        if (exif != null) {
+            showExifData(this, mResources, doc, exif, geoClickListener, this::getAddress);
+        }
+
+        Bundle video = metadata.getBundle(Shared.METADATA_KEY_VIDEO);
+        if (video != null) {
+            showVideoData(this, mResources, doc, video, geoClickListener);
+        }
+
+        Bundle audio = metadata.getBundle(Shared.METADATA_KEY_AUDIO);
+        if (audio != null) {
+            showAudioData(this, audio);
+        }
+
+        setVisible(!isEmpty());
+    }
+
+    @VisibleForTesting
+    public static void showAudioData(TableDisplay table, Bundle tags) {
+
+        if (tags.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+            table.put(R.string.metadata_artist, tags.getString(MediaMetadata.METADATA_KEY_ARTIST));
+        }
+
+        if (tags.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) {
+            table.put(R.string.metadata_composer,
+                    tags.getString(MediaMetadata.METADATA_KEY_COMPOSER));
+        }
+
+        if (tags.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) {
+            table.put(R.string.metadata_album, tags.getString(MediaMetadata.METADATA_KEY_ALBUM));
+        }
+
+        if (tags.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+            int millis = tags.getInt(MediaMetadata.METADATA_KEY_DURATION);
+            table.put(R.string.metadata_duration, DateUtils.formatElapsedTime(millis / 1000));
+        }
+    }
+
+    @VisibleForTesting
+    public static void showVideoData(
+            TableDisplay table,
+            Resources resources,
+            DocumentInfo doc,
+            Bundle tags,
+            @Nullable Runnable geoClickListener) {
+
+        addDimensionsRow(table, resources, tags);
+
+        if (MetadataUtils.hasVideoCoordinates(tags)) {
+            float[] coords = MetadataUtils.getVideoCoords(tags);
+            showCoordiantes(table, resources, coords, geoClickListener);
+        }
+
+        if (tags.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+            int millis = tags.getInt(MediaMetadata.METADATA_KEY_DURATION);
+            table.put(R.string.metadata_duration, DateUtils.formatElapsedTime(millis / 1000));
+        }
+    }
+
+    @VisibleForTesting
+    public static void showExifData(
+            TableDisplay table,
+            Resources resources,
+            DocumentInfo doc,
+            Bundle tags,
+            @Nullable Runnable geoClickListener,
+            Consumer<float[]> geoAddressFetcher) {
+
+        addDimensionsRow(table, resources, tags);
+
+        if (tags.containsKey(ExifInterface.TAG_DATETIME)) {
+            String date = tags.getString(ExifInterface.TAG_DATETIME);
+            table.put(R.string.metadata_date_time, date);
+        }
+
+        if (tags.containsKey(ExifInterface.TAG_GPS_ALTITUDE)) {
+            double altitude = tags.getDouble(ExifInterface.TAG_GPS_ALTITUDE);
+            table.put(R.string.metadata_altitude, String.valueOf(altitude));
+        }
+
+        if (tags.containsKey(ExifInterface.TAG_MAKE) || tags.containsKey(ExifInterface.TAG_MODEL)) {
+                String make = tags.getString(ExifInterface.TAG_MAKE);
+                String model = tags.getString(ExifInterface.TAG_MODEL);
+                make = make != null ? make : "";
+                model = model != null ? model : "";
+                table.put(
+                        R.string.metadata_camera,
+                        resources.getString(R.string.metadata_camera_format, make, model));
+        }
+
+        if (tags.containsKey(ExifInterface.TAG_APERTURE)) {
+            table.put(R.string.metadata_aperture, resources.getString(
+                    R.string.metadata_aperture_format, tags.getDouble(ExifInterface.TAG_APERTURE)));
+        }
+
+        if (tags.containsKey(ExifInterface.TAG_SHUTTER_SPEED_VALUE)) {
+            String shutterSpeed = String.valueOf(
+                    formatShutterSpeed(tags.getDouble(ExifInterface.TAG_SHUTTER_SPEED_VALUE)));
+            table.put(R.string.metadata_shutter_speed, shutterSpeed);
+        }
+
+        if (tags.containsKey(ExifInterface.TAG_FOCAL_LENGTH)) {
+            double length = tags.getDouble(ExifInterface.TAG_FOCAL_LENGTH);
+            table.put(R.string.metadata_focal_length,
+                    String.format(resources.getString(R.string.metadata_focal_format), length));
+        }
+
+        if (tags.containsKey(ExifInterface.TAG_ISO_SPEED_RATINGS)) {
+            int iso = tags.getInt(ExifInterface.TAG_ISO_SPEED_RATINGS);
+            table.put(R.string.metadata_iso_speed_ratings,
+                    String.format(resources.getString(R.string.metadata_iso_format), iso));
+        }
+
+        if (MetadataUtils.hasExifGpsFields(tags)) {
+            float[] coords = MetadataUtils.getExifGpsCoords(tags);
+            showCoordiantes(table, resources, coords, geoClickListener);
+            geoAddressFetcher.accept(coords);
+        }
+    }
+
+    private static void showCoordiantes(
+            TableDisplay table,
+            Resources resources,
+            float[] coords,
+            @Nullable Runnable geoClickListener) {
+
+        String value = resources.getString(
+                R.string.metadata_coordinates_format, coords[0], coords[1]);
+        if (geoClickListener != null) {
+            table.put(
+                    R.string.metadata_coordinates,
+                    value,
+                    view -> {
+                        geoClickListener.run();
+                    }
+            );
+        } else {
+            table.put(R.string.metadata_coordinates, value);
+        }
+    }
+
+    /**
+     * Attempts to retrieve an approximate address and displays the address if it can find one.
+     * @param coords the coordinates that gets an address.
+     */
+    private void getAddress(float[] coords) {
+        new AsyncTask<Float, Void, Address>() {
+            @Override
+            protected Address doInBackground(Float... coords) {
+                assert (coords.length == 2);
+                Geocoder geocoder = new Geocoder(mContext);
+                try {
+                    Address address = geocoder.getFromLocation(coords[0], // latitude
+                            coords[1], // longitude
+                            1 // amount of results returned
+                    ).get(0);
+                    return address;
+                } catch (IOException e) {
+                    return null;
+                }
+            }
+            @Override
+            protected void onPostExecute(@Nullable Address address) {
+                if (address != null) {
+                    TableDisplay table = MediaView.this;
+                    if (address.getMaxAddressLineIndex() >= 0) {
+                        String formattedAddress;
+                        StringBuilder addressBuilder = new StringBuilder("");
+                        addressBuilder.append(address.getAddressLine(0));
+                        for (int i = 1; i < address.getMaxAddressLineIndex(); i++) {
+                            addressBuilder.append("\n");
+                            addressBuilder.append(address.getAddressLine(i));
+                        }
+                        formattedAddress = addressBuilder.toString();
+                        table.put(R.string.metadata_address, formattedAddress);
+                    } else if (address.getLocality() != null) {
+                        table.put(R.string.metadata_address, address.getLocality());
+                    } else if (address.getSubAdminArea() != null) {
+                        table.put(R.string.metadata_address, address.getSubAdminArea());
+                    } else if (address.getAdminArea() != null) {
+                        table.put(R.string.metadata_address, address.getAdminArea());
+                    } else if (address.getCountryName() != null) {
+                        table.put(R.string.metadata_address, address.getCountryName());
+                    }                }
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, coords[0], coords[1]);
+    }
+
+    /**
+     * @param speed a value n, where shutter speed equals 1/(2^n)
+     * @return a String containing either a fraction that displays 1 over a positive integer, or a
+     * double rounded to one decimal, depending on if 1/(2^n) is less than or greater than 1,
+     * respectively.
+     */
+    private static String formatShutterSpeed(double speed) {
+        if (speed <= 0) {
+            double shutterSpeed = Math.pow(2, -1 * speed);
+            String formattedSpeed = String.valueOf(Math.round(shutterSpeed * 10.0) / 10.0);
+            return formattedSpeed;
+        } else {
+            int approximateSpeedDenom = (int) Math.pow(2, speed) + 1;
+            String formattedSpeed = "1/" + String.valueOf(approximateSpeedDenom);
+            return formattedSpeed;
+        }
+    }
+
+    /**
+     * @param table
+     * @param resources
+     * @param tags
+     */
+    private static void addDimensionsRow(TableDisplay table, Resources resources, Bundle tags) {
+        if (tags.containsKey(ExifInterface.TAG_IMAGE_WIDTH)
+            && tags.containsKey(ExifInterface.TAG_IMAGE_LENGTH)) {
+            int width = tags.getInt(ExifInterface.TAG_IMAGE_WIDTH);
+            int height = tags.getInt(ExifInterface.TAG_IMAGE_LENGTH);
+            float megaPixels = height * width / 1000000f;
+            table.put(R.string.metadata_dimensions,
+                    resources.getString(
+                            R.string.metadata_dimensions_format, width, height, megaPixels));
+        }
+    }
+}
diff --git a/src/com/android/documentsui/inspector/MetadataLoader.java b/src/com/android/documentsui/inspector/MetadataLoader.java
new file mode 100644
index 0000000..3de15ba
--- /dev/null
+++ b/src/com/android/documentsui/inspector/MetadataLoader.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import android.content.AsyncTaskLoader;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+
+/**
+ * Loads metadata from {@link DocumentsContract#getDocumentMetadata(android.content.ContentProviderClient, Uri, String[])}
+ */
+final class MetadataLoader extends AsyncTaskLoader<Bundle> {
+
+    private static final String TAG = "MetadataLoader";
+
+    private final Context mContext;
+    private final Uri mUri;
+
+    private @Nullable Bundle mMetadata;
+
+    MetadataLoader(Context context, Uri uri) {
+        super(context);
+        mContext = context;
+        mUri = uri;
+    }
+
+    @Override
+    public Bundle loadInBackground() {
+        try {
+            return DocumentsContract.getDocumentMetadata(mContext.getContentResolver(), mUri);
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "Failed to load metadata for doc: " + mUri, e);
+        }
+
+        return null;
+    }
+
+    @Override
+    protected void onStartLoading() {
+        if (mMetadata != null) {
+            deliverResult(mMetadata);
+        }
+        if (takeContentChanged() || mMetadata == null) {
+            forceLoad();
+        }
+    }
+
+    @Override
+    public void deliverResult(Bundle metadata) {
+        if (isReset()) {
+            return;
+        }
+        mMetadata = metadata;
+        if (isStarted()) {
+            super.deliverResult(metadata);
+        }
+    }
+
+    /**
+     * Must be called from the UI thread
+     */
+    @Override
+    protected void onStopLoading() {
+        // Attempt to cancel the current load task if possible.
+        cancelLoad();
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+
+        // Ensure the loader is stopped
+        onStopLoading();
+
+        mMetadata = null;
+    }
+}
diff --git a/src/com/android/documentsui/inspector/MetadataUtils.java b/src/com/android/documentsui/inspector/MetadataUtils.java
new file mode 100644
index 0000000..b5c1034
--- /dev/null
+++ b/src/com/android/documentsui/inspector/MetadataUtils.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.media.ExifInterface;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+
+import com.android.documentsui.base.Shared;
+
+import javax.annotation.Nullable;
+
+final class MetadataUtils {
+
+    private MetadataUtils() {}
+
+    static boolean hasGeoCoordinates(@Nullable Bundle metadata) {
+        if (metadata == null) {
+            return false;
+        }
+        return hasVideoCoordinates(metadata.getBundle(Shared.METADATA_KEY_VIDEO))
+                || hasExifGpsFields(metadata.getBundle(DocumentsContract.METADATA_EXIF));
+    }
+
+    static boolean hasVideoCoordinates(@Nullable Bundle data) {
+        return data != null && (data.containsKey(Shared.METADATA_VIDEO_LATITUDE)
+                && data.containsKey(Shared.METADATA_VIDEO_LONGITUTE));
+    }
+
+    static boolean hasExifGpsFields(@Nullable Bundle exif) {
+        return exif != null && (exif.containsKey(ExifInterface.TAG_GPS_LATITUDE)
+                && exif.containsKey(ExifInterface.TAG_GPS_LONGITUDE)
+                && exif.containsKey(ExifInterface.TAG_GPS_LATITUDE_REF)
+                && exif.containsKey(ExifInterface.TAG_GPS_LONGITUDE_REF));
+    }
+
+    static float[] getGeoCoordinates(Bundle metadata) {
+        assert hasGeoCoordinates(metadata);
+        checkNotNull(metadata);
+
+        Bundle bundle = metadata.getBundle(DocumentsContract.METADATA_EXIF);
+        if (hasExifGpsFields(bundle)) {
+            return getExifGpsCoords(bundle);
+        }
+
+        bundle = metadata.getBundle(Shared.METADATA_KEY_VIDEO);
+        if (hasVideoCoordinates(bundle)) {
+            return getVideoCoords(bundle);
+        }
+
+        // This should never happen, because callers should always check w/ hasGeoCoordinates first.
+        throw new IllegalArgumentException("Invalid metadata bundle: " + metadata);
+    }
+
+    static float[] getExifGpsCoords(Bundle exif) {
+        assert hasExifGpsFields(exif);
+
+        String lat = exif.getString(ExifInterface.TAG_GPS_LATITUDE);
+        String lon = exif.getString(ExifInterface.TAG_GPS_LONGITUDE);
+        String latRef = exif.getString(ExifInterface.TAG_GPS_LATITUDE_REF);
+        String lonRef = exif.getString(ExifInterface.TAG_GPS_LONGITUDE_REF);
+
+        return new float[] {
+            ExifInterface.convertRationalLatLonToFloat(lat, latRef),
+            ExifInterface.convertRationalLatLonToFloat(lon, lonRef)
+        };
+    }
+
+    static float[] getVideoCoords(Bundle data) {
+        assert hasVideoCoordinates(data);
+        return new float[] {
+                data.getFloat(Shared.METADATA_VIDEO_LATITUDE),
+                data.getFloat(Shared.METADATA_VIDEO_LONGITUTE)
+        };
+    }
+}
diff --git a/src/com/android/documentsui/inspector/DocumentLoader.java b/src/com/android/documentsui/inspector/RuntimeDataSupplier.java
similarity index 77%
rename from src/com/android/documentsui/inspector/DocumentLoader.java
rename to src/com/android/documentsui/inspector/RuntimeDataSupplier.java
index 9c92b1c..bb8998b 100644
--- a/src/com/android/documentsui/inspector/DocumentLoader.java
+++ b/src/com/android/documentsui/inspector/RuntimeDataSupplier.java
@@ -27,32 +27,35 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-
 import android.provider.DocumentsContract;
 import android.support.annotation.Nullable;
+
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.inspector.InspectorController.Loader;
+import com.android.documentsui.inspector.InspectorController.DataSupplier;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Consumer;
 
 /**
- * Asynchronously loads a document's metadata for the inspector.
+ * Asynchronously loads a document data for the inspector.
+ *
+ * <p>This loader is not a Loader! Its our own funky loader.
  */
-public class DocumentLoader implements Loader {
+public class RuntimeDataSupplier implements DataSupplier {
 
     private final Context mContext;
-    private final LoaderManager mLoader;
-    private List<Integer> loaderIds;
+    private final LoaderManager mLoaderMgr;
+    private final List<Integer> loaderIds = new ArrayList<>();
     private @Nullable Callbacks mDocCallbacks;
     private @Nullable Callbacks mDirCallbacks;
+    private @Nullable LoaderCallbacks<Bundle> mMetadataCallbacks;
 
-    public DocumentLoader(Context context, LoaderManager loader) {
+    public RuntimeDataSupplier(Context context, LoaderManager loaderMgr) {
         checkArgument(context != null);
-        checkArgument(loader != null);
+        checkArgument(loaderMgr != null);
         mContext = context;
-        mLoader = loader;
-        loaderIds = new ArrayList<>();
+        mLoaderMgr = loaderMgr;
     }
 
     /**
@@ -63,14 +66,10 @@
         //Check that we have correct Uri type and that the loader is not already created.
         checkArgument(uri.getScheme().equals("content"));
 
-        //get a new loader id.
-        int loadId = getNextLoaderId();
-        checkArgument(mLoader.getLoader(loadId) == null);
-        loaderIds.add(loadId);
-
         Consumer<Cursor> callback = new Consumer<Cursor>() {
             @Override
             public void accept(Cursor cursor) {
+
                 if (cursor == null || !cursor.moveToFirst()) {
                     updateView.accept(null);
                 } else {
@@ -81,7 +80,7 @@
         };
 
         mDocCallbacks = new Callbacks(mContext, uri, callback);
-        mLoader.restartLoader(loadId, null, mDocCallbacks);
+        mLoaderMgr.restartLoader(getNextLoaderId(), null, mDocCallbacks);
     }
 
     /**
@@ -93,11 +92,6 @@
         Uri children = DocumentsContract.buildChildDocumentsUri(
                 directory.authority, directory.documentId);
 
-        //get a new loader id.
-        int loadId = getNextLoaderId();
-        checkArgument(mLoader.getLoader(loadId) == null);
-        loaderIds.add(loadId);
-
         Consumer<Cursor> callback = new Consumer<Cursor>() {
             @Override
             public void accept(Cursor cursor) {
@@ -108,19 +102,42 @@
         };
 
         mDirCallbacks = new Callbacks(mContext, children, callback);
-        mLoader.restartLoader(loadId, null, mDirCallbacks);
+        mLoaderMgr.restartLoader(getNextLoaderId(), null, mDirCallbacks);
+    }
+
+    @Override
+    public void getDocumentMetadata(Uri uri, Consumer<Bundle> callback) {
+        mMetadataCallbacks = new LoaderCallbacks<Bundle>() {
+            @Override
+            public android.content.Loader<Bundle> onCreateLoader(int id, Bundle unused) {
+                return new MetadataLoader(mContext, uri);
+            }
+
+            @Override
+            public void onLoadFinished(android.content.Loader<Bundle> loader, Bundle data) {
+                callback.accept(data);
+            }
+
+            @Override
+            public void onLoaderReset(android.content.Loader<Bundle> loader) {
+            }
+        };
+
+        // TODO: Listen for changes on content URI.
+        mLoaderMgr.restartLoader(getNextLoaderId(), null, mMetadataCallbacks);
     }
 
     @Override
     public void reset() {
         for (Integer id : loaderIds) {
-            mLoader.destroyLoader(id);
+            mLoaderMgr.destroyLoader(id);
         }
         loaderIds.clear();
 
         if (mDocCallbacks != null && mDocCallbacks.getObserver() != null) {
             mContext.getContentResolver().unregisterContentObserver(mDocCallbacks.getObserver());
         }
+
         if (mDirCallbacks != null && mDirCallbacks.getObserver() != null) {
             mContext.getContentResolver().unregisterContentObserver(mDocCallbacks.getObserver());
         }
@@ -128,10 +145,11 @@
 
     private int getNextLoaderId() {
         int id = 0;
-        while(mLoader.getLoader(id) != null) {
+        while(mLoaderMgr.getLoader(id) != null) {
             id++;
             checkArgument(id <= Integer.MAX_VALUE);
         }
+        loaderIds.add(id);
         return id;
     }
 
@@ -195,4 +213,4 @@
             mContentChangedCallback.run();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/inspector/TableView.java b/src/com/android/documentsui/inspector/TableView.java
index 91c30d8..191e89a 100644
--- a/src/com/android/documentsui/inspector/TableView.java
+++ b/src/com/android/documentsui/inspector/TableView.java
@@ -20,28 +20,29 @@
 import android.content.res.Resources;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
+import android.view.textclassifier.TextClassifier;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.android.documentsui.R;
+import com.android.documentsui.inspector.InspectorController.TableDisplay;
 
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.annotation.Nullable;
-
-
 /**
  * Organizes and Displays the basic details about a file
  */
-public class TableView extends LinearLayout {
+public class TableView extends LinearLayout implements TableDisplay {
 
     private final LayoutInflater mInflater;
 
-    private final Map<String, KeyValueRow> mRows = new HashMap<>();
+    private final Map<CharSequence, KeyValueRow> mRows = new HashMap<>();
     private final Resources mRes;
-    private @Nullable TextView mTitle;
+    private final Map<CharSequence, TextView> mTitles = new HashMap<>();
+    private final TextClassifier mClassifier;
 
     public TableView(Context context) {
         this(context, null);
@@ -55,40 +56,77 @@
         super(context, attrs, defStyleAttr);
         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mRes = context.getResources();
+        mClassifier = GpsCoordinatesTextClassifier.create(context);
     }
 
-    protected void setTitle(ViewGroup parent, @StringRes int title) {
-        if (mTitle == null) {
-            mTitle = (TextView) mInflater.inflate(R.layout.inspector_section_title, null);
-            parent.addView(mTitle);
+    void setTitle(@StringRes int title, boolean showDivider) {
+        putTitle(mContext.getResources().getString(title), showDivider);
+    }
+
+    // A naughty title method (that takes strings, not message ids), mostly for DebugView.
+    protected void putTitle(CharSequence title, boolean showDivider) {
+        TextView view = mTitles.get(title);
+        if (view == null) {
+            LinearLayout layout =
+                (LinearLayout) mInflater.inflate(R.layout.inspector_section_title, null);
+            if (!showDivider) {
+                layout.setDividerDrawable(null);
+            }
+            view = (TextView) layout.findViewById(R.id.inspector_header_title);
+            addView(layout);
+            mTitles.put(title, view);
         }
-        mTitle.setText(mContext.getResources().getString(title));
+        view.setText(title);
     }
 
     protected KeyValueRow createKeyValueRow(ViewGroup parent) {
         KeyValueRow row = (KeyValueRow) mInflater.inflate(R.layout.table_key_value_row, null);
         parent.addView(row);
+        row.setTextClassifier(mClassifier);
         return row;
     }
 
     /**
-     * Puts or updates an value in the table view.
+     * Puts or updates a value in the table view.
      */
-    protected void put(@StringRes int keyId, String value) {
+    @Override
+    public void put(@StringRes int keyId, CharSequence value) {
         put(mRes.getString(keyId), value);
     }
 
+
     /**
-     * Puts or updates an value in the table view.
+     * Puts or updates a value in the table view.
      */
-    protected void put(String key, String value) {
-        if(mRows.containsKey(key)) {
-            mRows.get(key).setValue(value);
-        } else {
-            KeyValueRow row = createKeyValueRow(this);
+    protected KeyValueRow put(CharSequence key, CharSequence value) {
+        KeyValueRow row = mRows.get(key);
+
+        if (row == null) {
+            row = createKeyValueRow(this);
             row.setKey(key);
-            row.setValue(value);
             mRows.put(key, row);
+        } else {
+            row.removeOnClickListener();
         }
+
+        row.setValue(value);
+        row.setTextClassifier(mClassifier);
+        return row;
+    }
+
+    @Override
+    public void put(@StringRes int keyId, CharSequence value, OnClickListener callback) {
+        put(keyId, value);
+        mRows.get(mRes.getString(keyId)).setOnClickListener(callback);
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return mRows.isEmpty();
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        setVisibility(visible ? View.VISIBLE : View.GONE);
     }
 }
diff --git a/src/com/android/documentsui/inspector/actions/Action.java b/src/com/android/documentsui/inspector/actions/Action.java
index 1b0b693..d90d6dc 100644
--- a/src/com/android/documentsui/inspector/actions/Action.java
+++ b/src/com/android/documentsui/inspector/actions/Action.java
@@ -17,6 +17,7 @@
 package com.android.documentsui.inspector.actions;
 
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -54,6 +55,8 @@
 
     public abstract @Nullable String getPackageName();
 
+    public abstract @StringRes int getButtonLabel();
+
     public @Nullable Drawable getAppIcon() {
 
         String packageName = getPackageName();
diff --git a/src/com/android/documentsui/inspector/actions/ActionView.java b/src/com/android/documentsui/inspector/actions/ActionView.java
index 485e2b1..b519bcc 100644
--- a/src/com/android/documentsui/inspector/actions/ActionView.java
+++ b/src/com/android/documentsui/inspector/actions/ActionView.java
@@ -15,6 +15,7 @@
  */
 package com.android.documentsui.inspector.actions;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
@@ -34,6 +35,7 @@
  */
 public final class ActionView extends LinearLayout implements InspectorController.ActionDisplay {
 
+    private Context mContext;
     private final TextView mHeader;
     private final ImageView mAppIcon;
     private final TextView mAppName;
@@ -55,12 +57,18 @@
         View view = inflater.inflate(R.layout.inspector_action_view, null);
         addView(view);
 
-        mHeader = (TextView) findViewById(R.id.action_header);
+        mContext = context;
+        mHeader = getSectionTitle();
         mAppIcon = (ImageView) findViewById(R.id.app_icon);
         mAppName = (TextView) findViewById(R.id.app_name);
         mActionButton = (ImageButton) findViewById(R.id.inspector_action_button);
     }
 
+    public TextView getSectionTitle() {
+        LinearLayout header = (LinearLayout) findViewById(R.id.action_header);
+        return (TextView) header.findViewById(R.id.inspector_header_title);
+    }
+
     @Override
     public void init(Action action, OnClickListener listener) {
         mAction = action;
@@ -68,6 +76,7 @@
 
         setAppIcon(mAction.getAppIcon());
         setAppName(mAction.getAppName());
+        mActionButton.setContentDescription(mContext.getString(action.getButtonLabel()));
 
         mActionButton.setOnClickListener(listener);
         showAction(true);
@@ -84,8 +93,14 @@
     }
 
     @Override
-    public void setAppIcon(Drawable icon) {
-        mAppIcon.setImageDrawable(icon);
+    public void setAppIcon(@Nullable Drawable icon) {
+
+        if (icon != null) {
+            mAppIcon.setVisibility(View.VISIBLE);
+            mAppIcon.setImageDrawable(icon);
+        } else {
+            mAppIcon.setVisibility(View.GONE);
+        }
     }
 
     @Override
diff --git a/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java b/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java
index 4f954ba..f8f6aeb 100644
--- a/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java
+++ b/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java
@@ -15,6 +15,7 @@
  */
 package com.android.documentsui.inspector.actions;
 
+import android.annotation.StringRes;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -84,4 +85,8 @@
             return null;
         }
     }
+
+    public @StringRes int getButtonLabel() {
+        return R.string.button_clear;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java b/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java
index aee649d..0dc221a 100644
--- a/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java
+++ b/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 
+import android.support.annotation.StringRes;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.roots.ProvidersAccess;
@@ -67,4 +68,8 @@
     public String getPackageName() {
         return mProviders.getPackageName(mDoc.derivedUri.getAuthority());
     }
+
+    public @StringRes int getButtonLabel() {
+        return R.string.button_show_provider;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 0a3972a..596c627 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -41,6 +41,7 @@
 import com.android.documentsui.DocumentsAccess;
 import com.android.documentsui.Injector;
 import com.android.documentsui.Metrics;
+import com.android.documentsui.Model;
 import com.android.documentsui.base.BooleanConsumer;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
@@ -50,11 +51,10 @@
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.AnimationView;
-import com.android.documentsui.dirlist.DocumentDetails;
-import com.android.documentsui.Model;
 import com.android.documentsui.picker.ActionHandler.Addons;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.ProvidersAccess;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.services.FileOperationService;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -246,12 +246,12 @@
     }
 
     @Override
-    public boolean openDocument(DocumentDetails details, @ViewType int type,
+    public boolean openItem(ItemDetails details, @ViewType int type,
             @ViewType int fallback) {
-        DocumentInfo doc = mModel.getDocument(details.getModelId());
+        DocumentInfo doc = mModel.getDocument(details.getStableId());
         if (doc == null) {
             Log.w(TAG,
-                    "Can't view item. No Document available for modeId: " + details.getModelId());
+                    "Can't view item. No Document available for modeId: " + details.getStableId());
             return false;
         }
 
@@ -374,6 +374,7 @@
     }
 
     public interface Addons extends CommonAddons {
+        @Override
         void onDocumentPicked(DocumentInfo doc);
 
         /**
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index fb43ce6..94327b1 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -34,6 +34,7 @@
 
 import com.android.documentsui.ActionModeController;
 import com.android.documentsui.BaseActivity;
+import com.android.documentsui.DocsSelectionHelper;
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
@@ -49,7 +50,6 @@
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.prefs.ScopedPreferences;
-import com.android.documentsui.selection.SelectionManager;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.sidebar.RootsFragment;
 import com.android.documentsui.ui.DialogController;
@@ -94,10 +94,9 @@
 
         super.onCreate(icicle);
 
-        mInjector.selectionMgr = new SelectionManager(
-                mState.allowMultiple
-                        ? SelectionManager.MODE_MULTIPLE
-                        : SelectionManager.MODE_SINGLE);
+        mInjector.selectionMgr = mState.allowMultiple
+                ? DocsSelectionHelper.createMultiSelect()
+                : DocsSelectionHelper.createSingleSelect();
 
         mInjector.focusManager = new FocusManager(
                 mInjector.features,
diff --git a/src/com/android/documentsui/prefs/LocalPreferences.java b/src/com/android/documentsui/prefs/LocalPreferences.java
index 48a9220..955b19d 100644
--- a/src/com/android/documentsui/prefs/LocalPreferences.java
+++ b/src/com/android/documentsui/prefs/LocalPreferences.java
@@ -19,20 +19,19 @@
 import static com.android.documentsui.base.State.MODE_UNKNOWN;
 
 import android.annotation.IntDef;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.os.UserHandle;
 import android.preference.PreferenceManager;
 
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.base.State;
 import com.android.documentsui.base.State.ViewMode;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+/**
+ * Methods for accessing the local preferences.
+ */
 public class LocalPreferences {
     private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-";
 
@@ -66,64 +65,6 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionStatus {}
 
-    /**
-     * Clears all preferences associated with a given package.
-     *
-     * <p>Typically called when a package is removed or when user asked to clear its data.
-     */
-    public static void clearPackagePreferences(Context context, String packageName) {
-        clearScopedAccessPreferences(context, packageName);
-    }
-
-    /**
-     * Methods below are used to keep track of denied user requests on scoped directory access so
-     * the dialog is not offered when user checked the 'Do not ask again' box
-     *
-     * <p>It uses a shared preferences, whose key is:
-     * <ol>
-     * <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID
-     * (typically physical volumes like SD cards).
-     * <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID
-     * (typically the emulated volume used for primary storage
-     * </ol>
-     */
-    public static @PermissionStatus int getScopedAccessPermissionStatus(Context context,
-            String packageName, @Nullable String uuid, String directory) {
-        final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
-        return getPrefs(context).getInt(key, PERMISSION_ASK);
-    }
-
-    public static void setScopedAccessPermissionStatus(Context context, String packageName,
-            @Nullable String uuid, String directory, @PermissionStatus int status) {
-      final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
-      getPrefs(context).edit().putInt(key, status).apply();
-    }
-
-    private static void clearScopedAccessPreferences(Context context, String packageName) {
-        final String keySubstring = "|" + packageName + "|";
-        final SharedPreferences prefs = getPrefs(context);
-        Editor editor = null;
-        for (final String key : prefs.getAll().keySet()) {
-            if (key.contains(keySubstring)) {
-                if (editor == null) {
-                    editor = prefs.edit();
-                }
-                editor.remove(key);
-            }
-        }
-        if (editor != null) {
-            editor.apply();
-        }
-    }
-
-    private static String getScopedAccessDenialsKey(String packageName, String uuid,
-            String directory) {
-        final int userId = UserHandle.myUserId();
-        return uuid == null
-                ? userId + "|" + packageName + "||" + directory
-                : userId + "|" + packageName + "|" + uuid + "|" + directory;
-    }
-
     public static boolean shouldBackup(String s) {
         return (s != null) ? s.startsWith(ROOT_VIEW_MODE_PREFIX) : false;
     }
diff --git a/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java b/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
new file mode 100644
index 0000000..cd6c419
--- /dev/null
+++ b/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.prefs;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.UserHandle;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Methods for accessing the local preferences with regards to scoped directory access.
+ */
+//TODO(b/63720392): add unit tests
+public class ScopedAccessLocalPreferences {
+
+    private static final String TAG = "ScopedAccessLocalPreferences";
+
+    private static SharedPreferences getPrefs(Context context) {
+        return PreferenceManager.getDefaultSharedPreferences(context);
+    }
+
+    public static final int PERMISSION_ASK = 0;
+    public static final int PERMISSION_ASK_AGAIN = 1;
+    public static final int PERMISSION_NEVER_ASK = -1;
+
+    @IntDef(flag = true, value = {
+            PERMISSION_ASK,
+            PERMISSION_ASK_AGAIN,
+            PERMISSION_NEVER_ASK,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PermissionStatus {}
+
+    private static final String KEY_REGEX = "^.+\\|(.+)\\|(.*)\\|(.+)$";
+    private static final Pattern KEY_PATTERN = Pattern.compile(KEY_REGEX);
+
+    /**
+     * Methods below are used to keep track of denied user requests on scoped directory access so
+     * the dialog is not offered when user checked the 'Do not ask again' box
+     *
+     * <p>It uses a shared preferences, whose key is:
+     * <ol>
+     * <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID
+     * (typically physical volumes like SD cards).
+     * <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID
+     * (typically the emulated volume used for primary storage
+     * </ol>
+     */
+    public static @PermissionStatus int getScopedAccessPermissionStatus(Context context,
+            String packageName, @Nullable String uuid, String directory) {
+        final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
+        return getPrefs(context).getInt(key, PERMISSION_ASK);
+    }
+
+    public static void setScopedAccessPermissionStatus(Context context, String packageName,
+            @Nullable String uuid, String directory, @PermissionStatus int status) {
+      final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
+      getPrefs(context).edit().putInt(key, status).apply();
+    }
+
+    public static void clearScopedAccessPreferences(Context context, String packageName) {
+        final String keySubstring = "|" + packageName + "|";
+        final SharedPreferences prefs = getPrefs(context);
+        Editor editor = null;
+        for (final String key : prefs.getAll().keySet()) {
+            if (key.contains(keySubstring)) {
+                if (editor == null) {
+                    editor = prefs.edit();
+                }
+                editor.remove(key);
+            }
+        }
+        if (editor != null) {
+            editor.apply();
+        }
+    }
+
+    private static String getScopedAccessDenialsKey(String packageName, String uuid,
+            String directory) {
+        final int userId = UserHandle.myUserId();
+        return uuid == null
+                ? userId + "|" + packageName + "||" + directory
+                : userId + "|" + packageName + "|" + uuid + "|" + directory;
+    }
+
+    /**
+     * Clears all preferences associated with a given package.
+     *
+     * <p>Typically called when a package is removed or when user asked to clear its data.
+     */
+    public static void clearPackagePreferences(Context context, String packageName) {
+        ScopedAccessLocalPreferences.clearScopedAccessPreferences(context, packageName);
+    }
+
+    /**
+     * Gets all packages that have entries in the preferences
+     */
+    public static ArraySet<String> getAllPackages(Context context) {
+        final SharedPreferences prefs = getPrefs(context);
+        final ArraySet<String> pkgs = new ArraySet<>();
+
+        for (Entry<String, ?> pref : prefs.getAll().entrySet()) {
+            final String key = pref.getKey();
+            final String pkg = getPackage(key);
+            if (pkg == null) {
+                Log.w(TAG, "getAllPackages(): error parsing pref '" + key + "'");
+                continue;
+            }
+            pkgs.add(pkg);
+        }
+        return pkgs;
+    }
+
+    /**
+     * Gets all permissions.
+     */
+    public static ArrayList<Permission> getAllPermissions(Context context) {
+        final SharedPreferences prefs = getPrefs(context);
+        final ArrayList<Permission> permissions = new ArrayList<>();
+
+        for (Entry<String, ?> pref : prefs.getAll().entrySet()) {
+            final String key = pref.getKey();
+            final Object value = pref.getValue();
+            final Integer status;
+            try {
+                status = (Integer) value;
+            } catch (Exception e) {
+                Log.w(TAG, "error gettting value for key '" + key + "': " + value);
+                continue;
+            }
+            permissions.add(getPermission(key, status));
+        }
+
+        return permissions;
+    }
+
+    public static String statusAsString(@PermissionStatus int status) {
+        switch (status) {
+            case PERMISSION_ASK:
+                return "PERMISSION_ASK";
+            case PERMISSION_ASK_AGAIN:
+                return "PERMISSION_ASK_AGAIN";
+            case PERMISSION_NEVER_ASK:
+                return "PERMISSION_NEVER_ASK";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    private static String getPackage(String key) {
+        final Matcher matcher = KEY_PATTERN.matcher(key);
+        return matcher.matches() ? matcher.group(1) : null;
+    }
+
+    private static Permission getPermission(String key, Integer status) {
+        final Matcher matcher = KEY_PATTERN.matcher(key);
+        if (!matcher.matches()) return null;
+
+        final String pkg = matcher.group(1);
+        final String uuid = matcher.group(2);
+        final String directory = matcher.group(3);
+
+        return new Permission(pkg, uuid, directory, status);
+    }
+
+    public static final class Permission {
+        public final String pkg;
+        public final String uuid;
+        public final String directory;
+        public final int status;
+
+        private Permission(String pkg, String uuid, String directory, Integer status) {
+            this.pkg = pkg;
+            this.uuid = TextUtils.isEmpty(uuid) ? null : uuid;
+            this.directory = directory;
+            this.status = status.intValue();
+        }
+
+        @Override
+        public String toString() {
+            return "Permission: [pkg=" + pkg + ", uuid=" + uuid + ", dir=" + directory + ", status="
+                    + statusAsString(status) + " (" + status + ")]";
+        }
+    }
+}
diff --git a/src/com/android/documentsui/queries/SearchViewManager.java b/src/com/android/documentsui/queries/SearchViewManager.java
index 6a2790d..9e8411a 100644
--- a/src/com/android/documentsui/queries/SearchViewManager.java
+++ b/src/com/android/documentsui/queries/SearchViewManager.java
@@ -20,6 +20,8 @@
 
 import android.annotation.Nullable;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.provider.DocumentsContract.Root;
 import android.text.TextUtils;
 import android.util.Log;
@@ -38,6 +40,11 @@
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * Manages searching UI behavior.
@@ -48,9 +55,19 @@
 
     private static final String TAG = "SearchManager";
 
+    // How long we wait after the user finishes typing before kicking off a search.
+    public static final int SEARCH_DELAY_MS = 750;
+
     private final SearchManagerListener mListener;
     private final EventHandler<String> mCommandProcessor;
+    private final Timer mTimer;
+    private final Handler mUiHandler;
 
+    private final Object mSearchLock;
+    @GuardedBy("mSearchLock")
+    private @Nullable Runnable mQueuedSearchRunnable;
+    @GuardedBy("mSearchLock")
+    private @Nullable TimerTask mQueuedSearchTask;
     private @Nullable String mCurrentSearch;
     private boolean mSearchExpanded;
     private boolean mIgnoreNextClose;
@@ -64,12 +81,25 @@
             SearchManagerListener listener,
             EventHandler<String> commandProcessor,
             @Nullable Bundle savedState) {
+        this(listener, commandProcessor, savedState, new Timer(),
+                new Handler(Looper.getMainLooper()));
+    }
 
+    @VisibleForTesting
+    protected SearchViewManager(
+            SearchManagerListener listener,
+            EventHandler<String> commandProcessor,
+            @Nullable Bundle savedState,
+            Timer timer,
+            Handler handler) {
         assert (listener != null);
         assert (commandProcessor != null);
 
+        mSearchLock = new Object();
         mListener = listener;
         mCommandProcessor = commandProcessor;
+        mTimer = timer;
+        mUiHandler = handler;
         mCurrentSearch = savedState != null ? savedState.getString(Shared.EXTRA_QUERY) : null;
     }
 
@@ -169,6 +199,7 @@
      */
     public boolean cancelSearch() {
         if (isExpanded() || isSearching()) {
+            cancelQueuedSearch();
             // If the query string is not empty search view won't get iconified
             mSearchView.setQuery("", false);
 
@@ -183,13 +214,24 @@
         return false;
     }
 
+    private void cancelQueuedSearch() {
+        synchronized (mSearchLock) {
+            if (mQueuedSearchTask != null) {
+                mQueuedSearchTask.cancel();
+            }
+            mQueuedSearchTask = null;
+            mUiHandler.removeCallbacks(mQueuedSearchRunnable);
+            mQueuedSearchRunnable = null;
+        }
+    }
+
     /**
      * Sets search view into the searching state. Used to restore state after device orientation
      * change.
      */
     private void restoreSearch() {
         if (isSearching()) {
-            if(mFullBar) {
+            if (mFullBar) {
                 mMenuItem.expandActionView();
             } else {
                 mSearchView.setIconified(false);
@@ -202,7 +244,7 @@
 
     private void onSearchExpanded() {
         mSearchExpanded = true;
-        if(mFullBar) {
+        if (mFullBar) {
             mMenu.setGroupVisible(R.id.group_hide_when_searching, false);
         }
 
@@ -228,7 +270,7 @@
             mListener.onSearchChanged(mCurrentSearch);
         }
 
-        if(mFullBar) {
+        if (mFullBar) {
             mMenuItem.collapseActionView();
         }
         mListener.onSearchFinished();
@@ -261,9 +303,13 @@
         if (mCommandProcessor.accept(query)) {
             mSearchView.setQuery("", false);
         } else {
-            mCurrentSearch = query;
+            cancelQueuedSearch();
+            // Don't kick off a search if we've already finished it.
+            if (mCurrentSearch != query) {
+                mCurrentSearch = query;
+                mListener.onSearchChanged(mCurrentSearch);
+            }
             mSearchView.clearFocus();
-            mListener.onSearchChanged(mCurrentSearch);
         }
 
         return true;
@@ -283,9 +329,35 @@
         }
     }
 
+    @VisibleForTesting
+    protected TimerTask createSearchTask(String newText) {
+        return new TimerTask() {
+            @Override
+            public void run() {
+                // Do the actual work on the main looper.
+                synchronized (mSearchLock) {
+                    mQueuedSearchRunnable = () -> {
+                        mCurrentSearch = newText;
+                        if (mCurrentSearch != null && mCurrentSearch.isEmpty()) {
+                            mCurrentSearch = null;
+                        }
+                        mListener.onSearchChanged(mCurrentSearch);
+                    };
+                    mUiHandler.post(mQueuedSearchRunnable);
+                }
+            }
+        };
+    }
+
     @Override
     public boolean onQueryTextChange(String newText) {
-        return false;
+        cancelQueuedSearch();
+        synchronized (mSearchLock) {
+            mQueuedSearchTask = createSearchTask(newText);
+
+            mTimer.schedule(mQueuedSearchTask, SEARCH_DELAY_MS);
+        }
+        return true;
     }
 
     @Override
diff --git a/src/com/android/documentsui/roots/ProvidersCache.java b/src/com/android/documentsui/roots/ProvidersCache.java
index ffb01e8..e8dcbc6 100644
--- a/src/com/android/documentsui/roots/ProvidersCache.java
+++ b/src/com/android/documentsui/roots/ProvidersCache.java
@@ -396,6 +396,7 @@
         }
     }
 
+    @Override
     public RootInfo getDefaultRootBlocking(State state) {
         for (RootInfo root : ProvidersAccess.getMatchingRoots(getRootsBlocking(), state)) {
             if (root.isDownloads()) {
diff --git a/src/com/android/documentsui/selection/BandController.java b/src/com/android/documentsui/selection/BandController.java
deleted file mode 100644
index 399bb15..0000000
--- a/src/com/android/documentsui/selection/BandController.java
+++ /dev/null
@@ -1,1160 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import static com.android.documentsui.base.Shared.DEBUG;
-import static com.android.documentsui.ui.ViewAutoScroller.NOT_SET;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnScrollListener;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
-import android.view.View;
-
-import com.android.documentsui.DirectoryReloadLock;
-import com.android.documentsui.R;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.dirlist.DocumentsAdapter;
-import com.android.documentsui.dirlist.FocusHandler;
-import com.android.documentsui.ui.ViewAutoScroller;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollActionDelegate;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollDistanceDelegate;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.IntPredicate;
-
-/**
- * Provides mouse driven band-select support when used in conjunction with {@link RecyclerView}
- * and {@link SelectionManager}. This class is responsible for rendering the band select
- * overlay and selecting overlaid items via SelectionManager.
- */
-public class BandController extends OnScrollListener {
-
-    private static final String TAG = "BandController";
-
-    private final Runnable mModelBuilder;
-    private final SelectionEnvironment mEnvironment;
-    private final DocumentsAdapter mAdapter;
-    private final SelectionManager mSelectionManager;
-    private final DirectoryReloadLock mLock;
-    private final Runnable mViewScroller;
-    private final GridModel.OnSelectionChangedListener mGridListener;
-    private final List<Runnable> mStartBandSelectListeners = new ArrayList<>();
-
-    @Nullable private Rect mBounds;
-    @Nullable private Point mCurrentPosition;
-    @Nullable private Point mOrigin;
-    @Nullable private BandController.GridModel mModel;
-
-    private Selection mSelection;
-
-    public BandController(
-            final RecyclerView view,
-            DocumentsAdapter adapter,
-            SelectionManager selectionManager,
-            DirectoryReloadLock lock,
-            IntPredicate gridItemTester) {
-        this(new RuntimeSelectionEnvironment(view), adapter, selectionManager,
-                lock, gridItemTester);
-    }
-
-    @VisibleForTesting
-    BandController(
-            SelectionEnvironment env,
-            DocumentsAdapter adapter,
-            SelectionManager selectionManager,
-            DirectoryReloadLock lock,
-            IntPredicate gridItemTester) {
-
-        mLock = lock;
-        selectionManager.bindContoller(this);
-
-        mEnvironment = env;
-        mAdapter = adapter;
-        mSelectionManager = selectionManager;
-
-        mEnvironment.addOnScrollListener(this);
-        mViewScroller = new ViewAutoScroller(
-                new ScrollDistanceDelegate() {
-                    @Override
-                    public Point getCurrentPosition() {
-                        return mCurrentPosition;
-                    }
-
-                    @Override
-                    public int getViewHeight() {
-                        return mEnvironment.getHeight();
-                    }
-
-                    @Override
-                    public boolean isActive() {
-                        return BandController.this.isActive();
-                    }
-                },
-                env);
-
-        mAdapter.registerAdapterDataObserver(
-                new RecyclerView.AdapterDataObserver() {
-                    @Override
-                    public void onChanged() {
-                        if (isActive()) {
-                            endBandSelect();
-                        }
-                    }
-
-                    @Override
-                    public void onItemRangeChanged(
-                            int startPosition, int itemCount, Object payload) {
-                        // No change in position. Ignoring.
-                    }
-
-                    @Override
-                    public void onItemRangeInserted(int startPosition, int itemCount) {
-                        if (isActive()) {
-                            endBandSelect();
-                        }
-                    }
-
-                    @Override
-                    public void onItemRangeRemoved(int startPosition, int itemCount) {
-                        assert(startPosition >= 0);
-                        assert(itemCount > 0);
-
-                        // TODO: Should update grid model.
-                    }
-
-                    @Override
-                    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-                        throw new UnsupportedOperationException();
-                    }
-                });
-
-        mGridListener = new GridModel.OnSelectionChangedListener() {
-
-            @Override
-            public void onSelectionChanged(Set<String> updatedSelection) {
-                BandController.this.onSelectionChanged(updatedSelection);
-            }
-
-            @Override
-            public boolean onBeforeItemStateChange(String id, boolean nextState) {
-                return BandController.this.onBeforeItemStateChange(id, nextState);
-            }
-        };
-
-        mModelBuilder = new Runnable() {
-            @Override
-            public void run() {
-                mModel = new GridModel(mEnvironment, gridItemTester, mAdapter);
-                mModel.addOnSelectionChangedListener(mGridListener);
-            }
-        };
-    }
-
-    @VisibleForTesting
-    boolean isActive() {
-        return mModel != null;
-    }
-
-    void bindSelection(Selection selection) {
-        mSelection = selection;
-    }
-
-    public boolean onInterceptTouchEvent(InputEvent e) {
-        if (shouldStart(e)) {
-            if (!e.isCtrlKeyDown()) {
-                mSelectionManager.clearSelection();
-            }
-            startBandSelect(e.getOrigin());
-        } else if (shouldStop(e)) {
-            endBandSelect();
-        }
-
-        return isActive();
-    }
-
-    public void addBandSelectStartedListener(Runnable listener) {
-        mStartBandSelectListeners.add(listener);
-    }
-
-    public void removeBandSelectStartedListener(Runnable listener) {
-        mStartBandSelectListeners.remove(listener);
-    }
-
-    /**
-     * Handle a change in layout by cleaning up and getting rid of the old model and creating
-     * a new model which will track the new layout.
-     */
-    public void handleLayoutChanged() {
-        if (mModel != null) {
-            mModel.removeOnSelectionChangedListener(mGridListener);
-            mModel.stopListening();
-
-            // build a new model, all fresh and happy.
-            mModelBuilder.run();
-        }
-    }
-
-    public boolean shouldStart(InputEvent e) {
-        // Don't start, or extend bands on non-left clicks.
-        if (!e.isPrimaryButtonPressed()) {
-            return false;
-        }
-
-        if (!e.isMouseEvent() && isActive()) {
-            // Weird things happen if we keep up band select
-            // when touch events happen.
-            endBandSelect();
-            return false;
-        }
-
-        // b/30146357 && b/23793622. onInterceptTouchEvent does not dispatch events to onTouchEvent
-        // unless the event is != ACTION_DOWN. Thus, we need to actually start band selection when
-        // mouse moves, or else starting band selection on mouse down can cause problems as events
-        // don't get routed correctly to onTouchEvent.
-        return !isActive()
-                && e.isActionMove() // the initial button move via mouse-touch (ie. down press)
-                && mAdapter.hasModelIds() // we want to check against actual modelIds count to
-                                          // avoid dummy view count from the AdapterWrapper
-                && !e.isOverDragHotspot();
-
-    }
-
-    public boolean shouldStop(InputEvent input) {
-        return isActive()
-                && input.isMouseEvent()
-                && (input.isActionUp() || input.isMultiPointerActionUp() || input.isActionCancel());
-    }
-
-    /**
-     * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
-     * @param input
-     */
-    public void onTouchEvent(InputEvent input) {
-        assert(input.isMouseEvent());
-
-        if (shouldStop(input)) {
-            endBandSelect();
-            return;
-        }
-
-        // We shouldn't get any events in this method when band select is not active,
-        // but it turns some guests show up late to the party.
-        // Probably happening when a re-layout is happening to the ReyclerView (ie. Pull-To-Refresh)
-        if (!isActive()) {
-            return;
-        }
-
-        assert(input.isActionMove());
-        mCurrentPosition = input.getOrigin();
-        mModel.resizeSelection(input.getOrigin());
-        scrollViewIfNecessary();
-        resizeBandSelectRectangle();
-    }
-
-    /**
-     * Starts band select by adding the drawable to the RecyclerView's overlay.
-     */
-    private void startBandSelect(Point origin) {
-        if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
-
-        mLock.block();
-        notifyBandSelectStartedListeners();
-        mOrigin = origin;
-        mModelBuilder.run();  // Creates a new selection model.
-        mModel.startSelection(mOrigin);
-    }
-
-    private void notifyBandSelectStartedListeners() {
-        for (Runnable listener : mStartBandSelectListeners) {
-            listener.run();
-        }
-    }
-
-    /**
-     * Scrolls the view if necessary.
-     */
-    private void scrollViewIfNecessary() {
-        mEnvironment.removeCallback(mViewScroller);
-        mViewScroller.run();
-        mEnvironment.invalidateView();
-    }
-
-    /**
-     * Resizes the band select rectangle by using the origin and the current pointer position as
-     * two opposite corners of the selection.
-     */
-    private void resizeBandSelectRectangle() {
-        mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
-                Math.min(mOrigin.y, mCurrentPosition.y),
-                Math.max(mOrigin.x, mCurrentPosition.x),
-                Math.max(mOrigin.y, mCurrentPosition.y));
-        mEnvironment.showBand(mBounds);
-    }
-
-    /**
-     * Ends band select by removing the overlay.
-     */
-    private void endBandSelect() {
-        if (DEBUG) Log.d(TAG, "Ending band select.");
-
-        mEnvironment.hideBand();
-        mSelection.applyProvisionalSelection();
-        mModel.endSelection();
-        int firstSelected = mModel.getPositionNearestOrigin();
-        if (firstSelected != NOT_SET) {
-            if (mSelection.contains(mAdapter.getModelId(firstSelected))) {
-                // TODO: firstSelected should really be lastSelected, we want to anchor the item
-                // where the mouse-up occurred.
-                mSelectionManager.setSelectionRangeBegin(firstSelected);
-            } else {
-                // TODO: Check if this is really happening.
-                Log.w(TAG, "First selected by band is NOT in selection!");
-            }
-        }
-
-        mModel = null;
-        mOrigin = null;
-        mLock.unblock();
-    }
-
-    private void onSelectionChanged(Set<String> updatedSelection) {
-        Map<String, Boolean> delta = mSelection.setProvisionalSelection(updatedSelection);
-        for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
-            mSelectionManager.notifyItemStateChanged(entry.getKey(), entry.getValue());
-        }
-        mSelectionManager.notifySelectionChanged();
-    }
-
-    private boolean onBeforeItemStateChange(String id, boolean nextState) {
-        return mSelectionManager.canSetState(id, nextState);
-    }
-
-    @Override
-    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-        if (!isActive()) {
-            return;
-        }
-
-        // Adjust the y-coordinate of the origin the opposite number of pixels so that the
-        // origin remains in the same place relative to the view's items.
-        mOrigin.y -= dy;
-        resizeBandSelectRectangle();
-    }
-
-    /**
-     * Provides a band selection item model for views within a RecyclerView. This class queries the
-     * RecyclerView to determine where its items are placed; then, once band selection is underway,
-     * it alerts listeners of which items are covered by the selections.
-     */
-    @VisibleForTesting
-    static final class GridModel extends RecyclerView.OnScrollListener {
-
-        public static final int NOT_SET = -1;
-
-        // Enum values used to determine the corner at which the origin is located within the
-        private static final int UPPER = 0x00;
-        private static final int LOWER = 0x01;
-        private static final int LEFT = 0x00;
-        private static final int RIGHT = 0x02;
-        private static final int UPPER_LEFT = UPPER | LEFT;
-        private static final int UPPER_RIGHT = UPPER | RIGHT;
-        private static final int LOWER_LEFT = LOWER | LEFT;
-        private static final int LOWER_RIGHT = LOWER | RIGHT;
-
-        private final SelectionEnvironment mHelper;
-        private final IntPredicate mGridItemTester;
-        private final DocumentsAdapter mAdapter;
-
-        private final List<GridModel.OnSelectionChangedListener> mOnSelectionChangedListeners =
-                new ArrayList<>();
-
-        // Map from the x-value of the left side of a SparseBooleanArray of adapter positions, keyed
-        // by their y-offset. For example, if the first column of the view starts at an x-value of 5,
-        // mColumns.get(5) would return an array of positions in that column. Within that array, the
-        // value for key y is the adapter position for the item whose y-offset is y.
-        private final SparseArray<SparseIntArray> mColumns = new SparseArray<>();
-
-        // List of limits along the x-axis (columns).
-        // This list is sorted from furthest left to furthest right.
-        private final List<GridModel.Limits> mColumnBounds = new ArrayList<>();
-
-        // List of limits along the y-axis (rows). Note that this list only contains items which
-        // have been in the viewport.
-        private final List<GridModel.Limits> mRowBounds = new ArrayList<>();
-
-        // The adapter positions which have been recorded so far.
-        private final SparseBooleanArray mKnownPositions = new SparseBooleanArray();
-
-        // Array passed to registered OnSelectionChangedListeners. One array is created and reused
-        // throughout the lifetime of the object.
-        private final Set<String> mSelection = new HashSet<>();
-
-        // The current pointer (in absolute positioning from the top of the view).
-        private Point mPointer = null;
-
-        // The bounds of the band selection.
-        private RelativePoint mRelativeOrigin;
-        private RelativePoint mRelativePointer;
-
-        private boolean mIsActive;
-
-        // Tracks where the band select originated from. This is used to determine where selections
-        // should expand from when Shift+click is used.
-        private int mPositionNearestOrigin = NOT_SET;
-
-        GridModel(SelectionEnvironment helper, IntPredicate gridItemTester, DocumentsAdapter adapter) {
-            mHelper = helper;
-            mAdapter = adapter;
-            mGridItemTester = gridItemTester;
-            mHelper.addOnScrollListener(this);
-        }
-
-        /**
-         * Stops listening to the view's scrolls. Call this function before discarding a
-         * BandSelecModel object to prevent memory leaks.
-         */
-        void stopListening() {
-            mHelper.removeOnScrollListener(this);
-        }
-
-        /**
-         * Start a band select operation at the given point.
-         * @param relativeOrigin The origin of the band select operation, relative to the viewport.
-         *     For example, if the view is scrolled to the bottom, the top-left of the viewport
-         *     would have a relative origin of (0, 0), even though its absolute point has a higher
-         *     y-value.
-         */
-        void startSelection(Point relativeOrigin) {
-            recordVisibleChildren();
-            if (isEmpty()) {
-                // The selection band logic works only if there is at least one visible child.
-                return;
-            }
-
-            mIsActive = true;
-            mPointer = mHelper.createAbsolutePoint(relativeOrigin);
-            mRelativeOrigin = new RelativePoint(mPointer);
-            mRelativePointer = new RelativePoint(mPointer);
-            computeCurrentSelection();
-            notifyListeners();
-        }
-
-        /**
-         * Resizes the selection by adjusting the pointer (i.e., the corner of the selection
-         * opposite the origin.
-         * @param relativePointer The pointer (opposite of the origin) of the band select operation,
-         *     relative to the viewport. For example, if the view is scrolled to the bottom, the
-         *     top-left of the viewport would have a relative origin of (0, 0), even though its
-         *     absolute point has a higher y-value.
-         */
-        @VisibleForTesting
-        void resizeSelection(Point relativePointer) {
-            mPointer = mHelper.createAbsolutePoint(relativePointer);
-            updateModel();
-        }
-
-        /**
-         * Ends the band selection.
-         */
-        void endSelection() {
-            mIsActive = false;
-        }
-
-        /**
-         * @return The adapter position for the item nearest the origin corresponding to the latest
-         *         band select operation, or NOT_SET if the selection did not cover any items.
-         */
-        int getPositionNearestOrigin() {
-            return mPositionNearestOrigin;
-        }
-
-        @Override
-        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-            if (!mIsActive) {
-                return;
-            }
-
-            mPointer.x += dx;
-            mPointer.y += dy;
-            recordVisibleChildren();
-            updateModel();
-        }
-
-        /**
-         * Queries the view for all children and records their location metadata.
-         */
-        private void recordVisibleChildren() {
-            for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
-                int adapterPosition = mHelper.getAdapterPositionAt(i);
-                // Sometimes the view is not attached, as we notify the multi selection manager
-                // synchronously, while views are attached asynchronously. As a result items which
-                // are in the adapter may not actually have a corresponding view (yet).
-                if (mHelper.hasView(adapterPosition) &&
-                        mGridItemTester.test(adapterPosition) &&
-                        !mKnownPositions.get(adapterPosition)) {
-                    mKnownPositions.put(adapterPosition, true);
-                    recordItemData(mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
-                }
-            }
-        }
-
-        /**
-         * Checks if there are any recorded children.
-         */
-        private boolean isEmpty() {
-            return mColumnBounds.size() == 0 || mRowBounds.size() == 0;
-        }
-
-        /**
-         * Updates the limits lists and column map with the given item metadata.
-         * @param absoluteChildRect The absolute rectangle for the child view being processed.
-         * @param adapterPosition The position of the child view being processed.
-         */
-        private void recordItemData(Rect absoluteChildRect, int adapterPosition) {
-            if (mColumnBounds.size() != mHelper.getColumnCount()) {
-                // If not all x-limits have been recorded, record this one.
-                recordLimits(
-                        mColumnBounds, new Limits(absoluteChildRect.left, absoluteChildRect.right));
-            }
-
-            recordLimits(mRowBounds, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
-
-            SparseIntArray columnList = mColumns.get(absoluteChildRect.left);
-            if (columnList == null) {
-                columnList = new SparseIntArray();
-                mColumns.put(absoluteChildRect.left, columnList);
-            }
-            columnList.put(absoluteChildRect.top, adapterPosition);
-        }
-
-        /**
-         * Ensures limits exists within the sorted list limitsList, and adds it to the list if it
-         * does not exist.
-         */
-        private void recordLimits(List<GridModel.Limits> limitsList, GridModel.Limits limits) {
-            int index = Collections.binarySearch(limitsList, limits);
-            if (index < 0) {
-                limitsList.add(~index, limits);
-            }
-        }
-
-        /**
-         * Handles a moved pointer; this function determines whether the pointer movement resulted
-         * in a selection change and, if it has, notifies listeners of this change.
-         */
-        private void updateModel() {
-            RelativePoint old = mRelativePointer;
-            mRelativePointer = new RelativePoint(mPointer);
-            if (old != null && mRelativePointer.equals(old)) {
-                return;
-            }
-
-            computeCurrentSelection();
-            notifyListeners();
-        }
-
-        /**
-         * Computes the currently-selected items.
-         */
-        private void computeCurrentSelection() {
-            if (areItemsCoveredByBand(mRelativePointer, mRelativeOrigin)) {
-                updateSelection(computeBounds());
-            } else {
-                mSelection.clear();
-                mPositionNearestOrigin = NOT_SET;
-            }
-        }
-
-        /**
-         * Notifies all listeners of a selection change. Note that this function simply passes
-         * mSelection, so computeCurrentSelection() should be called before this
-         * function.
-         */
-        private void notifyListeners() {
-            for (GridModel.OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
-                listener.onSelectionChanged(mSelection);
-            }
-        }
-
-        /**
-         * @param rect Rectangle including all covered items.
-         */
-        private void updateSelection(Rect rect) {
-            int columnStart =
-                    Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
-            assert(columnStart >= 0);
-            int columnEnd = columnStart;
-
-            for (int i = columnStart; i < mColumnBounds.size()
-                    && mColumnBounds.get(i).lowerLimit <= rect.right; i++) {
-                columnEnd = i;
-            }
-
-            int rowStart = Collections.binarySearch(mRowBounds, new Limits(rect.top, rect.top));
-            if (rowStart < 0) {
-                mPositionNearestOrigin = NOT_SET;
-                return;
-            }
-
-            int rowEnd = rowStart;
-            for (int i = rowStart; i < mRowBounds.size()
-                    && mRowBounds.get(i).lowerLimit <= rect.bottom; i++) {
-                rowEnd = i;
-            }
-
-            updateSelection(columnStart, columnEnd, rowStart, rowEnd);
-        }
-
-        /**
-         * Computes the selection given the previously-computed start- and end-indices for each
-         * row and column.
-         */
-        private void updateSelection(
-                int columnStartIndex, int columnEndIndex, int rowStartIndex, int rowEndIndex) {
-            if (DEBUG) Log.d(TAG, String.format("updateSelection: %d, %d, %d, %d",
-                    columnStartIndex, columnEndIndex, rowStartIndex, rowEndIndex));
-
-            mSelection.clear();
-            for (int column = columnStartIndex; column <= columnEndIndex; column++) {
-                SparseIntArray items = mColumns.get(mColumnBounds.get(column).lowerLimit);
-                for (int row = rowStartIndex; row <= rowEndIndex; row++) {
-                    // The default return value for SparseIntArray.get is 0, which is a valid
-                    // position. Use a sentry value to prevent erroneously selecting item 0.
-                    final int rowKey = mRowBounds.get(row).lowerLimit;
-                    int position = items.get(rowKey, NOT_SET);
-                    if (position != NOT_SET) {
-                        String id = mAdapter.getModelId(position);
-                        if (id != null) {
-                            // The adapter inserts items for UI layout purposes that aren't associated
-                            // with files.  Those will have a null model ID.  Don't select them.
-                            if (canSelect(id)) {
-                                mSelection.add(id);
-                            }
-                        }
-                        if (isPossiblePositionNearestOrigin(column, columnStartIndex, columnEndIndex,
-                                row, rowStartIndex, rowEndIndex)) {
-                            // If this is the position nearest the origin, record it now so that it
-                            // can be returned by endSelection() later.
-                            mPositionNearestOrigin = position;
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
-         * @return True if the item is selectable.
-         */
-        private boolean canSelect(String id) {
-            // TODO: Simplify the logic, so the check whether we can select is done in one place.
-            // Consider injecting ActivityConfig, or move the checks from MultiSelectManager to
-            // Selection.
-            for (GridModel.OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
-                if (!listener.onBeforeItemStateChange(id, true)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        /**
-         * @return Returns true if the position is the nearest to the origin, or, in the case of the
-         *     lower-right corner, whether it is possible that the position is the nearest to the
-         *     origin. See comment below for reasoning for this special case.
-         */
-        private boolean isPossiblePositionNearestOrigin(int columnIndex, int columnStartIndex,
-                int columnEndIndex, int rowIndex, int rowStartIndex, int rowEndIndex) {
-            int corner = computeCornerNearestOrigin();
-            switch (corner) {
-                case UPPER_LEFT:
-                    return columnIndex == columnStartIndex && rowIndex == rowStartIndex;
-                case UPPER_RIGHT:
-                    return columnIndex == columnEndIndex && rowIndex == rowStartIndex;
-                case LOWER_LEFT:
-                    return columnIndex == columnStartIndex && rowIndex == rowEndIndex;
-                case LOWER_RIGHT:
-                    // Note that in some cases, the last row will not have as many items as there
-                    // are columns (e.g., if there are 4 items and 3 columns, the second row will
-                    // only have one item in the first column). This function is invoked for each
-                    // position from left to right, so return true for any position in the bottom
-                    // row and only the right-most position in the bottom row will be recorded.
-                    return rowIndex == rowEndIndex;
-                default:
-                    throw new RuntimeException("Invalid corner type.");
-            }
-        }
-
-        /**
-         * Listener for changes in which items have been band selected.
-         */
-        static interface OnSelectionChangedListener {
-            public void onSelectionChanged(Set<String> updatedSelection);
-            public boolean onBeforeItemStateChange(String id, boolean nextState);
-        }
-
-        void addOnSelectionChangedListener(GridModel.OnSelectionChangedListener listener) {
-            mOnSelectionChangedListeners.add(listener);
-        }
-
-        void removeOnSelectionChangedListener(GridModel.OnSelectionChangedListener listener) {
-            mOnSelectionChangedListeners.remove(listener);
-        }
-
-        /**
-         * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
-         * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
-         * of item columns and the top- and bottom sides of item rows so that it can be determined
-         * whether the pointer is located within the bounds of an item.
-         */
-        private static class Limits implements Comparable<GridModel.Limits> {
-            int lowerLimit;
-            int upperLimit;
-
-            Limits(int lowerLimit, int upperLimit) {
-                this.lowerLimit = lowerLimit;
-                this.upperLimit = upperLimit;
-            }
-
-            @Override
-            public int compareTo(GridModel.Limits other) {
-                return lowerLimit - other.lowerLimit;
-            }
-
-            @Override
-            public boolean equals(Object other) {
-                if (!(other instanceof GridModel.Limits)) {
-                    return false;
-                }
-
-                return ((GridModel.Limits) other).lowerLimit == lowerLimit &&
-                        ((GridModel.Limits) other).upperLimit == upperLimit;
-            }
-
-            @Override
-            public String toString() {
-                return "(" + lowerLimit + ", " + upperLimit + ")";
-            }
-        }
-
-        /**
-         * The location of a coordinate relative to items. This class represents a general area of the
-         * view as it relates to band selection rather than an explicit point. For example, two
-         * different points within an item are considered to have the same "location" because band
-         * selection originating within the item would select the same items no matter which point
-         * was used. Same goes for points between items as well as those at the very beginning or end
-         * of the view.
-         *
-         * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
-         * advantage of tying the value to the Limits of items along that axis. This allows easy
-         * selection of items within those Limits as opposed to a search through every item to see if a
-         * given coordinate value falls within those Limits.
-         */
-        private static class RelativeCoordinate
-                implements Comparable<GridModel.RelativeCoordinate> {
-            /**
-             * Location describing points after the last known item.
-             */
-            static final int AFTER_LAST_ITEM = 0;
-
-            /**
-             * Location describing points before the first known item.
-             */
-            static final int BEFORE_FIRST_ITEM = 1;
-
-            /**
-             * Location describing points between two items.
-             */
-            static final int BETWEEN_TWO_ITEMS = 2;
-
-            /**
-             * Location describing points within the limits of one item.
-             */
-            static final int WITHIN_LIMITS = 3;
-
-            /**
-             * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
-             * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
-             */
-            final int type;
-
-            /**
-             * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
-             * BETWEEN_TWO_ITEMS.
-             */
-            GridModel.Limits limitsBeforeCoordinate;
-
-            /**
-             * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
-             */
-            GridModel.Limits limitsAfterCoordinate;
-
-            // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
-            GridModel.Limits mFirstKnownItem;
-            // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
-            GridModel.Limits mLastKnownItem;
-
-            /**
-             * @param limitsList The sorted limits list for the coordinate type. If this
-             *     CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
-             *     mYLimitsList should be pased.
-             * @param value The coordinate value.
-             */
-            RelativeCoordinate(List<GridModel.Limits> limitsList, int value) {
-                int index = Collections.binarySearch(limitsList, new Limits(value, value));
-
-                if (index >= 0) {
-                    this.type = WITHIN_LIMITS;
-                    this.limitsBeforeCoordinate = limitsList.get(index);
-                } else if (~index == 0) {
-                    this.type = BEFORE_FIRST_ITEM;
-                    this.mFirstKnownItem = limitsList.get(0);
-                } else if (~index == limitsList.size()) {
-                    GridModel.Limits lastLimits = limitsList.get(limitsList.size() - 1);
-                    if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
-                        this.type = WITHIN_LIMITS;
-                        this.limitsBeforeCoordinate = lastLimits;
-                    } else {
-                        this.type = AFTER_LAST_ITEM;
-                        this.mLastKnownItem = lastLimits;
-                    }
-                } else {
-                    GridModel.Limits limitsBeforeIndex = limitsList.get(~index - 1);
-                    if (limitsBeforeIndex.lowerLimit <= value && value <= limitsBeforeIndex.upperLimit) {
-                        this.type = WITHIN_LIMITS;
-                        this.limitsBeforeCoordinate = limitsList.get(~index - 1);
-                    } else {
-                        this.type = BETWEEN_TWO_ITEMS;
-                        this.limitsBeforeCoordinate = limitsList.get(~index - 1);
-                        this.limitsAfterCoordinate = limitsList.get(~index);
-                    }
-                }
-            }
-
-            int toComparisonValue() {
-                if (type == BEFORE_FIRST_ITEM) {
-                    return mFirstKnownItem.lowerLimit - 1;
-                } else if (type == AFTER_LAST_ITEM) {
-                    return mLastKnownItem.upperLimit + 1;
-                } else if (type == BETWEEN_TWO_ITEMS) {
-                    return limitsBeforeCoordinate.upperLimit + 1;
-                } else {
-                    return limitsBeforeCoordinate.lowerLimit;
-                }
-            }
-
-            @Override
-            public boolean equals(Object other) {
-                if (!(other instanceof GridModel.RelativeCoordinate)) {
-                    return false;
-                }
-
-                GridModel.RelativeCoordinate otherCoordinate = (GridModel.RelativeCoordinate) other;
-                return toComparisonValue() == otherCoordinate.toComparisonValue();
-            }
-
-            @Override
-            public int compareTo(GridModel.RelativeCoordinate other) {
-                return toComparisonValue() - other.toComparisonValue();
-            }
-        }
-
-        /**
-         * The location of a point relative to the Limits of nearby items; consists of both an x- and
-         * y-RelativeCoordinateLocation.
-         */
-        private class RelativePoint {
-            final GridModel.RelativeCoordinate xLocation;
-            final GridModel.RelativeCoordinate yLocation;
-
-            RelativePoint(Point point) {
-                this.xLocation = new RelativeCoordinate(mColumnBounds, point.x);
-                this.yLocation = new RelativeCoordinate(mRowBounds, point.y);
-            }
-
-            @Override
-            public boolean equals(Object other) {
-                if (!(other instanceof RelativePoint)) {
-                    return false;
-                }
-
-                RelativePoint otherPoint = (RelativePoint) other;
-                return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
-            }
-        }
-
-        /**
-         * Generates a rectangle which contains the items selected by the pointer and origin.
-         * @return The rectangle, or null if no items were selected.
-         */
-        private Rect computeBounds() {
-            Rect rect = new Rect();
-            rect.left = getCoordinateValue(
-                    min(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
-                    mColumnBounds,
-                    true);
-            rect.right = getCoordinateValue(
-                    max(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
-                    mColumnBounds,
-                    false);
-            rect.top = getCoordinateValue(
-                    min(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
-                    mRowBounds,
-                    true);
-            rect.bottom = getCoordinateValue(
-                    max(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
-                    mRowBounds,
-                    false);
-            return rect;
-        }
-
-        /**
-         * Computes the corner of the selection nearest the origin.
-         * @return
-         */
-        private int computeCornerNearestOrigin() {
-            int cornerValue = 0;
-
-            if (mRelativeOrigin.yLocation ==
-                    min(mRelativeOrigin.yLocation, mRelativePointer.yLocation)) {
-                cornerValue |= UPPER;
-            } else {
-                cornerValue |= LOWER;
-            }
-
-            if (mRelativeOrigin.xLocation ==
-                    min(mRelativeOrigin.xLocation, mRelativePointer.xLocation)) {
-                cornerValue |= LEFT;
-            } else {
-                cornerValue |= RIGHT;
-            }
-
-            return cornerValue;
-        }
-
-        private GridModel.RelativeCoordinate min(GridModel.RelativeCoordinate first, GridModel.RelativeCoordinate second) {
-            return first.compareTo(second) < 0 ? first : second;
-        }
-
-        private GridModel.RelativeCoordinate max(GridModel.RelativeCoordinate first, GridModel.RelativeCoordinate second) {
-            return first.compareTo(second) > 0 ? first : second;
-        }
-
-        /**
-         * @return The absolute coordinate (i.e., the x- or y-value) of the given relative
-         *     coordinate.
-         */
-        private int getCoordinateValue(GridModel.RelativeCoordinate coordinate,
-                List<GridModel.Limits> limitsList, boolean isStartOfRange) {
-            switch (coordinate.type) {
-                case RelativeCoordinate.BEFORE_FIRST_ITEM:
-                    return limitsList.get(0).lowerLimit;
-                case RelativeCoordinate.AFTER_LAST_ITEM:
-                    return limitsList.get(limitsList.size() - 1).upperLimit;
-                case RelativeCoordinate.BETWEEN_TWO_ITEMS:
-                    if (isStartOfRange) {
-                        return coordinate.limitsAfterCoordinate.lowerLimit;
-                    } else {
-                        return coordinate.limitsBeforeCoordinate.upperLimit;
-                    }
-                case RelativeCoordinate.WITHIN_LIMITS:
-                    return coordinate.limitsBeforeCoordinate.lowerLimit;
-            }
-
-            throw new RuntimeException("Invalid coordinate value.");
-        }
-
-        private boolean areItemsCoveredByBand(
-                RelativePoint first, RelativePoint second) {
-            return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
-                    doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
-        }
-
-        private boolean doesCoordinateLocationCoverItems(
-                GridModel.RelativeCoordinate pointerCoordinate,
-                GridModel.RelativeCoordinate originCoordinate) {
-            if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
-                    originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
-                return false;
-            }
-
-            if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
-                    originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
-                return false;
-            }
-
-            if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
-                    originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
-                    pointerCoordinate.limitsBeforeCoordinate.equals(
-                            originCoordinate.limitsBeforeCoordinate) &&
-                    pointerCoordinate.limitsAfterCoordinate.equals(
-                            originCoordinate.limitsAfterCoordinate)) {
-                return false;
-            }
-
-            return true;
-        }
-    }
-
-    /**
-     * Provides functionality for BandController. Exists primarily to tests that are
-     * fully isolated from RecyclerView.
-     */
-    interface SelectionEnvironment extends ScrollActionDelegate {
-        void showBand(Rect rect);
-        void hideBand();
-        void addOnScrollListener(RecyclerView.OnScrollListener listener);
-        void removeOnScrollListener(RecyclerView.OnScrollListener listener);
-        int getHeight();
-        void invalidateView();
-        Point createAbsolutePoint(Point relativePoint);
-        Rect getAbsoluteRectForChildViewAt(int index);
-        int getAdapterPositionAt(int index);
-        int getColumnCount();
-        int getChildCount();
-        int getVisibleChildCount();
-        /**
-         * Items may be in the adapter, but without an attached view.
-         */
-        boolean hasView(int adapterPosition);
-    }
-
-    /** Recycler view facade implementation backed by good ol' RecyclerView. */
-    private static final class RuntimeSelectionEnvironment implements SelectionEnvironment {
-
-        private final RecyclerView mView;
-        private final Drawable mBand;
-
-        private boolean mIsOverlayShown = false;
-
-        RuntimeSelectionEnvironment(RecyclerView view) {
-            mView = view;
-            mBand = mView.getContext().getTheme().getDrawable(R.drawable.band_select_overlay);
-        }
-
-        @Override
-        public int getAdapterPositionAt(int index) {
-            return mView.getChildAdapterPosition(mView.getChildAt(index));
-        }
-
-        @Override
-        public void addOnScrollListener(RecyclerView.OnScrollListener listener) {
-            mView.addOnScrollListener(listener);
-        }
-
-        @Override
-        public void removeOnScrollListener(RecyclerView.OnScrollListener listener) {
-            mView.removeOnScrollListener(listener);
-        }
-
-        @Override
-        public Point createAbsolutePoint(Point relativePoint) {
-            return new Point(relativePoint.x + mView.computeHorizontalScrollOffset(),
-                    relativePoint.y + mView.computeVerticalScrollOffset());
-        }
-
-        @Override
-        public Rect getAbsoluteRectForChildViewAt(int index) {
-            final View child = mView.getChildAt(index);
-            final Rect childRect = new Rect();
-            child.getHitRect(childRect);
-            childRect.left += mView.computeHorizontalScrollOffset();
-            childRect.right += mView.computeHorizontalScrollOffset();
-            childRect.top += mView.computeVerticalScrollOffset();
-            childRect.bottom += mView.computeVerticalScrollOffset();
-            return childRect;
-        }
-
-        @Override
-        public int getChildCount() {
-            return mView.getAdapter().getItemCount();
-        }
-
-        @Override
-        public int getVisibleChildCount() {
-            return mView.getChildCount();
-        }
-
-        @Override
-        public int getColumnCount() {
-            RecyclerView.LayoutManager layoutManager = mView.getLayoutManager();
-            if (layoutManager instanceof GridLayoutManager) {
-                return ((GridLayoutManager) layoutManager).getSpanCount();
-            }
-
-            // Otherwise, it is a list with 1 column.
-            return 1;
-        }
-
-        @Override
-        public int getHeight() {
-            return mView.getHeight();
-        }
-
-        @Override
-        public void invalidateView() {
-            mView.invalidate();
-        }
-
-        @Override
-        public void runAtNextFrame(Runnable r) {
-            mView.postOnAnimation(r);
-        }
-
-        @Override
-        public void removeCallback(Runnable r) {
-            mView.removeCallbacks(r);
-        }
-
-        @Override
-        public void scrollBy(int dy) {
-            mView.scrollBy(0, dy);
-        }
-
-        @Override
-        public void showBand(Rect rect) {
-            mBand.setBounds(rect);
-
-            if (!mIsOverlayShown) {
-                mView.getOverlay().add(mBand);
-            }
-        }
-
-        @Override
-        public void hideBand() {
-            mView.getOverlay().remove(mBand);
-        }
-
-        @Override
-        public boolean hasView(int pos) {
-            return mView.findViewHolderForAdapterPosition(pos) != null;
-        }
-    }
-}
diff --git a/src/com/android/documentsui/selection/BandPredicate.java b/src/com/android/documentsui/selection/BandPredicate.java
new file mode 100644
index 0000000..48b154b
--- /dev/null
+++ b/src/com/android/documentsui/selection/BandPredicate.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Provides a means of controlling when and where band selection is initiated.
+ * This can be used to permit band initiation in non-empty areas, like in the whitespace of
+ * a bound view. This is especially useful when there is no empty space between items.
+ */
+public abstract class BandPredicate {
+
+    /** @return true if band selection can be initiated in response to the {@link MotionEvent}. */
+    public abstract boolean canInitiate(MotionEvent e);
+
+    /**
+     * A BandPredicate that allows initiation of band selection only in areas of RecyclerView
+     * that have {@link RecyclerView#NO_POSITION}. In most cases, this will be the empty areas
+     * between views.
+     */
+    public static final class NoPositionBandPredicate extends BandPredicate {
+
+        private final RecyclerView mRecView;
+
+        public NoPositionBandPredicate(RecyclerView recView) {
+            checkArgument(recView != null);
+
+            mRecView = recView;
+        }
+
+        @Override
+        public boolean canInitiate(MotionEvent e) {
+            View itemView = mRecView.findChildViewUnder(e.getX(), e.getY());
+            int position = itemView != null
+                    ? mRecView.getChildAdapterPosition(itemView)
+                    : RecyclerView.NO_POSITION;
+
+            return position == RecyclerView.NO_POSITION;
+        }
+    };
+}
diff --git a/src/com/android/documentsui/selection/BandSelectionHelper.java b/src/com/android/documentsui/selection/BandSelectionHelper.java
new file mode 100644
index 0000000..554dcf4
--- /dev/null
+++ b/src/com/android/documentsui/selection/BandSelectionHelper.java
@@ -0,0 +1,401 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+import static android.support.v4.util.Preconditions.checkState;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Provides mouse driven band-selection support when used in conjunction with a {@link RecyclerView}
+ * instance. This class is responsible for rendering a band overlay and manipulating selection
+ * status of the items it intersects with.
+ *
+ * <p> Given the recycling nature of RecyclerView items that have scrolled off-screen would not
+ * be selectable with a band that itself was partially rendered off-screen. To address this,
+ * BandSelectionController builds a model of the list/grid information presented by RecyclerView as
+ * the user interacts with items using their pointer (and the band). Selectable items that intersect
+ * with the band, both on and off screen, are selected on pointer up.
+ */
+public class BandSelectionHelper implements OnItemTouchListener {
+
+    static final boolean DEBUG = false;
+    static final String TAG = "BandController";
+
+    private final BandHost mHost;
+    private final StableIdProvider mStableIds;
+    private final RecyclerView.Adapter<?> mAdapter;
+    private final SelectionHelper mSelectionHelper;
+    private final SelectionPredicate mSelectionPredicate;
+    private final BandPredicate mBandPredicate;
+    private final ContentLock mLock;
+    private final Runnable mViewScroller;
+    private final GridModel.SelectionObserver mGridObserver;
+    private final List<Runnable> mBandStartedListeners = new ArrayList<>();
+
+    @Nullable private Rect mBounds;
+    @Nullable private Point mCurrentPosition;
+    @Nullable private Point mOrigin;
+    @Nullable private GridModel mModel;
+
+    public BandSelectionHelper(
+            BandHost host,
+            RecyclerView.Adapter<?> adapter,
+            StableIdProvider stableIds,
+            SelectionHelper selectionHelper,
+            SelectionPredicate selectionPredicate,
+            BandPredicate bandPredicate,
+            ContentLock lock) {
+
+        checkArgument(host != null);
+        checkArgument(adapter != null);
+        checkArgument(stableIds != null);
+        checkArgument(selectionHelper != null);
+        checkArgument(selectionPredicate != null);
+        checkArgument(bandPredicate != null);
+        checkArgument(lock != null);
+
+        mHost = host;
+        mStableIds = stableIds;
+        mAdapter = adapter;
+        mSelectionHelper = selectionHelper;
+        mSelectionPredicate = selectionPredicate;
+        mBandPredicate = bandPredicate;
+        mLock = lock;
+
+        mHost.addOnScrollListener(
+                new OnScrollListener() {
+                    @Override
+                    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+                        BandSelectionHelper.this.onScrolled(recyclerView, dx, dy);
+                    }
+                });
+
+        mViewScroller = new ViewAutoScroller(
+                new ScrollHost() {
+                    @Override
+                    public Point getCurrentPosition() {
+                        return mCurrentPosition;
+                    }
+
+                    @Override
+                    public int getViewHeight() {
+                        return mHost.getHeight();
+                    }
+
+                    @Override
+                    public boolean isActive() {
+                        return BandSelectionHelper.this.isActive();
+                    }
+                },
+                host);
+
+        mAdapter.registerAdapterDataObserver(
+                new RecyclerView.AdapterDataObserver() {
+                    @Override
+                    public void onChanged() {
+                        if (isActive()) {
+                            endBandSelect();
+                        }
+                    }
+
+                    @Override
+                    public void onItemRangeChanged(
+                            int startPosition, int itemCount, Object payload) {
+                        // No change in position. Ignoring.
+                    }
+
+                    @Override
+                    public void onItemRangeInserted(int startPosition, int itemCount) {
+                        if (isActive()) {
+                            endBandSelect();
+                        }
+                    }
+
+                    @Override
+                    public void onItemRangeRemoved(int startPosition, int itemCount) {
+                        assert(startPosition >= 0);
+                        assert(itemCount > 0);
+
+                        // TODO: Should update grid model.
+                    }
+
+                    @Override
+                    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+                        throw new UnsupportedOperationException();
+                    }
+                });
+
+        mGridObserver = new GridModel.SelectionObserver() {
+                @Override
+                public void onSelectionChanged(Set<String> updatedSelection) {
+                    mSelectionHelper.setProvisionalSelection(updatedSelection);
+                }
+            };
+    }
+
+    @VisibleForTesting
+    boolean isActive() {
+        boolean active = mModel != null;
+        if (Build.IS_DEBUGGABLE && active) {
+            mLock.checkLocked();
+        }
+        return active;
+    }
+
+    /**
+     * Adds a new listener to be notified when band is created.
+     */
+    public void addOnBandStartedListener(Runnable listener) {
+        checkArgument(listener != null);
+
+        mBandStartedListeners.add(listener);
+    }
+
+    /**
+     * Removes listener. No-op if listener was not previously installed.
+     */
+    public void removeOnBandStartedListener(Runnable listener) {
+        mBandStartedListeners.remove(listener);
+    }
+
+    /**
+     * Clients must call reset when there are any material changes to the layout of items
+     * in RecyclerView.
+     */
+    public void reset() {
+        if (!isActive()) {
+            return;
+        }
+
+        mHost.hideBand();
+        mModel.stopCapturing();
+        mModel.onDestroy();
+        mModel = null;
+        mOrigin = null;
+        mLock.unblock();
+    }
+
+    boolean shouldStart(MotionEvent e) {
+        // Don't start, or extend bands on non-left clicks.
+        if (!MotionEvents.isPrimaryButtonPressed(e)) {
+            return false;
+        }
+
+        // TODO: Refactor to NOT have side-effects on this "should" method.
+        // Weird things happen if we keep up band select
+        // when touch events happen.
+        if (isActive() && !MotionEvents.isMouseEvent(e)) {
+            endBandSelect();
+            return false;
+        }
+
+        // b/30146357 && b/23793622. onInterceptTouchEvent does not dispatch events to onTouchEvent
+        // unless the event is != ACTION_DOWN. Thus, we need to actually start band selection when
+        // mouse moves, or else starting band selection on mouse down can cause problems as events
+        // don't get routed correctly to onTouchEvent.
+        return !isActive()
+                && MotionEvents.isActionMove(e)
+                // the initial button move via mouse-touch (ie. down press)
+                // The adapter inserts items for UI layout purposes that aren't
+                // associated with files. Checking against actual modelIds count
+                // effectively ignores those UI layout items.
+                && !mStableIds.getStableIds().isEmpty()
+                && mBandPredicate.canInitiate(e);
+    }
+
+    public boolean shouldStop(MotionEvent e) {
+        return isActive()
+                && MotionEvents.isMouseEvent(e)
+                && (MotionEvents.isActionUp(e)
+                        || MotionEvents.isActionPointerUp(e)
+                        || MotionEvents.isActionCancel(e));
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(RecyclerView unused, MotionEvent e) {
+        if (shouldStart(e)) {
+            if (!MotionEvents.isCtrlKeyPressed(e)) {
+                mSelectionHelper.clearSelection();
+            }
+
+            startBandSelect(MotionEvents.getOrigin(e));
+            return isActive();
+        }
+
+        if (shouldStop(e)) {
+            endBandSelect();
+            checkState(mModel == null);
+            // fall through to return false, because the band eeess done!
+        }
+
+        return false;
+    }
+
+    /**
+     * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
+     * @param input
+     */
+    @Override
+    public void onTouchEvent(RecyclerView unused, MotionEvent e) {
+        if (shouldStop(e)) {
+            endBandSelect();
+            return;
+        }
+
+        // We shouldn't get any events in this method when band select is not active,
+        // but it turns some guests show up late to the party.
+        // Probably happening when a re-layout is happening to the ReyclerView (ie. Pull-To-Refresh)
+        if (!isActive()) {
+            return;
+        }
+
+        assert MotionEvents.isActionMove(e);
+
+        mCurrentPosition = MotionEvents.getOrigin(e);
+        mModel.resizeSelection(mCurrentPosition);
+
+        scrollViewIfNecessary();
+        resizeBand();
+    }
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+
+    /**
+     * Starts band select by adding the drawable to the RecyclerView's overlay.
+     */
+    private void startBandSelect(Point origin) {
+        if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
+
+        reset();
+        mModel = new GridModel(mHost, mStableIds, mSelectionPredicate);
+        mModel.addOnSelectionChangedListener(mGridObserver);
+
+        mLock.block();
+        notifyBandStarted();
+        mOrigin = origin;
+        mModel.startCapturing(mOrigin);
+    }
+
+    private void notifyBandStarted() {
+        for (Runnable listener : mBandStartedListeners) {
+            listener.run();
+        }
+    }
+
+    private void scrollViewIfNecessary() {
+        mHost.removeCallback(mViewScroller);
+        mViewScroller.run();
+        mHost.invalidateView();
+    }
+
+    /**
+     * Resizes the band select rectangle by using the origin and the current pointer position as
+     * two opposite corners of the selection.
+     */
+    private void resizeBand() {
+        mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
+                Math.min(mOrigin.y, mCurrentPosition.y),
+                Math.max(mOrigin.x, mCurrentPosition.x),
+                Math.max(mOrigin.y, mCurrentPosition.y));
+
+        mHost.showBand(mBounds);
+    }
+
+    /**
+     * Ends band select by removing the overlay.
+     */
+    private void endBandSelect() {
+        if (DEBUG) Log.d(TAG, "Ending band select.");
+
+        // TODO: Currently when a band select operation ends outside
+        // of an item (e.g. in the empty area between items),
+        // getPositionNearestOrigin may return an unselected item.
+        // Since the point of this code is to establish the
+        // anchor point for subsequent range operations (SHIFT+CLICK)
+        // we really want to do a better job figuring out the last
+        // item selected (and nearest to the cursor).
+        int firstSelected = mModel.getPositionNearestOrigin();
+        if (firstSelected != GridModel.NOT_SET
+                && mSelectionHelper.isSelected(mStableIds.getStableId(firstSelected))) {
+            // Establish the band selection point as range anchor. This
+            // allows touch and keyboard based selection activities
+            // to be based on the band selection anchor point.
+            mSelectionHelper.anchorRange(firstSelected);
+        }
+
+        mSelectionHelper.mergeProvisionalSelection();
+        reset();
+    }
+
+    /**
+     * @see RecyclerView.OnScrollListener
+     */
+    private void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+        if (!isActive()) {
+            return;
+        }
+
+        // Adjust the y-coordinate of the origin the opposite number of pixels so that the
+        // origin remains in the same place relative to the view's items.
+        mOrigin.y -= dy;
+        resizeBand();
+    }
+
+    /**
+     * Provides functionality for BandController. Exists primarily to tests that are
+     * fully isolated from RecyclerView.
+     */
+    public static abstract class BandHost extends ScrollerCallbacks {
+        public abstract void showBand(Rect rect);
+        public abstract void hideBand();
+        public abstract void addOnScrollListener(RecyclerView.OnScrollListener listener);
+        public abstract void removeOnScrollListener(RecyclerView.OnScrollListener listener);
+        public abstract int getHeight();
+        public abstract void invalidateView();
+        public abstract Point createAbsolutePoint(Point relativePoint);
+        public abstract Rect getAbsoluteRectForChildViewAt(int index);
+        public abstract int getAdapterPositionAt(int index);
+        public abstract int getColumnCount();
+        public abstract int getChildCount();
+        public abstract int getVisibleChildCount();
+        /**
+         * @return true if the item at adapter position is attached to a view.
+         */
+        public abstract boolean hasView(int adapterPosition);
+    }
+}
diff --git a/src/com/android/documentsui/selection/ContentLock.java b/src/com/android/documentsui/selection/ContentLock.java
new file mode 100644
index 0000000..2c87d3a
--- /dev/null
+++ b/src/com/android/documentsui/selection/ContentLock.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkState;
+import static com.android.documentsui.selection.Shared.DEBUG;
+import static com.android.documentsui.selection.Shared.TAG;
+
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.content.Loader;
+import android.util.Log;
+
+/**
+ * ContentLock provides a mechanism to block content from reloading while selection
+ * activities like gesture and band selection are active. Clients using live data
+ * (data loaded, for example by a {@link Loader}), should route calls to load
+ * content through this lock using {@link ContentLock#runWhenUnlocked(Runnable)}.
+ */
+public final class ContentLock {
+
+    private int mLocks = 0;
+    private @Nullable Runnable mCallback;
+
+    /**
+     * Increment the block count by 1
+     */
+    @MainThread
+    public synchronized void block() {
+        mLocks++;
+        if (DEBUG) Log.v(TAG, "Incremented content lock count to " + mLocks + ".");
+    }
+
+    /**
+     * Decrement the block count by 1; If no other object is trying to block and there exists some
+     * callback, that callback will be run
+     */
+    @MainThread
+    public synchronized void unblock() {
+        checkState(mLocks > 0);
+
+        mLocks--;
+        if (DEBUG) Log.v(TAG, "Decremented content lock count to " + mLocks + ".");
+
+        if (mLocks == 0 && mCallback != null) {
+            mCallback.run();
+            mCallback = null;
+        }
+    }
+
+    /**
+     * Attempts to run the given Runnable if not-locked, or else the Runnable is set to be ran next
+     * (replacing any previous set Runnables).
+     */
+    public synchronized void runWhenUnlocked(Runnable runnable) {
+        if (mLocks == 0) {
+            runnable.run();
+        } else {
+            mCallback = runnable;
+        }
+    }
+
+    /**
+     * Allows other selection code to perform a precondition check asserting the state is locked.
+     */
+    final void checkLocked() {
+        checkState(mLocks > 0);
+    }
+
+    /**
+     * Allows other selection code to perform a precondition check asserting the state is unlocked.
+     */
+    final void checkUnlocked() {
+        checkState(mLocks == 0);
+    }
+}
diff --git a/src/com/android/documentsui/selection/DefaultBandHost.java b/src/com/android/documentsui/selection/DefaultBandHost.java
new file mode 100644
index 0000000..6760706
--- /dev/null
+++ b/src/com/android/documentsui/selection/DefaultBandHost.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.annotation.DrawableRes;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import com.android.documentsui.selection.BandSelectionHelper.BandHost;
+
+/**
+ * RecyclerView backed {@link BandHost}.
+ */
+public final class DefaultBandHost extends BandHost {
+
+    private final RecyclerView mRecView;
+    private final Drawable mBand;
+
+    private boolean mIsOverlayShown;
+
+    public DefaultBandHost(RecyclerView recView, @DrawableRes int bandOverlayId) {
+
+        checkArgument(recView != null);
+
+        mRecView = recView;
+        mBand = mRecView.getContext().getTheme().getDrawable(bandOverlayId);
+
+        checkArgument(mBand != null);
+    }
+
+    @Override
+    public int getAdapterPositionAt(int index) {
+        return mRecView.getChildAdapterPosition(mRecView.getChildAt(index));
+    }
+
+    @Override
+    public void addOnScrollListener(RecyclerView.OnScrollListener listener) {
+        mRecView.addOnScrollListener(listener);
+    }
+
+    @Override
+    public void removeOnScrollListener(RecyclerView.OnScrollListener listener) {
+        mRecView.removeOnScrollListener(listener);
+    }
+
+    @Override
+    public Point createAbsolutePoint(Point relativePoint) {
+        return new Point(relativePoint.x + mRecView.computeHorizontalScrollOffset(),
+                relativePoint.y + mRecView.computeVerticalScrollOffset());
+    }
+
+    @Override
+    public Rect getAbsoluteRectForChildViewAt(int index) {
+        final View child = mRecView.getChildAt(index);
+        final Rect childRect = new Rect();
+        child.getHitRect(childRect);
+        childRect.left += mRecView.computeHorizontalScrollOffset();
+        childRect.right += mRecView.computeHorizontalScrollOffset();
+        childRect.top += mRecView.computeVerticalScrollOffset();
+        childRect.bottom += mRecView.computeVerticalScrollOffset();
+        return childRect;
+    }
+
+    @Override
+    public int getChildCount() {
+        return mRecView.getAdapter().getItemCount();
+    }
+
+    @Override
+    public int getVisibleChildCount() {
+        return mRecView.getChildCount();
+    }
+
+    @Override
+    public int getColumnCount() {
+        RecyclerView.LayoutManager layoutManager = mRecView.getLayoutManager();
+        if (layoutManager instanceof GridLayoutManager) {
+            return ((GridLayoutManager) layoutManager).getSpanCount();
+        }
+
+        // Otherwise, it is a list with 1 column.
+        return 1;
+    }
+
+    @Override
+    public int getHeight() {
+        return mRecView.getHeight();
+    }
+
+    @Override
+    public void invalidateView() {
+        mRecView.invalidate();
+    }
+
+    @Override
+    public void runAtNextFrame(Runnable r) {
+        mRecView.postOnAnimation(r);
+    }
+
+    @Override
+    public void removeCallback(Runnable r) {
+        mRecView.removeCallbacks(r);
+    }
+
+    @Override
+    public void scrollBy(int dy) {
+        mRecView.scrollBy(0, dy);
+    }
+
+    @Override
+    public void showBand(Rect rect) {
+        mBand.setBounds(rect);
+
+        if (!mIsOverlayShown) {
+            mRecView.getOverlay().add(mBand);
+        }
+    }
+
+    @Override
+    public void hideBand() {
+        mRecView.getOverlay().remove(mBand);
+    }
+
+    @Override
+    public boolean hasView(int pos) {
+        return mRecView.findViewHolderForAdapterPosition(pos) != null;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/DefaultBandPredicate.java b/src/com/android/documentsui/selection/DefaultBandPredicate.java
new file mode 100644
index 0000000..5de59d8
--- /dev/null
+++ b/src/com/android/documentsui/selection/DefaultBandPredicate.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.support.annotation.Nullable;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+
+/**
+ * BandPredicate that consults ItemDetails, premitting band selection to start
+ * when the event is not in the drag region of the item.
+ */
+public final class DefaultBandPredicate extends BandPredicate {
+
+    private final ItemDetailsLookup mDetailsLookup;
+
+    public DefaultBandPredicate(ItemDetailsLookup detailsLookup) {
+        checkArgument(detailsLookup != null);
+
+        mDetailsLookup = detailsLookup;
+    }
+
+    @Override
+    public boolean canInitiate(MotionEvent e) {
+        @Nullable ItemDetails details = mDetailsLookup.getItemDetails(e);
+        return (details != null)
+            ? !details.inDragRegion(e)
+            : true;
+    }
+}
diff --git a/src/com/android/documentsui/selection/DefaultSelectionHelper.java b/src/com/android/documentsui/selection/DefaultSelectionHelper.java
new file mode 100644
index 0000000..75fcacb
--- /dev/null
+++ b/src/com/android/documentsui/selection/DefaultSelectionHelper.java
@@ -0,0 +1,554 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+import static android.support.v4.util.Preconditions.checkState;
+import static com.android.documentsui.selection.Shared.DEBUG;
+import static com.android.documentsui.selection.Shared.TAG;
+
+import android.support.annotation.IntDef;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.Adapter;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * {@link SelectionHelper} providing support traditional multi-item selection on top
+ * of {@link RecyclerView}.
+ *
+ * <p>The class supports running in a single-select mode, which can be enabled
+ * by passing {@colde #MODE_SINGLE} to the constructor.
+ */
+public final class DefaultSelectionHelper extends SelectionHelper {
+
+    public static final int MODE_MULTIPLE = 0;
+    public static final int MODE_SINGLE = 1;
+
+    @IntDef(flag = true, value = {
+            MODE_MULTIPLE,
+            MODE_SINGLE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SelectionMode {}
+
+    private static final int RANGE_REGULAR = 0;
+
+    /**
+     * "Provisional" selection represents a overlay on the primary selection. A provisional
+     * selection maybe be eventually added to the primary selection, or it may be abandoned.
+     *
+     * <p>E.g. BandController creates a provisional selection while a user is actively selecting
+     * items with the band. Provisionally selected items are considered to be selected in
+     * {@link Selection#contains(String)} and related methods. A provisional may be abandoned or
+     * applied by selection components (like
+     * {@link com.android.documentsui.selection.BandSelectionHelper}).
+     *
+     * <p>A provisional selection may intersect the primary selection, however clearing the
+     * provisional selection will not affect the primary selection where the two may intersect.
+     */
+    private static final int RANGE_PROVISIONAL = 1;
+    @IntDef({
+        RANGE_REGULAR,
+        RANGE_PROVISIONAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface RangeType {}
+
+    private final Selection mSelection = new Selection();
+    private final List<SelectionObserver> mObservers = new ArrayList<>(1);
+    private final RecyclerView.Adapter<?> mAdapter;
+    private final StableIdProvider mStableIds;
+    private final SelectionPredicate mSelectionPredicate;
+    private final RecyclerView.AdapterDataObserver mAdapterObserver;
+    private final RangeCallbacks mRangeCallbacks;
+    private final boolean mSingleSelect;
+
+    private @Nullable Range mRange;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param mode single or multiple selection mode. In single selection mode
+     *     users can only select a single item.
+     * @param adapter {@link Adapter} for the RecyclerView this instance is coupled with.
+     * @param stableIds client supplied class providing access to stable ids.
+     * @param selectionPredicate A predicate allowing the client to disallow selection
+     *     of individual elements.
+     */
+    public DefaultSelectionHelper(
+            @SelectionMode int mode,
+            RecyclerView.Adapter<?> adapter,
+            StableIdProvider stableIds,
+            SelectionPredicate selectionPredicate) {
+
+        checkArgument(mode == MODE_SINGLE || mode == MODE_MULTIPLE);
+        checkArgument(adapter != null);
+        checkArgument(stableIds != null);
+        checkArgument(selectionPredicate != null);
+
+        mAdapter = adapter;
+        mStableIds = stableIds;
+        mSelectionPredicate = selectionPredicate;
+        mAdapterObserver = new AdapterObserver();
+        mRangeCallbacks = new RangeCallbacks();
+
+        mSingleSelect = mode == MODE_SINGLE;
+
+        mAdapter.registerAdapterDataObserver(mAdapterObserver);
+    }
+
+    @Override
+    public void addObserver(SelectionObserver callback) {
+        checkArgument(callback != null);
+        mObservers.add(callback);
+    }
+
+    @Override
+    public boolean hasSelection() {
+        return !mSelection.isEmpty();
+    }
+
+    @Override
+    public Selection getSelection() {
+        return mSelection;
+    }
+
+    @Override
+    public void copySelection(Selection dest) {
+        dest.copyFrom(mSelection);
+    }
+
+    @Override
+    public boolean isSelected(String id) {
+        return mSelection.contains(id);
+    }
+
+    @Override
+    public void restoreSelection(Selection other) {
+        setItemsSelectedQuietly(other.mSelection, true);
+        // NOTE: We intentionally don't restore provisional selection. It's provisional.
+        notifySelectionRestored();
+    }
+
+    @Override
+    public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
+        boolean changed = setItemsSelectedQuietly(ids, selected);
+        notifySelectionChanged();
+        return changed;
+    }
+
+    private boolean setItemsSelectedQuietly(Iterable<String> ids, boolean selected) {
+        boolean changed = false;
+        for (String id: ids) {
+            boolean itemChanged = selected
+                    ? canSetState(id, true) && mSelection.add(id)
+                    : canSetState(id, false) && mSelection.remove(id);
+            if (itemChanged) {
+                notifyItemStateChanged(id, selected);
+            }
+            changed |= itemChanged;
+        }
+        return changed;
+    }
+
+    @Override
+    public void clearSelection() {
+        if (!hasSelection()) {
+            return;
+        }
+
+        Selection prev = clearSelectionQuietly();
+        notifySelectionCleared(prev);
+        notifySelectionChanged();
+    }
+
+    /**
+     * Clears the selection, without notifying selection listeners.
+     * Returns items in previous selection. Callers are responsible for notifying
+     * listeners about changes.
+     */
+    private Selection clearSelectionQuietly() {
+        mRange = null;
+
+        Selection prevSelection = new Selection();
+        if (hasSelection()) {
+            copySelection(prevSelection);
+            mSelection.clear();
+        }
+
+        return prevSelection;
+    }
+
+    @Override
+    public boolean select(String id) {
+        checkArgument(id != null);
+
+        if (!mSelection.contains(id)) {
+            if (!canSetState(id, true)) {
+                if (DEBUG) Log.d(TAG, "Select cancelled by selection predicate test.");
+                return false;
+            }
+
+            // Enforce single selection policy.
+            if (mSingleSelect && hasSelection()) {
+                Selection prev = clearSelectionQuietly();
+                notifySelectionCleared(prev);
+            }
+
+            mSelection.add(id);
+            notifyItemStateChanged(id, true);
+            notifySelectionChanged();
+
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean deselect(String id) {
+        checkArgument(id != null);
+
+        if (mSelection.contains(id)) {
+            if (!canSetState(id, false)) {
+                if (DEBUG) Log.d(TAG, "Deselect cancelled by selection predicate test.");
+                return false;
+            }
+            mSelection.remove(id);
+            notifyItemStateChanged(id, false);
+            notifySelectionChanged();
+            if (mSelection.isEmpty() && isRangeActive()) {
+                // if there's nothing in the selection and there is an active ranger it results
+                // in unexpected behavior when the user tries to start range selection: the item
+                // which the ranger 'thinks' is the already selected anchor becomes unselectable
+                endRange();
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public void startRange(int pos) {
+        select(mStableIds.getStableId(pos));
+        anchorRange(pos);
+    }
+
+    @Override
+    public void extendRange(int pos) {
+        extendRange(pos, RANGE_REGULAR);
+    }
+
+    @Override
+    public void endRange() {
+        mRange = null;
+        // Clean up in case there was any leftover provisional selection
+        clearProvisionalSelection();
+    }
+
+    @Override
+    public void anchorRange(int position) {
+        checkArgument(position != RecyclerView.NO_POSITION);
+
+        // TODO: I'm not a fan of silently ignoring calls.
+        // Determine if there are any cases where method can be called
+        // w/o item already being selected. Else, tighten up the ship
+        // and make this conditional guard into a proper precondition check.
+        if (mSelection.contains(mStableIds.getStableId(position))) {
+            mRange = new Range(mRangeCallbacks, position);
+        }
+    }
+
+    @Override
+    public void extendProvisionalRange(int pos) {
+        extendRange(pos, RANGE_PROVISIONAL);
+    }
+
+    /**
+     * Sets the end point for the current range selection, started by a call to
+     * {@link #startRange(int)}. This function should only be called when a range selection
+     * is active (see {@link #isRangeActive()}. Items in the range [anchor, end] will be
+     * selected or in provisional select, depending on the type supplied. Note that if the type is
+     * provisional selection, one should do {@link #mergeProvisionalSelection()} at some
+     * point before calling on {@link #endRange()}.
+     *
+     * @param pos The new end position for the selection range.
+     * @param type The type of selection the range should utilize.
+     */
+    private void extendRange(int pos, @RangeType int type) {
+        checkState(isRangeActive(), "Range start point not set.");
+
+        mRange.extendSelection(pos, type);
+
+        // We're being lazy here notifying even when something might not have changed.
+        // To make this more correct, we'd need to update the Ranger class to return
+        // information about what has changed.
+        notifySelectionChanged();
+    }
+
+    @Override
+    public void setProvisionalSelection(Set<String> newSelection) {
+        Map<String, Boolean> delta = mSelection.setProvisionalSelection(newSelection);
+        for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
+            notifyItemStateChanged(entry.getKey(), entry.getValue());
+        }
+
+        notifySelectionChanged();
+    }
+
+    @Override
+    public void mergeProvisionalSelection() {
+        mSelection.mergeProvisionalSelection();
+    }
+
+    @Override
+    public void clearProvisionalSelection() {
+        for (String id : mSelection.mProvisionalSelection) {
+            notifyItemStateChanged(id, false);
+        }
+        mSelection.clearProvisionalSelection();
+    }
+
+    @Override
+    public boolean isRangeActive() {
+        return mRange != null;
+    }
+
+    private boolean canSetState(String id, boolean nextState) {
+        return mSelectionPredicate.canSetStateForId(id, nextState);
+    }
+
+    private void onDataSetChanged() {
+        // Update the selection to remove any disappeared IDs.
+        mSelection.clearProvisionalSelection();
+        mSelection.intersect(mStableIds.getStableIds());
+        notifySelectionReset();
+
+        for (String id : mSelection) {
+            // If the underlying data set has changed, before restoring
+            // selection we must re-verify that it can be selected.
+            // Why? Because if the dataset has changed, then maybe the
+            // selectability of an item has changed.
+            if (!canSetState(id, true)) {
+                deselect(id);
+            } else {
+                int lastListener = mObservers.size() - 1;
+                for (int i = lastListener; i >= 0; i--) {
+                    mObservers.get(i).onItemStateChanged(id, true);
+                }
+            }
+        }
+        notifySelectionChanged();
+    }
+
+    private void onDataSetItemRangeInserted(int startPosition, int itemCount) {
+        mSelection.clearProvisionalSelection();
+    }
+
+    private void onDataSetItemRangeRemoved(int startPosition, int itemCount) {
+        checkArgument(startPosition >= 0);
+        checkArgument(itemCount > 0);
+
+        mSelection.clearProvisionalSelection();
+
+        // Remove any disappeared IDs from the selection.
+        //
+        // Ideally there could be a cheaper approach, checking
+        // each position individually, but since the source of
+        // truth for stable ids (StableIdProvider) probably
+        // it-self no-longer knows about the positions in question
+        // we fall back to the sledge hammer approach.
+        mSelection.intersect(mStableIds.getStableIds());
+    }
+
+    /**
+     * Notifies registered listeners when the selection status of a single item
+     * (identified by {@code position}) changes.
+     */
+    private void notifyItemStateChanged(String id, boolean selected) {
+        checkArgument(id != null);
+
+        int lastListenerIndex = mObservers.size() - 1;
+        for (int i = lastListenerIndex; i >= 0; i--) {
+            mObservers.get(i).onItemStateChanged(id, selected);
+        }
+
+        int position = mStableIds.getPosition(id);
+        if (DEBUG) Log.d(TAG, "ITEM " + id + " CHANGED at pos: " + position);
+
+        if (position >= 0) {
+            mAdapter.notifyItemChanged(position, SelectionHelper.SELECTION_CHANGED_MARKER);
+        } else {
+            Log.w(TAG, "Item change notification received for unknown item: " + id);
+        }
+    }
+
+    private void notifySelectionCleared(Selection selection) {
+        for (String id: selection.mSelection) {
+            notifyItemStateChanged(id, false);
+        }
+        for (String id: selection.mProvisionalSelection) {
+            notifyItemStateChanged(id, false);
+        }
+    }
+
+    /**
+     * Notifies registered listeners when the selection has changed. This
+     * notification should be sent only once a full series of changes
+     * is complete, e.g. clearingSelection, or updating the single
+     * selection from one item to another.
+     */
+    private void notifySelectionChanged() {
+        int lastListenerIndex = mObservers.size() - 1;
+        for (int i = lastListenerIndex; i >= 0; i--) {
+            mObservers.get(i).onSelectionChanged();
+        }
+    }
+
+    private void notifySelectionRestored() {
+        int lastListenerIndex = mObservers.size() - 1;
+        for (int i = lastListenerIndex; i >= 0; i--) {
+            mObservers.get(i).onSelectionRestored();
+        }
+    }
+
+    private void notifySelectionReset() {
+        int lastListenerIndex = mObservers.size() - 1;
+        for (int i = lastListenerIndex; i >= 0; i--) {
+            mObservers.get(i).onSelectionReset();
+        }
+    }
+
+    private void updateForRange(int begin, int end, boolean selected, @RangeType int type) {
+        switch (type) {
+            case RANGE_REGULAR:
+                updateForRegularRange(begin, end, selected);
+                break;
+            case RANGE_PROVISIONAL:
+                updateForProvisionalRange(begin, end, selected);
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid range type: " + type);
+        }
+    }
+
+    private void updateForRegularRange(int begin, int end, boolean selected) {
+        checkArgument(end >= begin);
+
+        for (int i = begin; i <= end; i++) {
+            String id = mStableIds.getStableId(i);
+            if (id == null) {
+                continue;
+            }
+
+            if (selected) {
+                select(id);
+            } else {
+                deselect(id);
+            }
+        }
+    }
+
+    private void updateForProvisionalRange(int begin, int end, boolean selected) {
+        checkArgument(end >= begin);
+
+        for (int i = begin; i <= end; i++) {
+            String id = mStableIds.getStableId(i);
+            if (id == null) {
+                continue;
+            }
+
+            boolean changedState = false;
+            if (selected) {
+                boolean canSelect = canSetState(id, true);
+                if (canSelect && !mSelection.mSelection.contains(id)) {
+                    mSelection.mProvisionalSelection.add(id);
+                    changedState = true;
+                }
+            } else {
+                mSelection.mProvisionalSelection.remove(id);
+                changedState = true;
+            }
+
+            // Only notify item callbacks when something's state is actually changed in provisional
+            // selection.
+            if (changedState) {
+                notifyItemStateChanged(id, selected);
+            }
+        }
+
+        notifySelectionChanged();
+    }
+
+    private final class AdapterObserver extends RecyclerView.AdapterDataObserver {
+        @Override
+        public void onChanged() {
+            onDataSetChanged();
+        }
+
+        @Override
+        public void onItemRangeChanged(
+                int startPosition, int itemCount, Object payload) {
+            // No change in position. Ignore, since we assume
+            // selection is a user driven activity. So changes
+            // in properties of items shouldn't result in a
+            // change of selection.
+        }
+
+        @Override
+        public void onItemRangeInserted(int startPosition, int itemCount) {
+            onDataSetItemRangeInserted(startPosition, itemCount);
+        }
+
+        @Override
+        public void onItemRangeRemoved(int startPosition, int itemCount) {
+            onDataSetItemRangeRemoved(startPosition, itemCount);
+        }
+
+        @Override
+        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private final class RangeCallbacks extends Range.Callbacks {
+        @Override
+        void updateForRange(int begin, int end, boolean selected, int type) {
+            switch (type) {
+                case RANGE_REGULAR:
+                    updateForRegularRange(begin, end, selected);
+                    break;
+                case RANGE_PROVISIONAL:
+                    updateForProvisionalRange(begin, end, selected);
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Invalid range type: " + type);
+            }
+        }
+    }
+}
diff --git a/src/com/android/documentsui/selection/GestureRouter.java b/src/com/android/documentsui/selection/GestureRouter.java
new file mode 100644
index 0000000..b336450
--- /dev/null
+++ b/src/com/android/documentsui/selection/GestureRouter.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkNotNull;
+
+import android.support.annotation.Nullable;
+import android.view.GestureDetector.OnDoubleTapListener;
+import android.view.GestureDetector.OnGestureListener;
+import android.view.GestureDetector.SimpleOnGestureListener;
+import android.view.MotionEvent;
+
+/**
+ * GestureRouter is responsible for routing gestures detected by a GestureDetector
+ * to registered handlers. The primary function is to divide events by tool-type
+ * allowing handlers to cleanly implement tool-type specific policies.
+ */
+public final class GestureRouter<T extends OnGestureListener & OnDoubleTapListener>
+        implements OnGestureListener, OnDoubleTapListener {
+
+    private final ToolHandlerRegistry<T> mDelegates;
+
+    public GestureRouter(T defaultDelegate) {
+        checkNotNull(defaultDelegate);
+        mDelegates = new ToolHandlerRegistry<>(defaultDelegate);
+    }
+
+    public GestureRouter() {
+        this((T) new SimpleOnGestureListener());
+    }
+
+    /**
+     * @param toolType
+     * @param delegate the delegate, or null to unregister.
+     */
+    public void register(int toolType, @Nullable T delegate) {
+        mDelegates.set(toolType, delegate);
+    }
+
+    @Override
+    public boolean onSingleTapConfirmed(MotionEvent e) {
+        return mDelegates.get(e).onSingleTapConfirmed(e);
+    }
+
+    @Override
+    public boolean onDoubleTap(MotionEvent e) {
+        return mDelegates.get(e).onDoubleTap(e);
+    }
+
+    @Override
+    public boolean onDoubleTapEvent(MotionEvent e) {
+        return mDelegates.get(e).onDoubleTapEvent(e);
+    }
+
+    @Override
+    public boolean onDown(MotionEvent e) {
+        return mDelegates.get(e).onDown(e);
+    }
+
+    @Override
+    public void onShowPress(MotionEvent e) {
+        mDelegates.get(e).onShowPress(e);
+    }
+
+    @Override
+    public boolean onSingleTapUp(MotionEvent e) {
+        return mDelegates.get(e).onSingleTapUp(e);
+    }
+
+    @Override
+    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+        return mDelegates.get(e2).onScroll(e1, e2, distanceX, distanceY);
+    }
+
+    @Override
+    public void onLongPress(MotionEvent e) {
+        mDelegates.get(e).onLongPress(e);
+    }
+
+    @Override
+    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+        return mDelegates.get(e2).onFling(e1, e2, velocityX, velocityY);
+    }
+}
diff --git a/src/com/android/documentsui/selection/GestureSelectionHelper.java b/src/com/android/documentsui/selection/GestureSelectionHelper.java
new file mode 100644
index 0000000..f3456fd
--- /dev/null
+++ b/src/com/android/documentsui/selection/GestureSelectionHelper.java
@@ -0,0 +1,316 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+import static android.support.v4.util.Preconditions.checkState;
+
+import android.graphics.Point;
+import android.os.Build;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
+
+/**
+ * GestureSelectionHelper provides logic that interprets a combination
+ * of motions and gestures in order to provide gesture driven selection support
+ * when used in conjunction with RecyclerView and other classes in the ReyclerView
+ * selection support package.
+ */
+public final class GestureSelectionHelper extends ScrollHost implements OnItemTouchListener {
+
+    private static final String TAG = "GestureSelectionHelper";
+
+    private final SelectionHelper mSelectionMgr;
+    private final Runnable mScroller;
+    private final ViewDelegate mView;
+    private final ContentLock mLock;
+
+    private int mLastStartedItemPos = -1;
+    private boolean mStarted = false;
+    private Point mLastInterceptedPoint;
+
+    /**
+     * See {@link #create(SelectionHelper, RecyclerView, ContentLock)} for convenience
+     * method.
+     */
+    @VisibleForTesting
+    GestureSelectionHelper(
+            SelectionHelper selectionHelper,
+            ViewDelegate view,
+            ContentLock lock) {
+
+        checkArgument(selectionHelper != null);
+        checkArgument(view != null);
+        checkArgument(lock != null);
+
+        mSelectionMgr = selectionHelper;
+        mView = view;
+        mLock = lock;
+
+        mScroller = new ViewAutoScroller(this, mView);
+    }
+
+    /**
+     * Explicitly kicks off a gesture multi-select.
+     *
+     * @return true if started.
+     */
+    public void start() {
+        checkState(!mStarted);
+        checkState(mLastStartedItemPos > -1);
+
+        // Partner code in MotionInputHandler ensures items
+        // are selected and range established prior to
+        // start being called.
+        // Verify the truth of that statement here
+        // to make the implicit coupling less of a time bomb.
+        checkState(mSelectionMgr.isRangeActive());
+
+        mLock.checkUnlocked();
+
+        mStarted = true;
+        mLock.block();
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(RecyclerView unused, MotionEvent e) {
+        if (MotionEvents.isMouseEvent(e)) {
+            if (Shared.DEBUG) Log.w(TAG, "Unexpected Mouse event. Check configuration.");
+        }
+
+        switch (e.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                // NOTE: Unlike events with other actions, RecyclerView eats
+                // "DOWN" events. So even if we return true here we'll
+                // never see an event w/ ACTION_DOWN passed to onTouchEvent.
+                return handleInterceptedDownEvent(e);
+            case MotionEvent.ACTION_MOVE:
+                return mStarted;
+        }
+
+        return false;
+    }
+
+    @Override
+    public void onTouchEvent(RecyclerView unused, MotionEvent e) {
+        // Note: There were a couple times I as this check firing
+        // after combinations of mouse + touch + rotation.
+        // But after further investigation I couldn't repro.
+        // For that reason we guard this check (for now) w/ IS_DEBUGGABLE.
+        if (Build.IS_DEBUGGABLE) checkState(mStarted);
+
+        switch (e.getActionMasked()) {
+            case MotionEvent.ACTION_MOVE:
+                handleMoveEvent(e);
+                break;
+            case MotionEvent.ACTION_UP:
+                handleUpEvent(e);
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                handleCancelEvent(e);
+                break;
+        }
+    }
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+
+    // Called when an ACTION_DOWN event is intercepted.
+    // If down event happens on an item, we mark that item's position as last started.
+    private boolean handleInterceptedDownEvent(MotionEvent e) {
+        mLastStartedItemPos = mView.getItemUnder(e);
+        return mLastStartedItemPos != RecyclerView.NO_POSITION;
+    }
+
+    // Called when ACTION_UP event is to be handled.
+    // Essentially, since this means all gesture movement is over, reset everything and apply
+    // provisional selection.
+    private void handleUpEvent(MotionEvent e) {
+        mSelectionMgr.mergeProvisionalSelection();
+        endSelection();
+        if (mLastStartedItemPos > -1) {
+            mSelectionMgr.startRange(mLastStartedItemPos);
+        }
+    }
+
+    // Called when ACTION_CANCEL event is to be handled.
+    // This means this gesture selection is aborted, so reset everything and abandon provisional
+    // selection.
+    private void handleCancelEvent(MotionEvent unused) {
+        mSelectionMgr.clearProvisionalSelection();
+        endSelection();
+    }
+
+    private void endSelection() {
+        checkState(mStarted);
+
+        mLastStartedItemPos = -1;
+        mStarted = false;
+        mLock.unblock();
+    }
+
+    // Call when an intercepted ACTION_MOVE event is passed down.
+    // At this point, we are sure user wants to gesture multi-select.
+    private void handleMoveEvent(MotionEvent e) {
+        mLastInterceptedPoint = MotionEvents.getOrigin(e);
+
+        int lastGlidedItemPos = mView.getLastGlidedItemPosition(e);
+        if (lastGlidedItemPos != RecyclerView.NO_POSITION) {
+            doGestureMultiSelect(lastGlidedItemPos);
+        }
+        scrollIfNecessary();
+    }
+
+    // It's possible for events to go over the top/bottom of the RecyclerView.
+    // We want to get a Y-coordinate within the RecyclerView so we can find the childView underneath
+    // correctly.
+    private static float getInboundY(float max, float y) {
+        if (y < 0f) {
+            return 0f;
+        } else if (y > max) {
+            return max;
+        }
+        return y;
+    }
+
+    /* Given the end position, select everything in-between.
+     * @param endPos  The adapter position of the end item.
+     */
+    private void doGestureMultiSelect(int endPos) {
+        mSelectionMgr.extendProvisionalRange(endPos);
+    }
+
+    private void scrollIfNecessary() {
+        mScroller.run();
+    }
+
+    @Override
+    public Point getCurrentPosition() {
+        return mLastInterceptedPoint;
+    }
+
+    @Override
+    public int getViewHeight() {
+        return mView.getHeight();
+    }
+
+    @Override
+    public boolean isActive() {
+        return mStarted && mSelectionMgr.hasSelection();
+    }
+
+    /**
+     * Returns a new instance of GestureSelectionHelper.
+     */
+    public static GestureSelectionHelper create(
+            SelectionHelper selectionMgr, RecyclerView recycler, ContentLock lock) {
+
+        return new GestureSelectionHelper(
+                selectionMgr, new RecyclerViewDelegate(recycler), lock);
+    }
+
+    @VisibleForTesting
+    static abstract class ViewDelegate extends ScrollerCallbacks {
+        abstract int getHeight();
+        abstract int getItemUnder(MotionEvent e);
+        abstract int getLastGlidedItemPosition(MotionEvent e);
+    }
+
+    @VisibleForTesting
+    static final class RecyclerViewDelegate extends ViewDelegate {
+
+        private final RecyclerView mView;
+
+        RecyclerViewDelegate(RecyclerView view) {
+            checkArgument(view != null);
+            mView = view;
+        }
+
+        @Override
+        int getHeight() {
+            return mView.getHeight();
+        }
+
+        @Override
+        int getItemUnder(MotionEvent e) {
+            View child = mView.findChildViewUnder(e.getX(), e.getY());
+            return child != null
+                    ? mView.getChildAdapterPosition(child)
+                    : RecyclerView.NO_POSITION;
+        }
+
+        @Override
+        int getLastGlidedItemPosition(MotionEvent e) {
+            // If user has moved his pointer to the bottom-right empty pane (ie. to the right of the
+            // last item of the recycler view), we would want to set that as the currentItemPos
+            View lastItem = mView.getLayoutManager()
+                    .getChildAt(mView.getLayoutManager().getChildCount() - 1);
+            int direction =
+                    mView.getContext().getResources().getConfiguration().getLayoutDirection();
+            final boolean pastLastItem = isPastLastItem(lastItem.getTop(),
+                    lastItem.getLeft(),
+                    lastItem.getRight(),
+                    e,
+                    direction);
+
+            // Since views get attached & detached from RecyclerView,
+            // {@link LayoutManager#getChildCount} can return a different number from the actual
+            // number
+            // of items in the adapter. Using the adapter is the for sure way to get the actual last
+            // item position.
+            final float inboundY = getInboundY(mView.getHeight(), e.getY());
+            return (pastLastItem) ? mView.getAdapter().getItemCount() - 1
+                    : mView.getChildAdapterPosition(mView.findChildViewUnder(e.getX(), inboundY));
+        }
+
+        /*
+         * Check to see if MotionEvent if past a particular item, i.e. to the right or to the bottom
+         * of the item.
+         * For RTL, it would to be to the left or to the bottom of the item.
+         */
+        @VisibleForTesting
+        static boolean isPastLastItem(int top, int left, int right, MotionEvent e, int direction) {
+            if (direction == View.LAYOUT_DIRECTION_LTR) {
+                return e.getX() > right && e.getY() > top;
+            } else {
+                return e.getX() < left && e.getY() > top;
+            }
+        }
+
+        @Override
+        public void scrollBy(int dy) {
+            mView.scrollBy(0, dy);
+        }
+
+        @Override
+        public void runAtNextFrame(Runnable r) {
+            mView.postOnAnimation(r);
+        }
+
+        @Override
+        public void removeCallback(Runnable r) {
+            mView.removeCallbacks(r);
+        }
+    }
+}
diff --git a/src/com/android/documentsui/selection/GestureSelector.java b/src/com/android/documentsui/selection/GestureSelector.java
deleted file mode 100644
index 7c5f217..0000000
--- a/src/com/android/documentsui/selection/GestureSelector.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import static com.android.documentsui.base.Shared.DEBUG;
-
-import android.graphics.Point;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.View;
-
-import com.android.documentsui.DirectoryReloadLock;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.ui.ViewAutoScroller;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollActionDelegate;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollDistanceDelegate;
-
-import java.util.function.IntSupplier;
-
-import javax.annotation.Nullable;
-
-/*
- * Helper class used to intercept events that could cause a gesture multi-select, and keeps
- * the interception going if necessary.
- */
-public final class GestureSelector {
-    private final String TAG = "GestureSelector";
-
-    private final SelectionManager mSelectionMgr;
-    private final Runnable mDragScroller;
-    private final IntSupplier mHeight;
-    private final ViewFinder mViewFinder;
-    private final DirectoryReloadLock mLock;
-    private int mLastStartedItemPos = -1;
-    private boolean mStarted = false;
-    private Point mLastInterceptedPoint;
-
-    GestureSelector(
-            SelectionManager selectionMgr,
-            IntSupplier heightSupplier,
-            ViewFinder viewFinder,
-            ScrollActionDelegate actionDelegate,
-            DirectoryReloadLock lock) {
-        mSelectionMgr = selectionMgr;
-        mHeight = heightSupplier;
-        mViewFinder = viewFinder;
-        mLock = lock;
-
-        ScrollDistanceDelegate distanceDelegate = new ScrollDistanceDelegate() {
-            @Override
-            public Point getCurrentPosition() {
-                return mLastInterceptedPoint;
-            }
-
-            @Override
-            public int getViewHeight() {
-                return mHeight.getAsInt();
-            }
-
-            @Override
-            public boolean isActive() {
-                return mStarted && mSelectionMgr.hasSelection();
-            }
-        };
-
-        mDragScroller = new ViewAutoScroller(distanceDelegate, actionDelegate);
-    }
-
-    public static GestureSelector create(
-            SelectionManager selectionMgr,
-            RecyclerView scrollView,
-            DirectoryReloadLock lock) {
-        ScrollActionDelegate actionDelegate = new ScrollActionDelegate() {
-            @Override
-            public void scrollBy(int dy) {
-                scrollView.scrollBy(0, dy);
-            }
-
-            @Override
-            public void runAtNextFrame(Runnable r) {
-                scrollView.postOnAnimation(r);
-            }
-
-            @Override
-            public void removeCallback(Runnable r) {
-                scrollView.removeCallbacks(r);
-            }
-        };
-        GestureSelector helper =
-                new GestureSelector(
-                        selectionMgr,
-                        scrollView::getHeight,
-                        scrollView::findChildViewUnder,
-                        actionDelegate,
-                        lock);
-
-        return helper;
-    }
-
-    // Explicitly kick off a gesture multi-select.
-    public boolean start(InputEvent event) {
-        //the anchor must already be set before a multi-select event can be started
-        if (mLastStartedItemPos < 0) {
-            if (DEBUG) Log.d(TAG, "Tried to start multi-select without setting an anchor.");
-            return false;
-        }
-        if (mStarted) {
-            return false;
-        }
-        mStarted = true;
-        return true;
-    }
-
-    public boolean onInterceptTouchEvent(InputEvent e) {
-        if (e.isMouseEvent()) {
-            return false;
-        }
-
-        boolean handled = false;
-
-        if (e.isActionDown()) {
-            handled = handleInterceptedDownEvent(e);
-        }
-
-        if (e.isActionMove()) {
-            handled = handleInterceptedMoveEvent(e);
-        }
-
-        return handled;
-    }
-
-    public void onTouchEvent(RecyclerView rv, InputEvent e) {
-        if (!mStarted) {
-            return;
-        }
-
-        if (e.isActionUp()) {
-            handleUpEvent(e);
-        }
-
-        if (e.isActionCancel()) {
-            handleCancelEvent(e);
-        }
-
-        if (e.isActionMove()) {
-            handleOnTouchMoveEvent(rv, e);
-        }
-    }
-
-    // Called when an ACTION_DOWN event is intercepted.
-    // If down event happens on a file/doc, we mark that item's position as last started.
-    private boolean handleInterceptedDownEvent(InputEvent e) {
-        View itemView = mViewFinder.findView(e.getX(), e.getY());
-        if (itemView != null) {
-            mLastStartedItemPos = e.getItemPosition();
-        }
-        return false;
-    }
-
-    // Called when an ACTION_MOVE event is intercepted.
-    private boolean handleInterceptedMoveEvent(InputEvent e) {
-        mLastInterceptedPoint = e.getOrigin();
-        if (mStarted) {
-            mSelectionMgr.startRangeSelection(mLastStartedItemPos);
-            // Gesture Selection about to start
-            mLock.block();
-            return true;
-        }
-        return false;
-    }
-
-    // Called when ACTION_UP event is to be handled.
-    // Essentially, since this means all gesture movement is over, reset everything and apply
-    // provisional selection.
-    private void handleUpEvent(InputEvent e) {
-        mSelectionMgr.getSelection().applyProvisionalSelection();
-        endSelection();
-    }
-
-    // Called when ACTION_CANCEL event is to be handled.
-    // This means this gesture selection is aborted, so reset everything and abandon provisional
-    // selection.
-    private void handleCancelEvent(InputEvent e) {
-        mSelectionMgr.cancelProvisionalSelection();
-        endSelection();
-    }
-
-    private void endSelection() {
-        assert(mStarted);
-        mLastStartedItemPos = -1;
-        mStarted = false;
-        mLock.unblock();
-    }
-
-    // Call when an intercepted ACTION_MOVE event is passed down.
-    // At this point, we are sure user wants to gesture multi-select.
-    private void handleOnTouchMoveEvent(RecyclerView rv, InputEvent e) {
-        mLastInterceptedPoint = e.getOrigin();
-
-        // If user has moved his pointer to the bottom-right empty pane (ie. to the right of the
-        // last item of the recycler view), we would want to set that as the currentItemPos
-        View lastItem = rv.getLayoutManager()
-                .getChildAt(rv.getLayoutManager().getChildCount() - 1);
-        int direction = rv.getContext().getResources().getConfiguration().getLayoutDirection();
-        final boolean pastLastItem = isPastLastItem(lastItem.getTop(),
-                lastItem.getLeft(),
-                lastItem.getRight(),
-                e,
-                direction);
-
-        // Since views get attached & detached from RecyclerView,
-        // {@link LayoutManager#getChildCount} can return a different number from the actual
-        // number
-        // of items in the adapter. Using the adapter is the for sure way to get the actual last
-        // item position.
-        final float inboundY = getInboundY(rv.getHeight(), e.getY());
-        final int lastGlidedItemPos = (pastLastItem) ? rv.getAdapter().getItemCount() - 1
-                : rv.getChildAdapterPosition(rv.findChildViewUnder(e.getX(), inboundY));
-        if (lastGlidedItemPos != RecyclerView.NO_POSITION) {
-            doGestureMultiSelect(lastGlidedItemPos);
-        }
-        scrollIfNecessary();
-    }
-
-    // It's possible for events to go over the top/bottom of the RecyclerView.
-    // We want to get a Y-coordinate within the RecyclerView so we can find the childView underneath
-    // correctly.
-    private static float getInboundY(float max, float y) {
-        if (y < 0f) {
-            return 0f;
-        } else if (y > max) {
-            return max;
-        }
-        return y;
-    }
-
-    /*
-     * Check to see an InputEvent if past a particular item, i.e. to the right or to the bottom
-     * of the item.
-     * For RTL, it would to be to the left or to the bottom of the item.
-     */
-    @VisibleForTesting
-    static boolean isPastLastItem(int top, int left, int right, InputEvent e, int direction) {
-        if (direction == View.LAYOUT_DIRECTION_LTR) {
-            return e.getX() > right && e.getY() > top;
-        } else {
-            return e.getX() < left && e.getY() > top;
-        }
-    }
-
-    /* Given the end position, select everything in-between.
-     * @param endPos  The adapter position of the end item.
-     */
-    private void doGestureMultiSelect(int endPos) {
-        mSelectionMgr.snapProvisionalRangeSelection(endPos);
-    }
-
-    private void scrollIfNecessary() {
-        mDragScroller.run();
-    }
-
-    @FunctionalInterface
-    interface ViewFinder {
-        @Nullable View findView(float x, float y);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/GridModel.java b/src/com/android/documentsui/selection/GridModel.java
new file mode 100644
index 0000000..dae445d
--- /dev/null
+++ b/src/com/android/documentsui/selection/GridModel.java
@@ -0,0 +1,727 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+
+import com.android.documentsui.selection.BandSelectionHelper.BandHost;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Provides a band selection item model for views within a RecyclerView. This class queries the
+ * RecyclerView to determine where its items are placed; then, once band selection is underway,
+ * it alerts listeners of which items are covered by the selections.
+ */
+final class GridModel {
+
+    // Magical value indicating that a value has not been previously set. primitive null :)
+    static final int NOT_SET = -1;
+
+    // Enum values used to determine the corner at which the origin is located within the
+    private static final int UPPER = 0x00;
+    private static final int LOWER = 0x01;
+    private static final int LEFT = 0x00;
+    private static final int RIGHT = 0x02;
+    private static final int UPPER_LEFT = UPPER | LEFT;
+    private static final int UPPER_RIGHT = UPPER | RIGHT;
+    private static final int LOWER_LEFT = LOWER | LEFT;
+    private static final int LOWER_RIGHT = LOWER | RIGHT;
+
+    private final BandHost mHost;
+    private final StableIdProvider mStableIds;
+    private final SelectionPredicate mSelectionPredicate;
+
+    private final List<SelectionObserver> mOnSelectionChangedListeners =
+            new ArrayList<>();
+
+    // Map from the x-value of the left side of a SparseBooleanArray of adapter positions, keyed
+    // by their y-offset. For example, if the first column of the view starts at an x-value of 5,
+    // mColumns.get(5) would return an array of positions in that column. Within that array, the
+    // value for key y is the adapter position for the item whose y-offset is y.
+    private final SparseArray<SparseIntArray> mColumns = new SparseArray<>();
+
+    // List of limits along the x-axis (columns).
+    // This list is sorted from furthest left to furthest right.
+    private final List<Limits> mColumnBounds = new ArrayList<>();
+
+    // List of limits along the y-axis (rows). Note that this list only contains items which
+    // have been in the viewport.
+    private final List<Limits> mRowBounds = new ArrayList<>();
+
+    // The adapter positions which have been recorded so far.
+    private final SparseBooleanArray mKnownPositions = new SparseBooleanArray();
+
+    // Array passed to registered OnSelectionChangedListeners. One array is created and reused
+    // throughout the lifetime of the object.
+    private final Set<String> mSelection = new HashSet<>();
+
+    // The current pointer (in absolute positioning from the top of the view).
+    private Point mPointer = null;
+
+    // The bounds of the band selection.
+    private RelativePoint mRelativeOrigin;
+    private RelativePoint mRelativePointer;
+
+    private boolean mIsActive;
+
+    // Tracks where the band select originated from. This is used to determine where selections
+    // should expand from when Shift+click is used.
+    private int mPositionNearestOrigin = NOT_SET;
+
+    private final OnScrollListener mScrollListener;
+
+    GridModel(
+            BandHost host,
+            StableIdProvider stableIds,
+            SelectionPredicate selectionPredicate) {
+
+        mHost = host;
+        mStableIds = stableIds;
+        mSelectionPredicate = selectionPredicate;
+
+        mScrollListener = new OnScrollListener() {
+            @Override
+            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+                GridModel.this.onScrolled(recyclerView, dx, dy);
+            }
+        };
+
+        mHost.addOnScrollListener(mScrollListener);
+    }
+
+    /**
+     * Stops listening to the view's scrolls. Call this function before discarding a
+     * GridModel object to prevent memory leaks.
+     */
+    void stopListening() {
+        mHost.removeOnScrollListener(mScrollListener);
+    }
+
+    /**
+     * Start a band select operation at the given point.
+     * @param relativeOrigin The origin of the band select operation, relative to the viewport.
+     *     For example, if the view is scrolled to the bottom, the top-left of the viewport
+     *     would have a relative origin of (0, 0), even though its absolute point has a higher
+     *     y-value.
+     */
+    void startCapturing(Point relativeOrigin) {
+        recordVisibleChildren();
+        if (isEmpty()) {
+            // The selection band logic works only if there is at least one visible child.
+            return;
+        }
+
+        mIsActive = true;
+        mPointer = mHost.createAbsolutePoint(relativeOrigin);
+        mRelativeOrigin = new RelativePoint(mPointer);
+        mRelativePointer = new RelativePoint(mPointer);
+        computeCurrentSelection();
+        notifySelectionChanged();
+    }
+
+    /**
+     * Ends the band selection.
+     */
+    void stopCapturing() {
+        mIsActive = false;
+    }
+
+    /**
+     * Resizes the selection by adjusting the pointer (i.e., the corner of the selection
+     * opposite the origin.
+     * @param relativePointer The pointer (opposite of the origin) of the band select operation,
+     *     relative to the viewport. For example, if the view is scrolled to the bottom, the
+     *     top-left of the viewport would have a relative origin of (0, 0), even though its
+     *     absolute point has a higher y-value.
+     */
+    @VisibleForTesting
+    void resizeSelection(Point relativePointer) {
+        mPointer = mHost.createAbsolutePoint(relativePointer);
+        updateModel();
+    }
+
+    /**
+     * @return The adapter position for the item nearest the origin corresponding to the latest
+     *         band select operation, or NOT_SET if the selection did not cover any items.
+     */
+    int getPositionNearestOrigin() {
+        return mPositionNearestOrigin;
+    }
+
+    private void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+        if (!mIsActive) {
+            return;
+        }
+
+        mPointer.x += dx;
+        mPointer.y += dy;
+        recordVisibleChildren();
+        updateModel();
+    }
+
+    /**
+     * Queries the view for all children and records their location metadata.
+     */
+    private void recordVisibleChildren() {
+        for (int i = 0; i < mHost.getVisibleChildCount(); i++) {
+            int adapterPosition = mHost.getAdapterPositionAt(i);
+            // Sometimes the view is not attached, as we notify the multi selection manager
+            // synchronously, while views are attached asynchronously. As a result items which
+            // are in the adapter may not actually have a corresponding view (yet).
+            if (mHost.hasView(adapterPosition) &&
+                    mSelectionPredicate.canSetStateAtPosition(adapterPosition, true) &&
+                    !mKnownPositions.get(adapterPosition)) {
+                mKnownPositions.put(adapterPosition, true);
+                recordItemData(mHost.getAbsoluteRectForChildViewAt(i), adapterPosition);
+            }
+        }
+    }
+
+    /**
+     * Checks if there are any recorded children.
+     */
+    private boolean isEmpty() {
+        return mColumnBounds.size() == 0 || mRowBounds.size() == 0;
+    }
+
+    /**
+     * Updates the limits lists and column map with the given item metadata.
+     * @param absoluteChildRect The absolute rectangle for the child view being processed.
+     * @param adapterPosition The position of the child view being processed.
+     */
+    private void recordItemData(Rect absoluteChildRect, int adapterPosition) {
+        if (mColumnBounds.size() != mHost.getColumnCount()) {
+            // If not all x-limits have been recorded, record this one.
+            recordLimits(
+                    mColumnBounds, new Limits(absoluteChildRect.left, absoluteChildRect.right));
+        }
+
+        recordLimits(mRowBounds, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
+
+        SparseIntArray columnList = mColumns.get(absoluteChildRect.left);
+        if (columnList == null) {
+            columnList = new SparseIntArray();
+            mColumns.put(absoluteChildRect.left, columnList);
+        }
+        columnList.put(absoluteChildRect.top, adapterPosition);
+    }
+
+    /**
+     * Ensures limits exists within the sorted list limitsList, and adds it to the list if it
+     * does not exist.
+     */
+    private void recordLimits(List<Limits> limitsList, Limits limits) {
+        int index = Collections.binarySearch(limitsList, limits);
+        if (index < 0) {
+            limitsList.add(~index, limits);
+        }
+    }
+
+    /**
+     * Handles a moved pointer; this function determines whether the pointer movement resulted
+     * in a selection change and, if it has, notifies listeners of this change.
+     */
+    private void updateModel() {
+        RelativePoint old = mRelativePointer;
+        mRelativePointer = new RelativePoint(mPointer);
+        if (old != null && mRelativePointer.equals(old)) {
+            return;
+        }
+
+        computeCurrentSelection();
+        notifySelectionChanged();
+    }
+
+    /**
+     * Computes the currently-selected items.
+     */
+    private void computeCurrentSelection() {
+        if (areItemsCoveredByBand(mRelativePointer, mRelativeOrigin)) {
+            updateSelection(computeBounds());
+        } else {
+            mSelection.clear();
+            mPositionNearestOrigin = NOT_SET;
+        }
+    }
+
+    /**
+     * Notifies all listeners of a selection change. Note that this function simply passes
+     * mSelection, so computeCurrentSelection() should be called before this
+     * function.
+     */
+    private void notifySelectionChanged() {
+        for (SelectionObserver listener : mOnSelectionChangedListeners) {
+            listener.onSelectionChanged(mSelection);
+        }
+    }
+
+    /**
+     * @param rect Rectangle including all covered items.
+     */
+    private void updateSelection(Rect rect) {
+        int columnStart =
+                Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
+
+        checkArgument(columnStart >= 0, "Rect doesn't intesect any known column.");
+
+        int columnEnd = columnStart;
+
+        for (int i = columnStart; i < mColumnBounds.size()
+                && mColumnBounds.get(i).lowerLimit <= rect.right; i++) {
+            columnEnd = i;
+        }
+
+        int rowStart = Collections.binarySearch(mRowBounds, new Limits(rect.top, rect.top));
+        if (rowStart < 0) {
+            mPositionNearestOrigin = NOT_SET;
+            return;
+        }
+
+        int rowEnd = rowStart;
+        for (int i = rowStart; i < mRowBounds.size()
+                && mRowBounds.get(i).lowerLimit <= rect.bottom; i++) {
+            rowEnd = i;
+        }
+
+        updateSelection(columnStart, columnEnd, rowStart, rowEnd);
+    }
+
+    /**
+     * Computes the selection given the previously-computed start- and end-indices for each
+     * row and column.
+     */
+    private void updateSelection(
+            int columnStartIndex, int columnEndIndex, int rowStartIndex, int rowEndIndex) {
+
+        if (BandSelectionHelper.DEBUG) {
+            Log.d(BandSelectionHelper.TAG, String.format(
+                    "updateSelection: %d, %d, %d, %d",
+                    columnStartIndex, columnEndIndex, rowStartIndex, rowEndIndex));
+        }
+
+        mSelection.clear();
+        for (int column = columnStartIndex; column <= columnEndIndex; column++) {
+            SparseIntArray items = mColumns.get(mColumnBounds.get(column).lowerLimit);
+            for (int row = rowStartIndex; row <= rowEndIndex; row++) {
+                // The default return value for SparseIntArray.get is 0, which is a valid
+                // position. Use a sentry value to prevent erroneously selecting item 0.
+                final int rowKey = mRowBounds.get(row).lowerLimit;
+                int position = items.get(rowKey, NOT_SET);
+                if (position != NOT_SET) {
+                    String id = mStableIds.getStableId(position);
+                    if (id != null) {
+                        // The adapter inserts items for UI layout purposes that aren't
+                        // associated with files. Those will have a null model ID.
+                        // Don't select them.
+                        if (canSelect(id)) {
+                            mSelection.add(id);
+                        }
+                    }
+                    if (isPossiblePositionNearestOrigin(column, columnStartIndex, columnEndIndex,
+                            row, rowStartIndex, rowEndIndex)) {
+                        // If this is the position nearest the origin, record it now so that it
+                        // can be returned by endSelection() later.
+                        mPositionNearestOrigin = position;
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean canSelect(String id) {
+        return mSelectionPredicate.canSetStateForId(id, true);
+    }
+
+    /**
+     * @return Returns true if the position is the nearest to the origin, or, in the case of the
+     *     lower-right corner, whether it is possible that the position is the nearest to the
+     *     origin. See comment below for reasoning for this special case.
+     */
+    private boolean isPossiblePositionNearestOrigin(int columnIndex, int columnStartIndex,
+            int columnEndIndex, int rowIndex, int rowStartIndex, int rowEndIndex) {
+        int corner = computeCornerNearestOrigin();
+        switch (corner) {
+            case UPPER_LEFT:
+                return columnIndex == columnStartIndex && rowIndex == rowStartIndex;
+            case UPPER_RIGHT:
+                return columnIndex == columnEndIndex && rowIndex == rowStartIndex;
+            case LOWER_LEFT:
+                return columnIndex == columnStartIndex && rowIndex == rowEndIndex;
+            case LOWER_RIGHT:
+                // Note that in some cases, the last row will not have as many items as there
+                // are columns (e.g., if there are 4 items and 3 columns, the second row will
+                // only have one item in the first column). This function is invoked for each
+                // position from left to right, so return true for any position in the bottom
+                // row and only the right-most position in the bottom row will be recorded.
+                return rowIndex == rowEndIndex;
+            default:
+                throw new RuntimeException("Invalid corner type.");
+        }
+    }
+
+    /**
+     * Listener for changes in which items have been band selected.
+     */
+    public static abstract class SelectionObserver {
+        abstract void onSelectionChanged(Set<String> updatedSelection);
+    }
+
+    void addOnSelectionChangedListener(SelectionObserver listener) {
+        mOnSelectionChangedListeners.add(listener);
+    }
+
+    /**
+     * Called when {@link BandSelectionHelper} is finished with a GridModel.
+     */
+    void onDestroy() {
+        mOnSelectionChangedListeners.clear();
+        stopListening();
+    }
+
+    /**
+     * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
+     * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
+     * of item columns and the top- and bottom sides of item rows so that it can be determined
+     * whether the pointer is located within the bounds of an item.
+     */
+    private static class Limits implements Comparable<Limits> {
+        int lowerLimit;
+        int upperLimit;
+
+        Limits(int lowerLimit, int upperLimit) {
+            this.lowerLimit = lowerLimit;
+            this.upperLimit = upperLimit;
+        }
+
+        @Override
+        public int compareTo(Limits other) {
+            return lowerLimit - other.lowerLimit;
+        }
+
+        @Override
+        public int hashCode() {
+            return lowerLimit ^ upperLimit;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof Limits)) {
+                return false;
+            }
+
+            return ((Limits) other).lowerLimit == lowerLimit &&
+                    ((Limits) other).upperLimit == upperLimit;
+        }
+
+        @Override
+        public String toString() {
+            return "(" + lowerLimit + ", " + upperLimit + ")";
+        }
+    }
+
+    /**
+     * The location of a coordinate relative to items. This class represents a general area of the
+     * view as it relates to band selection rather than an explicit point. For example, two
+     * different points within an item are considered to have the same "location" because band
+     * selection originating within the item would select the same items no matter which point
+     * was used. Same goes for points between items as well as those at the very beginning or end
+     * of the view.
+     *
+     * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
+     * advantage of tying the value to the Limits of items along that axis. This allows easy
+     * selection of items within those Limits as opposed to a search through every item to see if a
+     * given coordinate value falls within those Limits.
+     */
+    private static class RelativeCoordinate
+            implements Comparable<RelativeCoordinate> {
+        /**
+         * Location describing points after the last known item.
+         */
+        static final int AFTER_LAST_ITEM = 0;
+
+        /**
+         * Location describing points before the first known item.
+         */
+        static final int BEFORE_FIRST_ITEM = 1;
+
+        /**
+         * Location describing points between two items.
+         */
+        static final int BETWEEN_TWO_ITEMS = 2;
+
+        /**
+         * Location describing points within the limits of one item.
+         */
+        static final int WITHIN_LIMITS = 3;
+
+        /**
+         * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
+         * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
+         */
+        final int type;
+
+        /**
+         * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
+         * BETWEEN_TWO_ITEMS.
+         */
+        Limits limitsBeforeCoordinate;
+
+        /**
+         * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
+         */
+        Limits limitsAfterCoordinate;
+
+        // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
+        Limits mFirstKnownItem;
+        // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
+        Limits mLastKnownItem;
+
+        /**
+         * @param limitsList The sorted limits list for the coordinate type. If this
+         *     CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
+         *     mYLimitsList should be pased.
+         * @param value The coordinate value.
+         */
+        RelativeCoordinate(List<Limits> limitsList, int value) {
+            int index = Collections.binarySearch(limitsList, new Limits(value, value));
+
+            if (index >= 0) {
+                this.type = WITHIN_LIMITS;
+                this.limitsBeforeCoordinate = limitsList.get(index);
+            } else if (~index == 0) {
+                this.type = BEFORE_FIRST_ITEM;
+                this.mFirstKnownItem = limitsList.get(0);
+            } else if (~index == limitsList.size()) {
+                Limits lastLimits = limitsList.get(limitsList.size() - 1);
+                if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
+                    this.type = WITHIN_LIMITS;
+                    this.limitsBeforeCoordinate = lastLimits;
+                } else {
+                    this.type = AFTER_LAST_ITEM;
+                    this.mLastKnownItem = lastLimits;
+                }
+            } else {
+                Limits limitsBeforeIndex = limitsList.get(~index - 1);
+                if (limitsBeforeIndex.lowerLimit <= value
+                        && value <= limitsBeforeIndex.upperLimit) {
+                    this.type = WITHIN_LIMITS;
+                    this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+                } else {
+                    this.type = BETWEEN_TWO_ITEMS;
+                    this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+                    this.limitsAfterCoordinate = limitsList.get(~index);
+                }
+            }
+        }
+
+        int toComparisonValue() {
+            if (type == BEFORE_FIRST_ITEM) {
+                return mFirstKnownItem.lowerLimit - 1;
+            } else if (type == AFTER_LAST_ITEM) {
+                return mLastKnownItem.upperLimit + 1;
+            } else if (type == BETWEEN_TWO_ITEMS) {
+                return limitsBeforeCoordinate.upperLimit + 1;
+            } else {
+                return limitsBeforeCoordinate.lowerLimit;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return mFirstKnownItem.lowerLimit
+                    ^ mLastKnownItem.upperLimit
+                    ^ limitsBeforeCoordinate.upperLimit
+                    ^ limitsBeforeCoordinate.lowerLimit;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof RelativeCoordinate)) {
+                return false;
+            }
+
+            RelativeCoordinate otherCoordinate = (RelativeCoordinate) other;
+            return toComparisonValue() == otherCoordinate.toComparisonValue();
+        }
+
+        @Override
+        public int compareTo(RelativeCoordinate other) {
+            return toComparisonValue() - other.toComparisonValue();
+        }
+    }
+
+    /**
+     * The location of a point relative to the Limits of nearby items; consists of both an x- and
+     * y-RelativeCoordinateLocation.
+     */
+    private class RelativePoint {
+        final RelativeCoordinate xLocation;
+        final RelativeCoordinate yLocation;
+
+        RelativePoint(Point point) {
+            this.xLocation = new RelativeCoordinate(mColumnBounds, point.x);
+            this.yLocation = new RelativeCoordinate(mRowBounds, point.y);
+        }
+
+        @Override
+        public int hashCode() {
+            return xLocation.toComparisonValue()
+                    ^ yLocation.toComparisonValue();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof RelativePoint)) {
+                return false;
+            }
+
+            RelativePoint otherPoint = (RelativePoint) other;
+            return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
+        }
+    }
+
+    /**
+     * Generates a rectangle which contains the items selected by the pointer and origin.
+     * @return The rectangle, or null if no items were selected.
+     */
+    private Rect computeBounds() {
+        Rect rect = new Rect();
+        rect.left = getCoordinateValue(
+                min(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
+                mColumnBounds,
+                true);
+        rect.right = getCoordinateValue(
+                max(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
+                mColumnBounds,
+                false);
+        rect.top = getCoordinateValue(
+                min(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
+                mRowBounds,
+                true);
+        rect.bottom = getCoordinateValue(
+                max(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
+                mRowBounds,
+                false);
+        return rect;
+    }
+
+    /**
+     * Computes the corner of the selection nearest the origin.
+     * @return
+     */
+    private int computeCornerNearestOrigin() {
+        int cornerValue = 0;
+
+        if (mRelativeOrigin.yLocation ==
+                min(mRelativeOrigin.yLocation, mRelativePointer.yLocation)) {
+            cornerValue |= UPPER;
+        } else {
+            cornerValue |= LOWER;
+        }
+
+        if (mRelativeOrigin.xLocation ==
+                min(mRelativeOrigin.xLocation, mRelativePointer.xLocation)) {
+            cornerValue |= LEFT;
+        } else {
+            cornerValue |= RIGHT;
+        }
+
+        return cornerValue;
+    }
+
+    private RelativeCoordinate min(RelativeCoordinate first, RelativeCoordinate second) {
+        return first.compareTo(second) < 0 ? first : second;
+    }
+
+    private RelativeCoordinate max(RelativeCoordinate first, RelativeCoordinate second) {
+        return first.compareTo(second) > 0 ? first : second;
+    }
+
+    /**
+     * @return The absolute coordinate (i.e., the x- or y-value) of the given relative
+     *     coordinate.
+     */
+    private int getCoordinateValue(
+            RelativeCoordinate coordinate, List<Limits> limitsList, boolean isStartOfRange) {
+
+        switch (coordinate.type) {
+            case RelativeCoordinate.BEFORE_FIRST_ITEM:
+                return limitsList.get(0).lowerLimit;
+            case RelativeCoordinate.AFTER_LAST_ITEM:
+                return limitsList.get(limitsList.size() - 1).upperLimit;
+            case RelativeCoordinate.BETWEEN_TWO_ITEMS:
+                if (isStartOfRange) {
+                    return coordinate.limitsAfterCoordinate.lowerLimit;
+                } else {
+                    return coordinate.limitsBeforeCoordinate.upperLimit;
+                }
+            case RelativeCoordinate.WITHIN_LIMITS:
+                return coordinate.limitsBeforeCoordinate.lowerLimit;
+        }
+
+        throw new RuntimeException("Invalid coordinate value.");
+    }
+
+    private boolean areItemsCoveredByBand(
+            RelativePoint first, RelativePoint second) {
+
+        return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
+                doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
+    }
+
+    private boolean doesCoordinateLocationCoverItems(
+            RelativeCoordinate pointerCoordinate, RelativeCoordinate originCoordinate) {
+
+        if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
+                originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
+            return false;
+        }
+
+        if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
+                originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
+            return false;
+        }
+
+        if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+                originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+                pointerCoordinate.limitsBeforeCoordinate.equals(
+                        originCoordinate.limitsBeforeCoordinate) &&
+                pointerCoordinate.limitsAfterCoordinate.equals(
+                        originCoordinate.limitsAfterCoordinate)) {
+            return false;
+        }
+
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/ItemDetailsLookup.java b/src/com/android/documentsui/selection/ItemDetailsLookup.java
new file mode 100644
index 0000000..b56a2bc
--- /dev/null
+++ b/src/com/android/documentsui/selection/ItemDetailsLookup.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import javax.annotation.Nullable;
+
+/**
+ * Provides event handlers w/ access to details about documents details
+ * view items Documents in the UI (RecyclerView).
+ */
+public abstract class ItemDetailsLookup {
+
+    /** @return true if there is an item under the finger/cursor. */
+    public abstract boolean overItem(MotionEvent e);
+
+    /** @return true if there is an item w/ a stable ID under the finger/cursor. */
+    public abstract boolean overStableItem(MotionEvent e);
+
+    /**
+     * @return true if the event is over an area that can be dragged via touch
+     * or via mouse. List items have a white area that is not draggable.
+     */
+    public abstract boolean inItemDragRegion(MotionEvent e);
+
+    /**
+     * @return true if the event is in the "selection hot spot" region.
+     * The hot spot region instantly selects in touch mode, vs launches.
+     */
+    public abstract boolean inItemSelectRegion(MotionEvent e);
+
+    /**
+     * @return the adapter position of the item under the finger/cursor.
+     */
+    public abstract int getItemPosition(MotionEvent e);
+
+    /**
+     * @return the DocumentDetails for the item under the event, or null.
+     */
+    public abstract @Nullable ItemDetails getItemDetails(MotionEvent e);
+
+    /**
+     * Abstract class providing helper classes with access to information about
+     * RecyclerView item associated with a MotionEvent.
+     */
+    public static abstract class ItemDetails {
+
+        public boolean hasPosition() {
+            return getPosition() > RecyclerView.NO_POSITION;
+        }
+
+        public abstract int getPosition();
+
+        public boolean hasStableId() {
+            return getStableId() != null;
+        }
+
+        public abstract @Nullable String getStableId();
+
+        /**
+         * @return The view type of this ViewHolder.
+         */
+        public abstract int getItemViewType();
+
+        /**
+         * @return true if the event is in an area of the item that should be
+         * directly interpreted as a user wishing to select the item. This
+         * is useful for checkboxes and other UI affordances focused on enabling
+         * selection.
+         */
+        public boolean inSelectionHotspot(MotionEvent e) {
+            return false;
+        }
+
+        /**
+         * Events in the drag region will not be processed as selection events. This
+         * allows the client to implement custom handling for events related to drag
+         * and drop.
+         */
+        public boolean inDragRegion(MotionEvent e) {
+            return false;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ItemDetails) {
+                return equals((ItemDetails) obj);
+            }
+            return false;
+        }
+
+        private boolean equals(ItemDetails other) {
+            return this.getPosition() == other.getPosition()
+                    && this.getStableId() == other.getStableId();
+        }
+
+        @Override
+        public int hashCode() {
+            return getPosition() >>> 8;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/selection/MotionEvents.java b/src/com/android/documentsui/selection/MotionEvents.java
new file mode 100644
index 0000000..1915c5a
--- /dev/null
+++ b/src/com/android/documentsui/selection/MotionEvents.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import android.graphics.Point;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+/**
+ * Utility methods for working with {@link MotionEvent} instances.
+ */
+final class MotionEvents {
+
+    private MotionEvents() {}
+
+    static boolean isMouseEvent(MotionEvent e) {
+        return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
+    }
+
+    static boolean isTouchEvent(MotionEvent e) {
+        return e.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER;
+    }
+
+    static boolean isActionMove(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_MOVE;
+    }
+
+    static boolean isActionDown(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+    }
+
+    static boolean isActionUp(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_UP;
+    }
+
+    static boolean isActionPointerUp(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_POINTER_UP;
+    }
+
+    static boolean isActionPointerDown(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN;
+    }
+
+    static boolean isActionCancel(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_CANCEL;
+    }
+
+    static Point getOrigin(MotionEvent e) {
+        return new Point((int) e.getX(), (int) e.getY());
+    }
+
+    static boolean isPrimaryButtonPressed(MotionEvent e) {
+        return e.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
+    }
+
+    public static boolean isSecondaryButtonPressed(MotionEvent e) {
+        return e.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
+    }
+
+    public static boolean isTertiaryButtonPressed(MotionEvent e) {
+        return e.isButtonPressed(MotionEvent.BUTTON_TERTIARY);
+    }
+
+    static boolean isShiftKeyPressed(MotionEvent e) {
+        return hasBit(e.getMetaState(), KeyEvent.META_SHIFT_ON);
+    }
+
+    static boolean isCtrlKeyPressed(MotionEvent e) {
+        return hasBit(e.getMetaState(), KeyEvent.META_CTRL_ON);
+    }
+
+    static boolean isAltKeyPressed(MotionEvent e) {
+        return hasBit(e.getMetaState(), KeyEvent.META_ALT_ON);
+    }
+
+    public static boolean isTouchpadScroll(MotionEvent e) {
+        // Touchpad inputs are treated as mouse inputs, and when scrolling, there are no buttons
+        // returned.
+        return isMouseEvent(e) && isActionMove(e) && e.getButtonState() == 0;
+    }
+
+    private static boolean hasBit(int metaState, int bit) {
+        return (metaState & bit) != 0;
+    }
+}
diff --git a/src/com/android/documentsui/selection/MotionInputHandler.java b/src/com/android/documentsui/selection/MotionInputHandler.java
new file mode 100644
index 0000000..474e17d
--- /dev/null
+++ b/src/com/android/documentsui/selection/MotionInputHandler.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.view.GestureDetector.SimpleOnGestureListener;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+
+/**
+ * Base class for handlers that can be registered w/ {@link GestureRouter}.
+ */
+public abstract class MotionInputHandler extends SimpleOnGestureListener {
+
+    protected final SelectionHelper mSelectionHelper;
+    protected final ItemDetailsLookup mDetailsLookup;
+
+    private final Callbacks mCallbacks;
+
+    public MotionInputHandler(
+            SelectionHelper selectionHelper,
+            ItemDetailsLookup detailsLookup,
+            Callbacks callbacks) {
+
+        checkArgument(selectionHelper != null);
+        checkArgument(detailsLookup != null);
+        checkArgument(callbacks != null);
+
+        mSelectionHelper = selectionHelper;
+        mDetailsLookup = detailsLookup;
+        mCallbacks = callbacks;
+    }
+
+    protected final boolean selectItem(ItemDetails details) {
+        checkArgument(details != null);
+        checkArgument(details.hasPosition());
+        checkArgument(details.hasStableId());
+
+        if (mSelectionHelper.select(details.getStableId())) {
+            mSelectionHelper.anchorRange(details.getPosition());
+        }
+
+        // we set the focus on this doc so it will be the origin for keyboard events or shift+clicks
+        // if there is only a single item selected, otherwise clear focus
+        if (mSelectionHelper.getSelection().size() == 1) {
+            mCallbacks.focusItem(details);
+        } else {
+            mCallbacks.clearFocus();
+        }
+        return true;
+    }
+
+    protected final boolean focusItem(ItemDetails details) {
+        checkArgument(details != null);
+        checkArgument(details.hasStableId());
+
+        mSelectionHelper.clearSelection();
+        mCallbacks.focusItem(details);
+        return true;
+    }
+
+    protected final void extendSelectionRange(ItemDetails details) {
+        checkArgument(details.hasPosition());
+        checkArgument(details.hasStableId());
+
+        mSelectionHelper.extendRange(details.getPosition());
+        mCallbacks.focusItem(details);
+    }
+
+    protected final boolean isRangeExtension(MotionEvent e) {
+        return MotionEvents.isShiftKeyPressed(e) && mSelectionHelper.isRangeActive();
+    }
+
+    protected boolean shouldClearSelection(MotionEvent e, ItemDetails item) {
+        return !MotionEvents.isCtrlKeyPressed(e)
+                && !item.inSelectionHotspot(e)
+                && !mSelectionHelper.isSelected(item.getStableId());
+    }
+
+    public static abstract class Callbacks {
+        public abstract void onPerformHapticFeedback();
+        public void focusItem(ItemDetails item) {}
+        public void clearFocus() {}
+    }
+}
diff --git a/src/com/android/documentsui/selection/MouseInputHandler.java b/src/com/android/documentsui/selection/MouseInputHandler.java
new file mode 100644
index 0000000..7ceb0f5
--- /dev/null
+++ b/src/com/android/documentsui/selection/MouseInputHandler.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static com.android.documentsui.selection.Shared.DEBUG;
+import static com.android.documentsui.selection.Shared.VERBOSE;
+
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.internal.widget.RecyclerView;
+
+import javax.annotation.Nullable;
+
+/**
+ * A MotionInputHandler that provides the high-level glue for mouse/stylus driven selection. This
+ * class works with {@link RecyclerView}, {@link GestureRouter}, and {@link GestureSelectionHelper}
+ * to provide robust user drive selection support.
+ */
+public final class MouseInputHandler extends MotionInputHandler {
+
+        private static final String TAG = "MouseInputDelegate";
+
+        private final Callbacks mCallbacks;
+
+        // The event has been handled in onSingleTapUp
+        private boolean mHandledTapUp;
+        // true when the previous event has consumed a right click motion event
+        private boolean mHandledOnDown;
+
+        public MouseInputHandler(
+                SelectionHelper selectionHelper,
+                ItemDetailsLookup detailsLookup,
+                Callbacks callbacks) {
+
+            super(selectionHelper, detailsLookup, callbacks);
+
+            mCallbacks = callbacks;
+        }
+
+        @Override
+        public boolean onDown(MotionEvent e) {
+            if (VERBOSE) Log.v(TAG, "Delegated onDown event.");
+            if ((MotionEvents.isAltKeyPressed(e) && MotionEvents.isPrimaryButtonPressed(e))
+                    || MotionEvents.isSecondaryButtonPressed(e)) {
+                mHandledOnDown = true;
+                return onRightClick(e);
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+            // Don't scroll content window in response to mouse drag
+            // If it's two-finger trackpad scrolling, we want to scroll
+            return !MotionEvents.isTouchpadScroll(e2);
+        }
+
+        @Override
+        public boolean onSingleTapUp(MotionEvent e) {
+            // See b/27377794. Since we don't get a button state back from UP events, we have to
+            // explicitly save this state to know whether something was previously handled by
+            // DOWN events or not.
+            if (mHandledOnDown) {
+                if (VERBOSE) Log.v(TAG, "Ignoring onSingleTapUp, previously handled in onDown.");
+                mHandledOnDown = false;
+                return false;
+            }
+
+            if (!mDetailsLookup.overStableItem(e)) {
+                if (DEBUG) Log.d(TAG, "Tap not associated w/ model item. Clearing selection.");
+                mSelectionHelper.clearSelection();
+                mCallbacks.clearFocus();
+                return false;
+            }
+
+            if (MotionEvents.isTertiaryButtonPressed(e)) {
+                if (DEBUG) Log.d(TAG, "Ignoring middle click");
+                return false;
+            }
+
+            ItemDetails item = mDetailsLookup.getItemDetails(e);
+            if (mSelectionHelper.hasSelection()) {
+                if (isRangeExtension(e)) {
+                    extendSelectionRange(item);
+                } else {
+                    if (shouldClearSelection(e, item)) {
+                        mSelectionHelper.clearSelection();
+                    }
+                    if (mSelectionHelper.isSelected(item.getStableId())) {
+                        if (mSelectionHelper.deselect(item.getStableId())) {
+                            mCallbacks.clearFocus();
+                        }
+                    } else {
+                        selectOrFocusItem(item, e);
+                    }
+                }
+                mHandledTapUp = true;
+                return true;
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            if (mHandledTapUp) {
+                if (VERBOSE) Log.v(TAG,
+                        "Ignoring onSingleTapConfirmed, previously handled in onSingleTapUp.");
+                mHandledTapUp = false;
+                return false;
+            }
+
+            if (mSelectionHelper.hasSelection()) {
+                return false;  // should have been handled by onSingleTapUp.
+            }
+
+            if (!mDetailsLookup.overItem(e)) {
+                if (DEBUG) Log.d(TAG, "Ignoring Confirmed Tap on non-item.");
+                return false;
+            }
+
+            if (MotionEvents.isTertiaryButtonPressed(e)) {
+                if (DEBUG) Log.d(TAG, "Ignoring middle click");
+                return false;
+            }
+
+            @Nullable ItemDetails item = mDetailsLookup.getItemDetails(e);
+            if (item == null || !item.hasStableId()) {
+                Log.w(TAG, "Ignoring Confirmed Tap. No document details associated w/ event.");
+                return false;
+            }
+
+            if (mCallbacks.hasFocusedItem() && MotionEvents.isShiftKeyPressed(e)) {
+                mSelectionHelper.startRange(mCallbacks.getFocusedPosition());
+                mSelectionHelper.extendRange(item.getPosition());
+            } else {
+                selectOrFocusItem(item, e);
+            }
+            return true;
+        }
+
+        @Override
+        public boolean onDoubleTap(MotionEvent e) {
+            mHandledTapUp = false;
+
+            if (!mDetailsLookup.overStableItem(e)) {
+                if (DEBUG) Log.d(TAG, "Ignoring DoubleTap on non-model-backed item.");
+                return false;
+            }
+
+            if (MotionEvents.isTertiaryButtonPressed(e)) {
+                if (DEBUG) Log.d(TAG, "Ignoring middle click");
+                return false;
+            }
+
+            @Nullable ItemDetails item = mDetailsLookup.getItemDetails(e);
+            if (item != null) {
+                return mCallbacks.onItemActivated(item, e);
+            }
+
+            return false;
+        }
+
+        private boolean onRightClick(MotionEvent e) {
+            if (mDetailsLookup.overStableItem(e)) {
+                @Nullable ItemDetails item = mDetailsLookup.getItemDetails(e);
+                if (item != null && !mSelectionHelper.isSelected(item.getStableId())) {
+                    mSelectionHelper.clearSelection();
+                    selectItem(item);
+                }
+            }
+
+            // We always delegate final handling of the event,
+            // since the handler might want to show a context menu
+            // in an empty area or some other weirdo view.
+            return mCallbacks.onContextClick(e);
+        }
+
+        private void selectOrFocusItem(ItemDetails item, MotionEvent e) {
+            if (item.inSelectionHotspot(e) || MotionEvents.isCtrlKeyPressed(e)) {
+                selectItem(item);
+            } else {
+                focusItem(item);
+            }
+        }
+
+        public static abstract class Callbacks extends MotionInputHandler.Callbacks {
+            public abstract boolean onItemActivated(ItemDetails item, MotionEvent e);
+            public boolean onContextClick(MotionEvent e) {
+                return false;
+            }
+            public boolean hasFocusedItem() {
+                return false;
+            }
+            public int getFocusedPosition() {
+                return RecyclerView.NO_POSITION;
+            }
+        }
+    }
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/MutableSelection.java b/src/com/android/documentsui/selection/MutableSelection.java
new file mode 100644
index 0000000..7939e14
--- /dev/null
+++ b/src/com/android/documentsui/selection/MutableSelection.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+/**
+ * Subclass of Selection exposing public support for mutating the underlying selection data.
+ * This is useful for clients of {@link SelectionHelper} that wish to manipulate
+ * a copy of selection data obtained via {@link SelectionHelper#copySelection(Selection)}.
+ */
+public final class MutableSelection extends Selection {
+
+    @Override
+    public boolean add(String id) {
+        return super.add(id);
+    }
+
+    @Override
+    public boolean remove(String id) {
+        return super.remove(id);
+    }
+
+    @Override
+    public void clear() {
+        super.clear();
+    }
+}
diff --git a/src/com/android/documentsui/selection/Range.java b/src/com/android/documentsui/selection/Range.java
index c7db84c..efe49e9 100644
--- a/src/com/android/documentsui/selection/Range.java
+++ b/src/com/android/documentsui/selection/Range.java
@@ -15,36 +15,36 @@
  */
 package com.android.documentsui.selection;
 
-import static com.android.documentsui.base.Shared.DEBUG;
-import static com.android.documentsui.base.Shared.VERBOSE;
+import static android.support.v4.util.Preconditions.checkArgument;
+import static android.support.v7.widget.RecyclerView.NO_POSITION;
+import static com.android.documentsui.selection.Shared.DEBUG;
+import static com.android.documentsui.selection.Shared.TAG;
 
-import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 
-import com.android.documentsui.selection.SelectionManager.RangeType;
+import com.android.documentsui.selection.DefaultSelectionHelper.RangeType;
 
 /**
  * Class providing support for managing range selections.
  */
 final class Range {
-    private static final int UNDEFINED = -1;
 
-    private final Range.RangeUpdater mUpdater;
+    private final Callbacks mCallbacks;
     private final int mBegin;
-    private int mEnd = UNDEFINED;
+    private int mEnd = NO_POSITION;
 
-    public Range(Range.RangeUpdater updater, int begin) {
-        if (DEBUG) Log.d(SelectionManager.TAG, "New Ranger created beginning @ " + begin);
-        mUpdater = updater;
+    public Range(Callbacks callbacks, int begin) {
+        if (DEBUG) Log.d(TAG, "New Ranger created beginning @ " + begin);
+        mCallbacks = callbacks;
         mBegin = begin;
     }
 
-    void snapSelection(int position, @RangeType int type) {
-        assert(position != RecyclerView.NO_POSITION);
+    void extendSelection(int position, @RangeType int type) {
+        checkArgument(position != NO_POSITION, "Position cannot be NO_POSITION.");
 
-        if (mEnd == UNDEFINED || mEnd == mBegin) {
+        if (mEnd == NO_POSITION || mEnd == mBegin) {
             // Reset mEnd so it can be established in establishRange.
-            mEnd = UNDEFINED;
+            mEnd = NO_POSITION;
             establishRange(position, type);
         } else {
             reviseRange(position, type);
@@ -52,7 +52,7 @@
     }
 
     private void establishRange(int position, @RangeType int type) {
-        assert(mEnd == UNDEFINED);
+        checkArgument(mEnd == NO_POSITION, "End has already been set.");
 
         if (position == mBegin) {
             mEnd = position;
@@ -68,11 +68,11 @@
     }
 
     private void reviseRange(int position, @RangeType int type) {
-        assert(mEnd != UNDEFINED);
-        assert(mBegin != mEnd);
+        checkArgument(mEnd != NO_POSITION, "End must already be set.");
+        checkArgument(mBegin != mEnd, "Beging and end point to same position.");
 
         if (position == mEnd) {
-            if (VERBOSE) Log.v(SelectionManager.TAG, "Ignoring no-op revision for range: " + this);
+            if (DEBUG) Log.v(TAG, "Ignoring no-op revision for range: " + this);
         }
 
         if (mEnd > mBegin) {
@@ -86,7 +86,7 @@
     }
 
     /**
-     * Updates an existing ascending seleciton.
+     * Updates an existing ascending selection.
      * @param position
      */
     private void reviseAscendingRange(int position, @RangeType int type) {
@@ -133,7 +133,7 @@
      * @param selected New selection state.
      */
     private void updateRange(int begin, int end, boolean selected, @RangeType int type) {
-        mUpdater.updateForRange(begin, end, selected, type);
+        mCallbacks.updateForRange(begin, end, selected, type);
     }
 
     @Override
@@ -142,11 +142,10 @@
     }
 
     /*
-     * @see {@link MultiSelectManager#updateForRegularRange(int, int , boolean)} and {@link
-     * MultiSelectManager#updateForProvisionalRange(int, int, boolean)}
+     * @see {@link DefaultSelectionHelper#updateForRange(int, int , boolean, int)}.
      */
-    @FunctionalInterface
-    interface RangeUpdater {
-        void updateForRange(int begin, int end, boolean selected, @RangeType int type);
+    static abstract class Callbacks {
+        abstract void updateForRange(
+                int begin, int end, boolean selected, @RangeType int type);
     }
 }
diff --git a/src/com/android/documentsui/selection/Selection.java b/src/com/android/documentsui/selection/Selection.java
index 8775c58..88b4cbb 100644
--- a/src/com/android/documentsui/selection/Selection.java
+++ b/src/com/android/documentsui/selection/Selection.java
@@ -15,6 +15,8 @@
  */
 package com.android.documentsui.selection;
 
+import static android.support.v4.util.Preconditions.checkArgument;
+
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.VisibleForTesting;
@@ -30,22 +32,29 @@
 import javax.annotation.Nullable;
 
 /**
- * Object representing the current selection. Provides read only access
- * public access, and private write access.
+ * Object representing the current selection and provisional selection. Provides read only public
+ * access, and private write access.
+ * <p>
+ * This class tracks selected items by managing two sets:
+ *
+ * <li>primary selection
+ *
+ * Primary selection consists of items tapped by a user or by lassoed by band select operation.
+ *
+ * <li>provisional selection
+ *
+ * Provisional selections are selections which have been temporarily created
+ * by an in-progress band select or gesture selection. Once the user releases the mouse button
+ * or lifts their finger the corresponding provisional selection should be converted into
+ * primary selection.
+ *
+ * <p>The total selection is the combination of
+ * both the core selection and the provisional selection. Tracking both separately is necessary to
+ * ensure that items in the core selection are not "erased" from the core selection when they
+ * are temporarily included in a secondary selection (like band selection).
  */
-public final class Selection implements Iterable<String>, Parcelable {
+public class Selection implements Iterable<String>, Parcelable {
 
-    // This class tracks selected items by managing two sets: the saved selection, and the total
-    // selection. Saved selections are those which have been completed by tapping an item or by
-    // completing a band select operation. Provisional selections are selections which have been
-    // temporarily created by an in-progress band select operation (once the user releases the
-    // mouse button during a band select operation, the selected items become saved). The total
-    // selection is the combination of both the saved selection and the provisional
-    // selection. Tracking both separately is necessary to ensure that saved selections do not
-    // become deselected when they are removed from the provisional selection; for example, if
-    // item A is tapped (and selected), then an in-progress band select covers A then uncovers
-    // A, A should still be selected as it has been saved. To ensure this behavior, the saved
-    // selection must be tracked separately.
     final Set<String> mSelection;
     final Set<String> mProvisionalSelection;
 
@@ -101,13 +110,12 @@
      * one (if it exists) is abandoned.
      * @return Map of ids added or removed. Added ids have a value of true, removed are false.
      */
-    @VisibleForTesting
-    protected Map<String, Boolean> setProvisionalSelection(Set<String> newSelection) {
+    Map<String, Boolean> setProvisionalSelection(Set<String> newSelection) {
         Map<String, Boolean> delta = new HashMap<>();
 
         for (String id: mProvisionalSelection) {
-            // Mark each item that used to be in the selection but is unsaved and not in the new
-            // provisional selection.
+            // Mark each item that used to be in the provisional selection
+            // but is not in the new provisional selection.
             if (!newSelection.contains(id) && !mSelection.contains(id)) {
                 delta.put(id, false);
             }
@@ -150,7 +158,7 @@
      * cause items in this existing provisional selection to become deselected.
      */
     @VisibleForTesting
-    protected void applyProvisionalSelection() {
+    protected void mergeProvisionalSelection() {
         mSelection.addAll(mProvisionalSelection);
         mProvisionalSelection.clear();
     }
@@ -160,42 +168,59 @@
      * now deselected.
      */
     @VisibleForTesting
-    void cancelProvisionalSelection() {
+    void clearProvisionalSelection() {
         mProvisionalSelection.clear();
     }
 
-    /** @hide */
-    @VisibleForTesting
-    public boolean add(String id) {
-        if (!mSelection.contains(id)) {
-            mSelection.add(id);
-            return true;
-        }
-        return false;
-    }
-
-    /** @hide */
-    @VisibleForTesting
-    boolean remove(String id) {
+    /**
+     * Adds a new item to the primary selection.
+     *
+     * @return true if the operation resulted in a modification to the selection.
+     */
+    boolean add(String id) {
         if (mSelection.contains(id)) {
-            mSelection.remove(id);
-            return true;
+            return false;
         }
-        return false;
+
+        mSelection.add(id);
+        return true;
     }
 
-    public void clear() {
+    /**
+     * Removes an item from the primary selection.
+     *
+     * @return true if the operation resulted in a modification to the selection.
+     */
+    boolean remove(String id) {
+        if (!mSelection.contains(id)) {
+            return false;
+        }
+
+        mSelection.remove(id);
+        return true;
+    }
+
+    /**
+     * Clears the primary selection. The provisional selection, if any, is unaffected.
+     */
+    void clear() {
         mSelection.clear();
     }
 
     /**
-     * Trims this selection to be the intersection of itself with the set of given IDs.
+     * Trims this selection to be the intersection of itself and {@code ids}.
      */
-    public void intersect(Collection<String> ids) {
+    void intersect(Collection<String> ids) {
+        checkArgument(ids != null);
+
         mSelection.retainAll(ids);
         mProvisionalSelection.retainAll(ids);
     }
 
+    /**
+     * Clones primary and provisional selection from supplied {@link Selection}.
+     * Does not copy active range data.
+     */
     @VisibleForTesting
     void copyFrom(Selection source) {
         mSelection.clear();
@@ -213,7 +238,7 @@
 
         StringBuilder buffer = new StringBuilder(size() * 28);
         buffer.append("Selection{")
-            .append("applied{size=" + mSelection.size())
+            .append("primary{size=" + mSelection.size())
             .append(", entries=" + mSelection)
             .append("}, provisional{size=" + mProvisionalSelection.size())
             .append(", entries=" + mProvisionalSelection)
@@ -227,17 +252,19 @@
     }
 
     @Override
-    public boolean equals(Object that) {
-      if (this == that) {
-          return true;
-      }
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
 
-      if (!(that instanceof Selection)) {
-          return false;
-      }
+        return other instanceof Selection
+            ? equals((Selection) other)
+            : false;
+    }
 
-      return mSelection.equals(((Selection) that).mSelection) &&
-              mProvisionalSelection.equals(((Selection) that).mProvisionalSelection);
+    private boolean equals(Selection other) {
+        return mSelection.equals(((Selection) other).mSelection) &&
+                mProvisionalSelection.equals(((Selection) other).mProvisionalSelection);
     }
 
     @Override
diff --git a/src/com/android/documentsui/selection/SelectionHelper.java b/src/com/android/documentsui/selection/SelectionHelper.java
new file mode 100644
index 0000000..bd8b34e
--- /dev/null
+++ b/src/com/android/documentsui/selection/SelectionHelper.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * SelectionManager provides support for managing selection within a RecyclerView instance.
+ *
+ * @see DefaultSelectionHelper for details on instantiation.
+ */
+public abstract class SelectionHelper {
+
+    /**
+     * This value is included in the payload when SelectionHelper implementations
+     * notify RecyclerView of changes. Clients can look for this in
+     * {@code onBindViewHolder} to know if the bind event is occurring in response
+     * to a selection state change.
+     */
+    public static final String SELECTION_CHANGED_MARKER = "Selection-Changed";
+
+    /**
+     * Adds {@code observe} to be notified when changes to selection occur.
+     *
+     * @param observer
+     */
+    public abstract void addObserver(SelectionObserver observer);
+
+    public abstract boolean hasSelection();
+
+    /**
+     * Returns a Selection object that provides a live view on the current selection.
+     *
+     * @see #copySelection(Selection) on how to get a snapshot
+     *     of the selection that will not reflect future changes
+     *     to selection.
+     *
+     * @return The current selection.
+     */
+    public abstract Selection getSelection();
+
+    /**
+     * Updates {@code dest} to reflect the current selection.
+     * @param dest
+     */
+    public abstract void copySelection(Selection dest);
+
+    /**
+     * @return true if the item specified by its id is selected. Shorthand for
+     * {@code getSelection().contains(String)}.
+     */
+    public abstract boolean isSelected(String id);
+
+    /**
+     * Restores the selected state of specified items. Used in cases such as restore the selection
+     * after rotation etc. Provisional selection, being provisional 'n all, isn't restored.
+     */
+    public abstract void restoreSelection(Selection other);
+
+    /**
+     * Sets the selected state of the specified items. Note that the callback will NOT
+     * be consulted to see if an item can be selected.
+     *
+     * @param ids
+     * @param selected
+     * @return
+     */
+    public abstract boolean setItemsSelected(Iterable<String> ids, boolean selected);
+
+    /**
+     * Clears the selection and notifies (if something changes).
+     */
+    public abstract void clearSelection();
+
+    /**
+     * Attempts to select an item.
+     *
+     * @return true if the item was selected. False if the item was not selected, or was
+     *         was already selected prior to the method being called.
+     */
+    public abstract boolean select(String itemId);
+
+    /**
+     * Attempts to deselect an item.
+     *
+     * @return true if the item was deselected. False if the item was not deselected, or was
+     *         was already deselected prior to the method being called.
+     */
+    public abstract boolean deselect(String itemId);
+
+    /**
+     * Starts a range selection. If a range selection is already active, this will start a new range
+     * selection (which will reset the range anchor).
+     *
+     * @param pos The anchor position for the selection range.
+     */
+    public abstract void startRange(int pos);
+
+    /**
+     * Sets the end point for the active range selection.
+     *
+     * <p>This function should only be called when a range selection is active
+     * (see {@link #isRangeActive()}. Items in the range [anchor, end] will be
+     * selected.
+     *
+     * @param pos The new end position for the selection range.
+     * @param type The type of selection the range should utilize.
+     *
+     * @throws IllegalStateException if a range selection is not active. Range selection
+     *         must have been started by a call to {@link #startRange(int)}.
+     */
+    public abstract void extendRange(int pos);
+
+    /**
+     * Stops an in-progress range selection. All selection done with
+     * {@link #extendProvisionalRange(int)} will be lost if
+     * {@link Selection#mergeProvisionalSelection()} is not called beforehand.
+     */
+    public abstract void endRange();
+
+    /**
+     * @return Whether or not there is a current range selection active.
+     */
+    public abstract boolean isRangeActive();
+
+    /**
+     * Sets the magic location at which a selection range begins (the selection anchor). This value
+     * is consulted when determining how to extend, and modify selection ranges. Calling this when a
+     * range selection is active will reset the range selection.
+     */
+    public abstract void anchorRange(int position);
+
+    /**
+     * @param pos
+     */
+    // TODO: This is smelly. Maybe this type of logic needs to move into range selection,
+    // then selection manager can have a startProvisionalRange and startRange. Or
+    // maybe ranges always start life as provisional.
+    public abstract void extendProvisionalRange(int pos);
+
+    /**
+     * @param newSelection
+     */
+    public abstract void setProvisionalSelection(Set<String> newSelection);
+
+    /**
+     *
+     */
+    public abstract void clearProvisionalSelection();
+
+    public abstract void mergeProvisionalSelection();
+
+    /**
+     * Observer interface providing access to information about Selection state changes.
+     */
+    public static abstract class SelectionObserver {
+
+        /**
+         * Called when state of an item has been changed.
+         */
+        public void onItemStateChanged(String id, boolean selected) {}
+
+        /**
+         * Called when the underlying data set has change. After this method is called
+         * the selection manager will attempt traverse the existing selection,
+         * calling {@link #onItemStateChanged(String, boolean)} for each selected item,
+         * and deselecting any items that cannot be selected given the updated dataset.
+         */
+        public void onSelectionReset() {}
+
+        /**
+         * Called immediately after completion of any set of changes, excluding
+         * those resulting in calls to {@link #onSelectionReset()} and
+         * {@link #onSelectionRestored()}.
+         */
+        public void onSelectionChanged() {}
+
+        /**
+         * Called immediately after selection is restored.
+         * {@link #onItemStateChanged(String, boolean)} will not be called
+         * for individual items in the selection.
+         */
+        public void onSelectionRestored() {}
+    }
+
+    /**
+     * Facilitates the use of stable ids.
+     */
+    public static abstract class StableIdProvider {
+        /**
+         * @return The model ID of the item at the given adapter position.
+         */
+        public abstract String getStableId(int position);
+
+        /**
+         * @return the position of a stable ID, or RecyclerView.NO_POSITION.
+         */
+        public abstract int getPosition(String id);
+
+        /**
+         * @return A list of all known stable IDs.
+         */
+        public abstract List<String> getStableIds();
+    }
+
+    /**
+     * Implement SelectionPredicate to control when items can be selected or unselected.
+     */
+    public static abstract class SelectionPredicate {
+
+        /** @return true if the item at {@code id} can be set to {@code nextState}. */
+        public abstract boolean canSetStateForId(String id, boolean nextState);
+
+        /** @return true if the item at {@code id} can be set to {@code nextState}. */
+        public abstract boolean canSetStateAtPosition(int position, boolean nextState);
+
+        /** @return true if more than a single item can be selected. */
+        public boolean canSelectMultiple() {
+            return true;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/selection/SelectionManager.java b/src/com/android/documentsui/selection/SelectionManager.java
deleted file mode 100644
index af77cfa..0000000
--- a/src/com/android/documentsui/selection/SelectionManager.java
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import static com.android.documentsui.base.Shared.DEBUG;
-
-import android.annotation.IntDef;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-
-import com.android.documentsui.dirlist.DocumentsAdapter;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-/**
- * MultiSelectManager provides support traditional multi-item selection support to RecyclerView.
- * Additionally it can be configured to restrict selection to a single element, @see
- * #setSelectMode.
- */
-public final class SelectionManager {
-
-    @IntDef(flag = true, value = {
-            MODE_MULTIPLE,
-            MODE_SINGLE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SelectionMode {}
-    public static final int MODE_MULTIPLE = 0;
-    public static final int MODE_SINGLE = 1;
-
-    @IntDef({
-            RANGE_REGULAR,
-            RANGE_PROVISIONAL
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RangeType {}
-    public static final int RANGE_REGULAR = 0;
-    public static final int RANGE_PROVISIONAL = 1;
-
-    static final String TAG = "SelectionManager";
-
-    private final Selection mSelection = new Selection();
-
-    private final List<Callback> mCallbacks = new ArrayList<>(1);
-    private final List<ItemCallback> mItemCallbacks = new ArrayList<>(1);
-
-    private @Nullable DocumentsAdapter mAdapter;
-    private @Nullable Range mRanger;
-    private boolean mSingleSelect;
-
-    private RecyclerView.AdapterDataObserver mAdapterObserver;
-    private SelectionPredicate mCanSetState;
-
-    public SelectionManager(@SelectionMode int mode) {
-        mSingleSelect = mode == MODE_SINGLE;
-    }
-
-    public SelectionManager reset(DocumentsAdapter adapter, SelectionPredicate canSetState) {
-
-        mCallbacks.clear();
-        mItemCallbacks.clear();
-        if (mAdapter != null && mAdapterObserver != null) {
-            mAdapter.unregisterAdapterDataObserver(mAdapterObserver);
-        }
-
-        clearSelectionQuietly();
-
-        assert(adapter != null);
-        assert(canSetState != null);
-
-        mAdapter = adapter;
-        mCanSetState = canSetState;
-
-        mAdapterObserver = new RecyclerView.AdapterDataObserver() {
-
-            private List<String> mModelIds;
-
-            @Override
-            public void onChanged() {
-                mModelIds = mAdapter.getModelIds();
-
-                // Update the selection to remove any disappeared IDs.
-                mSelection.cancelProvisionalSelection();
-                mSelection.intersect(mModelIds);
-
-                notifyDataChanged();
-            }
-
-            @Override
-            public void onItemRangeChanged(
-                    int startPosition, int itemCount, Object payload) {
-                // No change in position. Ignoring.
-            }
-
-            @Override
-            public void onItemRangeInserted(int startPosition, int itemCount) {
-                mSelection.cancelProvisionalSelection();
-            }
-
-            @Override
-            public void onItemRangeRemoved(int startPosition, int itemCount) {
-                assert(startPosition >= 0);
-                assert(itemCount > 0);
-
-                mSelection.cancelProvisionalSelection();
-                // Remove any disappeared IDs from the selection.
-                mSelection.intersect(mModelIds);
-            }
-
-            @Override
-            public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-                throw new UnsupportedOperationException();
-            }
-        };
-
-        mAdapter.registerAdapterDataObserver(mAdapterObserver);
-        return this;
-    }
-
-    void bindContoller(BandController controller) {
-        // Provides BandController with access to private mSelection state.
-        controller.bindSelection(mSelection);
-    }
-
-    /**
-     * Adds {@code callback} such that it will be notified when {@code MultiSelectManager}
-     * events occur.
-     *
-     * @param callback
-     */
-    public void addCallback(Callback callback) {
-        assert(callback != null);
-        mCallbacks.add(callback);
-    }
-
-    public void addItemCallback(ItemCallback itemCallback) {
-        assert(itemCallback != null);
-        mItemCallbacks.add(itemCallback);
-    }
-
-    public boolean hasSelection() {
-        return !mSelection.isEmpty();
-    }
-
-    /**
-     * Returns a Selection object that provides a live view
-     * on the current selection.
-     *
-     * @see #getSelection(Selection) on how to get a snapshot
-     *     of the selection that will not reflect future changes
-     *     to selection.
-     *
-     * @return The current selection.
-     */
-    public Selection getSelection() {
-        return mSelection;
-    }
-
-    /**
-     * Updates {@code dest} to reflect the current selection.
-     * @param dest
-     *
-     * @return The Selection instance passed in, for convenience.
-     */
-    public Selection getSelection(Selection dest) {
-        dest.copyFrom(mSelection);
-        return dest;
-    }
-
-    @VisibleForTesting
-    public void replaceSelection(Iterable<String> ids) {
-        clearSelection();
-        setItemsSelected(ids, true);
-    }
-
-    /**
-     * Restores the selected state of specified items. Used in cases such as restore the selection
-     * after rotation etc.
-     */
-    public void restoreSelection(Selection other) {
-        setItemsSelectedQuietly(other.mSelection, true);
-        // NOTE: We intentionally don't restore provisional selection. It's provisional.
-        notifySelectionRestored();
-    }
-
-    /**
-     * Sets the selected state of the specified items. Note that the callback will NOT
-     * be consulted to see if an item can be selected.
-     *
-     * @param ids
-     * @param selected
-     * @return
-     */
-    public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
-        final boolean changed = setItemsSelectedQuietly(ids, selected);
-        notifySelectionChanged();
-        return changed;
-    }
-
-    private boolean setItemsSelectedQuietly(Iterable<String> ids, boolean selected) {
-        boolean changed = false;
-        for (String id: ids) {
-            final boolean itemChanged =
-                    selected
-                    ? canSetState(id, true) && mSelection.add(id)
-                    : canSetState(id, false) && mSelection.remove(id);
-            if (itemChanged) {
-                notifyItemStateChanged(id, selected);
-            }
-            changed |= itemChanged;
-        }
-        return changed;
-    }
-
-    /**
-     * Clears the selection and notifies (if something changes).
-     */
-    public void clearSelection() {
-        if (!hasSelection()) {
-            return;
-        }
-
-        clearSelectionQuietly();
-        notifySelectionChanged();
-    }
-
-    /**
-     * Clears the selection, without notifying selection listeners. UI elements still need to be
-     * notified about state changes so that they can update their appearance.
-     */
-    private void clearSelectionQuietly() {
-        mRanger = null;
-
-        if (!hasSelection()) {
-            return;
-        }
-
-        Selection oldSelection = getSelection(new Selection());
-        mSelection.clear();
-
-        for (String id: oldSelection.mSelection) {
-            notifyItemStateChanged(id, false);
-        }
-        for (String id: oldSelection.mProvisionalSelection) {
-            notifyItemStateChanged(id, false);
-        }
-    }
-
-    /**
-     * Toggles selection on the item with the given model ID.
-     *
-     * @param modelId
-     */
-    public void toggleSelection(String modelId) {
-        assert(modelId != null);
-
-        final boolean changed = mSelection.contains(modelId)
-                ? attemptDeselect(modelId)
-                : attemptSelect(modelId);
-
-        if (changed) {
-            notifySelectionChanged();
-        }
-    }
-
-    /**
-     * Starts a range selection. If a range selection is already active, this will start a new range
-     * selection (which will reset the range anchor).
-     *
-     * @param pos The anchor position for the selection range.
-     */
-    public void startRangeSelection(int pos) {
-        attemptSelect(mAdapter.getModelId(pos));
-        setSelectionRangeBegin(pos);
-    }
-
-    public void snapRangeSelection(int pos) {
-        snapRangeSelection(pos, RANGE_REGULAR);
-    }
-
-    void snapProvisionalRangeSelection(int pos) {
-        snapRangeSelection(pos, RANGE_PROVISIONAL);
-    }
-
-    /*
-     * Starts and extends range selection in one go. This assumes item at startPos is not selected
-     * beforehand.
-     */
-    public void formNewSelectionRange(int startPos, int endPos) {
-        assert(!mSelection.contains(mAdapter.getModelId(startPos)));
-        startRangeSelection(startPos);
-        snapRangeSelection(endPos);
-    }
-
-    /**
-     * Sets the end point for the current range selection, started by a call to
-     * {@link #startRangeSelection(int)}. This function should only be called when a range selection
-     * is active (see {@link #isRangeSelectionActive()}. Items in the range [anchor, end] will be
-     * selected or in provisional select, depending on the type supplied. Note that if the type is
-     * provisional select, one should do {@link Selection#applyProvisionalSelection()} at some point
-     * before calling on {@link #endRangeSelection()}.
-     *
-     * @param pos The new end position for the selection range.
-     * @param type The type of selection the range should utilize.
-     */
-    private void snapRangeSelection(int pos, @RangeType int type) {
-        if (!isRangeSelectionActive()) {
-            throw new IllegalStateException("Range start point not set.");
-        }
-
-        mRanger.snapSelection(pos, type);
-
-        // We're being lazy here notifying even when something might not have changed.
-        // To make this more correct, we'd need to update the Ranger class to return
-        // information about what has changed.
-        notifySelectionChanged();
-    }
-
-    void cancelProvisionalSelection() {
-        for (String id : mSelection.mProvisionalSelection) {
-            notifyItemStateChanged(id, false);
-        }
-        mSelection.cancelProvisionalSelection();
-    }
-
-    /**
-     * Stops an in-progress range selection. All selection done with
-     * {@link #snapRangeSelection(int, int)} with type RANGE_PROVISIONAL will be lost if
-     * {@link Selection#applyProvisionalSelection()} is not called beforehand.
-     */
-    public void endRangeSelection() {
-        mRanger = null;
-        // Clean up in case there was any leftover provisional selection
-        cancelProvisionalSelection();
-    }
-
-    /**
-     * @return Whether or not there is a current range selection active.
-     */
-    public boolean isRangeSelectionActive() {
-        return mRanger != null;
-    }
-
-    /**
-     * Sets the magic location at which a selection range begins (the selection anchor). This value
-     * is consulted when determining how to extend, and modify selection ranges. Calling this when a
-     * range selection is active will reset the range selection.
-     */
-    public void setSelectionRangeBegin(int position) {
-        if (position == RecyclerView.NO_POSITION) {
-            return;
-        }
-
-        if (mSelection.contains(mAdapter.getModelId(position))) {
-            mRanger = new Range(this::updateForRange, position);
-        }
-    }
-
-    /**
-     * @param modelId
-     * @return True if the update was applied.
-     */
-    private boolean selectAndNotify(String modelId) {
-        boolean changed = mSelection.add(modelId);
-        if (changed) {
-            notifyItemStateChanged(modelId, true);
-        }
-        return changed;
-    }
-
-    /**
-     * @param id
-     * @return True if the update was applied.
-     */
-    private boolean attemptDeselect(String id) {
-        assert(id != null);
-        if (canSetState(id, false)) {
-            mSelection.remove(id);
-            notifyItemStateChanged(id, false);
-
-            // if there's nothing in the selection and there is an active ranger it results
-            // in unexpected behavior when the user tries to start range selection: the item
-            // which the ranger 'thinks' is the already selected anchor becomes unselectable
-            if (mSelection.isEmpty() && isRangeSelectionActive()) {
-                endRangeSelection();
-            }
-            if (DEBUG) Log.d(TAG, "Selection after deselect: " + mSelection);
-            return true;
-        } else {
-            if (DEBUG) Log.d(TAG, "Select cancelled by listener.");
-            return false;
-        }
-    }
-
-    /**
-     * @param id
-     * @return True if the update was applied.
-     */
-    private boolean attemptSelect(String id) {
-        assert(id != null);
-        boolean canSelect = canSetState(id, true);
-        if (!canSelect) {
-            return false;
-        }
-        if (mSingleSelect && hasSelection()) {
-            clearSelectionQuietly();
-        }
-
-        selectAndNotify(id);
-        return true;
-    }
-
-    boolean canSetState(String id, boolean nextState) {
-        return mCanSetState.test(id, nextState);
-    }
-
-    private void notifyDataChanged() {
-        final int lastListener = mItemCallbacks.size() - 1;
-
-        for (int i = lastListener; i >= 0; i--) {
-            mItemCallbacks.get(i).onSelectionReset();
-        }
-
-        for (String id : mSelection) {
-            if (!canSetState(id, true)) {
-                attemptDeselect(id);
-            } else {
-                for (int i = lastListener; i >= 0; i--) {
-                    mItemCallbacks.get(i).onItemStateChanged(id, true);
-                }
-            }
-        }
-    }
-
-    /**
-     * Notifies registered listeners when the selection status of a single item
-     * (identified by {@code position}) changes.
-     */
-    void notifyItemStateChanged(String id, boolean selected) {
-        assert(id != null);
-        int lastListener = mItemCallbacks.size() - 1;
-        for (int i = lastListener; i >= 0; i--) {
-            mItemCallbacks.get(i).onItemStateChanged(id, selected);
-        }
-        mAdapter.onItemSelectionChanged(id);
-    }
-
-    /**
-     * Notifies registered listeners when the selection has changed. This
-     * notification should be sent only once a full series of changes
-     * is complete, e.g. clearingSelection, or updating the single
-     * selection from one item to another.
-     */
-    void notifySelectionChanged() {
-        int lastListener = mCallbacks.size() - 1;
-        for (int i = lastListener; i > -1; i--) {
-            mCallbacks.get(i).onSelectionChanged();
-        }
-    }
-
-    private void notifySelectionRestored() {
-        int lastListener = mCallbacks.size() - 1;
-        for (int i = lastListener; i > -1; i--) {
-            mCallbacks.get(i).onSelectionRestored();
-        }
-    }
-
-    void updateForRange(int begin, int end, boolean selected, @RangeType int type) {
-        switch (type) {
-            case RANGE_REGULAR:
-                updateForRegularRange(begin, end, selected);
-                break;
-            case RANGE_PROVISIONAL:
-                updateForProvisionalRange(begin, end, selected);
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid range type: " + type);
-        }
-    }
-
-    private void updateForRegularRange(int begin, int end, boolean selected) {
-        assert(end >= begin);
-        for (int i = begin; i <= end; i++) {
-            String id = mAdapter.getModelId(i);
-            if (id == null) {
-                continue;
-            }
-
-            if (selected) {
-                boolean canSelect = canSetState(id, true);
-                if (canSelect) {
-                    if (mSingleSelect && hasSelection()) {
-                        clearSelectionQuietly();
-                    }
-                    selectAndNotify(id);
-                }
-            } else {
-                attemptDeselect(id);
-            }
-        }
-    }
-
-    private void updateForProvisionalRange(int begin, int end, boolean selected) {
-        assert (end >= begin);
-        for (int i = begin; i <= end; i++) {
-            String id = mAdapter.getModelId(i);
-            if (id == null) {
-                continue;
-            }
-
-            boolean changedState = false;
-            if (selected) {
-                boolean canSelect = canSetState(id, true);
-                if (canSelect && !mSelection.mSelection.contains(id)) {
-                    mSelection.mProvisionalSelection.add(id);
-                    changedState = true;
-                }
-            } else {
-                mSelection.mProvisionalSelection.remove(id);
-                changedState = true;
-            }
-
-            // Only notify item callbacks when something's state is actually changed in provisional
-            // selection.
-            if (changedState) {
-                notifyItemStateChanged(id, selected);
-            }
-        }
-        notifySelectionChanged();
-    }
-
-    public interface ItemCallback {
-        void onItemStateChanged(String id, boolean selected);
-
-        void onSelectionReset();
-    }
-
-    public interface Callback {
-        /**
-         * Called immediately after completion of any set of changes.
-         */
-        void onSelectionChanged();
-
-        /**
-         * Called immediately after selection is restored.
-         */
-        void onSelectionRestored();
-    }
-
-    @FunctionalInterface
-    public interface SelectionPredicate {
-        boolean test(String id, boolean nextState);
-    }
-}
diff --git a/src/com/android/documentsui/selection/Shared.java b/src/com/android/documentsui/selection/Shared.java
new file mode 100644
index 0000000..bf30919
--- /dev/null
+++ b/src/com/android/documentsui/selection/Shared.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+/**
+ * Shared constants used in this and descendant packages.
+ */
+public final class Shared {
+
+    public static final String TAG = "SelectionHelper";
+    public static final boolean DEBUG = false;
+    public static final boolean VERBOSE = false;
+
+    private Shared() {}
+}
diff --git a/src/com/android/documentsui/selection/ToolHandlerRegistry.java b/src/com/android/documentsui/selection/ToolHandlerRegistry.java
new file mode 100644
index 0000000..65f9f2e
--- /dev/null
+++ b/src/com/android/documentsui/selection/ToolHandlerRegistry.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+import static android.support.v4.util.Preconditions.checkState;
+
+import android.support.annotation.Nullable;
+import android.view.MotionEvent;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Registry for tool specific event handler.
+ */
+final class ToolHandlerRegistry<T> {
+
+    // Currently there are four known input types. ERASER is the last one, so has the
+    // highest value. UNKNOWN is zero, so we add one. This allows delegates to be
+    // registered by type, and avoid the auto-boxing that would be necessary were we
+    // to store delegates in a Map<Integer, Delegate>.
+    private static final int sNumInputTypes = MotionEvent.TOOL_TYPE_ERASER + 1;
+
+    private final List<T> mHandlers = Arrays.asList(null, null, null, null, null);
+    private final T mDefault;
+
+    ToolHandlerRegistry(T defaultDelegate) {
+        checkArgument(defaultDelegate != null);
+        mDefault = defaultDelegate;
+
+        // Initialize all values to null.
+        for (int i = 0; i < sNumInputTypes; i++) {
+            mHandlers.set(i, null);
+        }
+    }
+
+    /**
+     * @param toolType
+     * @param delegate the delegate, or null to unregister.
+     * @throws IllegalStateException if an tooltype handler is already registered.
+     */
+    void set(int toolType, @Nullable T delegate) {
+        checkArgument(toolType >= 0 && toolType <= MotionEvent.TOOL_TYPE_ERASER);
+        checkState(mHandlers.get(toolType) == null);
+
+        mHandlers.set(toolType, delegate);
+    }
+
+    T get(MotionEvent e) {
+        T d = mHandlers.get(e.getToolType(0));
+        return d != null ? d : mDefault;
+    }
+}
diff --git a/src/com/android/documentsui/selection/TouchEventRouter.java b/src/com/android/documentsui/selection/TouchEventRouter.java
new file mode 100644
index 0000000..50585fe
--- /dev/null
+++ b/src/com/android/documentsui/selection/TouchEventRouter.java
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+
+/**
+ * A class responsible for routing MotionEvents to tool-type specific handlers,
+ * and if not handled by a handler, on to a {@link GestureDetector} for further
+ * processing.
+ *
+ * <p>TouchEventRouter takes its name from
+ * {@link RecyclerView#addOnItemTouchListener(OnItemTouchListener)}. Despite "Touch"
+ * being in the name, it receives MotionEvents for all types of tools.
+ */
+public final class TouchEventRouter implements OnItemTouchListener {
+
+    private final GestureDetector mDetector;
+    private final ToolHandlerRegistry<OnItemTouchListener> mDelegates;
+
+    public TouchEventRouter(GestureDetector detector, OnItemTouchListener defaultDelegate) {
+        checkArgument(detector != null);
+        checkArgument(defaultDelegate != null);
+
+        mDetector = detector;
+        mDelegates = new ToolHandlerRegistry<>(defaultDelegate);
+    }
+
+    public TouchEventRouter(GestureDetector detector) {
+        this(
+                detector,
+                // Default listener does nothing.
+                new OnItemTouchListener() {
+                    @Override
+                    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+                        return false;
+                    }
+
+                    @Override
+                    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+                    }
+
+                    @Override
+                    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+                    }
+                });
+    }
+
+    /**
+     * @param toolType See MotionEvent for details on available types.
+     * @param delegate An {@link OnItemTouchListener} to receive events
+     *     of {@code toolType}.
+     */
+    public void register(int toolType, OnItemTouchListener delegate) {
+        checkArgument(delegate != null);
+        mDelegates.set(toolType, delegate);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+        boolean handled = mDelegates.get(e).onInterceptTouchEvent(rv, e);
+
+        // Forward all events to UserInputHandler.
+        // This is necessary since UserInputHandler needs to always see the first DOWN event. Or
+        // else all future UP events will be tossed.
+        handled |= mDetector.onTouchEvent(e);
+
+        return handled;
+    }
+
+    @Override
+    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+        mDelegates.get(e).onTouchEvent(rv, e);
+
+        // Note: even though this event is being handled as part of gestures such as drag and band,
+        // continue forwarding to the GestureDetector. The detector needs to see the entire cluster
+        // of events in order to properly interpret other gestures, such as long press.
+        mDetector.onTouchEvent(e);
+    }
+
+    @Override
+    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+}
diff --git a/src/com/android/documentsui/selection/TouchInputHandler.java b/src/com/android/documentsui/selection/TouchInputHandler.java
new file mode 100644
index 0000000..12ed33c
--- /dev/null
+++ b/src/com/android/documentsui/selection/TouchInputHandler.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static com.android.documentsui.base.Shared.DEBUG;
+
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+/**
+ * A MotionInputHandler that provides the high-level glue for touch driven selection. This class
+ * works with {@link RecyclerView}, {@link GestureRouter}, and {@link GestureSelectionHelper} to
+ * provide robust user drive selection support.
+ */
+public final class TouchInputHandler extends MotionInputHandler {
+    private static final String TAG = "TouchInputDelegate";
+
+    private final SelectionPredicate mSelectionPredicate;
+    private final Callbacks mCallbacks;
+    private final Runnable mGestureKicker;
+
+    public TouchInputHandler(
+            SelectionHelper selectionHelper,
+            ItemDetailsLookup detailsLookup,
+            SelectionPredicate selectionPredicate,
+            Runnable gestureKicker,
+            Callbacks callbacks) {
+
+        super(selectionHelper, detailsLookup, callbacks);
+
+        mSelectionPredicate = selectionPredicate;
+        mGestureKicker = gestureKicker;
+        mCallbacks = callbacks;
+    }
+
+    public TouchInputHandler(
+            SelectionHelper selectionHelper,
+            ItemDetailsLookup detailsLookup,
+            SelectionPredicate selectionPredicate,
+            GestureSelectionHelper gestureHelper,
+            Callbacks callbacks) {
+
+        this(
+                selectionHelper,
+                detailsLookup,
+                selectionPredicate,
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        gestureHelper.start();
+                    }
+                },
+                callbacks);
+    }
+
+    @Override
+    public boolean onSingleTapUp(MotionEvent e) {
+        if (!mDetailsLookup.overStableItem(e)) {
+            if (DEBUG) Log.d(TAG, "Tap not associated w/ model item. Clearing selection.");
+            mSelectionHelper.clearSelection();
+            return false;
+        }
+
+        ItemDetails item = mDetailsLookup.getItemDetails(e);
+        if (mSelectionHelper.hasSelection()) {
+            if (isRangeExtension(e)) {
+                extendSelectionRange(item);
+            } else if (mSelectionHelper.isSelected(item.getStableId())) {
+                mSelectionHelper.deselect(item.getStableId());
+            } else {
+                selectItem(item);
+            }
+
+            return true;
+        }
+
+        // Touch events select if they occur in the selection hotspot,
+        // otherwise they activate.
+        return item.inSelectionHotspot(e)
+                ? selectItem(item)
+                : mCallbacks.onItemActivated(item, e);
+    }
+
+    @Override
+    public final void onLongPress(MotionEvent e) {
+        if (!mDetailsLookup.overStableItem(e)) {
+            if (DEBUG) Log.d(TAG, "Ignoring LongPress on non-model-backed item.");
+            return;
+        }
+
+        ItemDetails item = mDetailsLookup.getItemDetails(e);
+        boolean handled = false;
+
+        if (isRangeExtension(e)) {
+            extendSelectionRange(item);
+            handled = true;
+        } else {
+            if (!mSelectionHelper.isSelected(item.getStableId())
+                    && mSelectionPredicate.canSetStateForId(item.getStableId(), true)) {
+                // If we cannot select it, we didn't apply anchoring - therefore should not
+                // start gesture selection
+                if (selectItem(item)) {
+                    // And finally if the item was selected && we can select multiple
+                    // we kick off gesture selection.
+                    if (mSelectionPredicate.canSelectMultiple()) {
+                        mGestureKicker.run();
+                    }
+                    handled = true;
+                }
+            } else {
+                // We only initiate drag and drop on long press for touch to allow regular
+                // touch-based scrolling
+                // mTouchDragListener.accept(e);
+                mCallbacks.onDragInitiated(e);
+                handled = true;
+            }
+        }
+
+        if (handled) {
+            mCallbacks.onPerformHapticFeedback();
+        }
+    }
+
+    public static abstract class Callbacks extends MotionInputHandler.Callbacks {
+        public abstract boolean onItemActivated(ItemDetails item, MotionEvent e);
+        public boolean onDragInitiated(MotionEvent e) {
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/ui/ViewAutoScroller.java b/src/com/android/documentsui/selection/ViewAutoScroller.java
similarity index 74%
rename from src/com/android/documentsui/ui/ViewAutoScroller.java
rename to src/com/android/documentsui/selection/ViewAutoScroller.java
index 2add5ae..b77176c 100644
--- a/src/com/android/documentsui/ui/ViewAutoScroller.java
+++ b/src/com/android/documentsui/selection/ViewAutoScroller.java
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-
-package com.android.documentsui.ui;
+package com.android.documentsui.selection;
 
 import android.graphics.Point;
 
@@ -27,19 +26,20 @@
  * past top/bottom of the screen.
  */
 public final class ViewAutoScroller implements Runnable {
-    public static final int NOT_SET = -1;
+
     // ratio used to calculate the top/bottom hotspot region; used with view height
     public static final float TOP_BOTTOM_THRESHOLD_RATIO = 0.125f;
     public static final int MAX_SCROLL_STEP = 70;
 
-    // Top and bottom inner buffer such that user's cursor does not have to be exactly off screen
-    // for auto scrolling to begin
-    private final ScrollDistanceDelegate mCalcDelegate;
-    private final ScrollActionDelegate mUiDelegate;
+    private ScrollHost mHost;
+    private ScrollerCallbacks mCallbacks;
 
-    public ViewAutoScroller(ScrollDistanceDelegate calcDelegate, ScrollActionDelegate uiDelegate) {
-        mCalcDelegate = calcDelegate;
-        mUiDelegate = uiDelegate;
+    public ViewAutoScroller(ScrollHost scrollHost, ScrollerCallbacks callbacks) {
+        assert scrollHost != null;
+        assert callbacks != null;
+
+        mHost = scrollHost;
+        mCallbacks = callbacks;
     }
 
     /**
@@ -56,18 +56,18 @@
         // pointer are in these buffer pixels.
         int pixelsPastView = 0;
 
-        final int topBottomThreshold = (int) (mCalcDelegate.getViewHeight()
+        final int topBottomThreshold = (int) (mHost.getViewHeight()
                 * TOP_BOTTOM_THRESHOLD_RATIO);
 
-        if (mCalcDelegate.getCurrentPosition().y <= topBottomThreshold) {
-            pixelsPastView = mCalcDelegate.getCurrentPosition().y - topBottomThreshold;
-        } else if (mCalcDelegate.getCurrentPosition().y >= mCalcDelegate.getViewHeight()
+        if (mHost.getCurrentPosition().y <= topBottomThreshold) {
+            pixelsPastView = mHost.getCurrentPosition().y - topBottomThreshold;
+        } else if (mHost.getCurrentPosition().y >= mHost.getViewHeight()
                 - topBottomThreshold) {
-            pixelsPastView = mCalcDelegate.getCurrentPosition().y - mCalcDelegate.getViewHeight()
+            pixelsPastView = mHost.getCurrentPosition().y - mHost.getViewHeight()
                     + topBottomThreshold;
         }
 
-        if (!mCalcDelegate.isActive() || pixelsPastView == 0) {
+        if (!mHost.isActive() || pixelsPastView == 0) {
             // If the operation that started the scrolling is no longer inactive, or if it is active
             // but not at the edge of the view, no scrolling is necessary.
             return;
@@ -79,11 +79,11 @@
 
         // Compute the number of pixels to scroll, and scroll that many pixels.
         final int numPixels = computeScrollDistance(pixelsPastView);
-        mUiDelegate.scrollBy(numPixels);
+        mCallbacks.scrollBy(numPixels);
 
         // Remove callback to this, and then properly run at next frame again
-        mUiDelegate.removeCallback(this);
-        mUiDelegate.runAtNextFrame(this);
+        mCallbacks.removeCallback(this);
+        mCallbacks.runAtNextFrame(this);
     }
 
     /**
@@ -93,8 +93,8 @@
      * @return
      */
     public int computeScrollDistance(int pixelsPastView) {
-        final int topBottomThreshold = (int) (mCalcDelegate.getViewHeight()
-                * TOP_BOTTOM_THRESHOLD_RATIO);
+        final int topBottomThreshold =
+                (int) (mHost.getViewHeight() * TOP_BOTTOM_THRESHOLD_RATIO);
 
         final int direction = (int) Math.signum(pixelsPastView);
         final int absPastView = Math.abs(pixelsPastView);
@@ -131,18 +131,19 @@
      * Used by {@link run} to properly calculate the proper amount of pixels to scroll given time
      * passed since scroll started, and to properly scroll / proper listener clean up if necessary.
      */
-    public interface ScrollDistanceDelegate {
-        public Point getCurrentPosition();
-        public int getViewHeight();
-        public boolean isActive();
+    public static abstract class ScrollHost {
+        public abstract Point getCurrentPosition();
+        public abstract int getViewHeight();
+        public abstract boolean isActive();
     }
 
     /**
-     * Used by {@link run} to do UI tasks, such as scrolling and rerunning at next UI cycle.
+     * Callback used by scroller to perform UI tasks, such as scrolling and rerunning at next UI
+     * cycle.
      */
-    public interface ScrollActionDelegate {
-        public void scrollBy(int dy);
-        public void runAtNextFrame(Runnable r);
-        public void removeCallback(Runnable r);
+    public static abstract class ScrollerCallbacks {
+        public void scrollBy(int dy) {}
+        public void runAtNextFrame(Runnable r) {}
+        public void removeCallback(Runnable r) {}
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/selection/demo/DemoDetailsLookup.java b/src/com/android/documentsui/selection/demo/DemoDetailsLookup.java
new file mode 100644
index 0000000..6811125
--- /dev/null
+++ b/src/com/android/documentsui/selection/demo/DemoDetailsLookup.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.demo;
+
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.documentsui.selection.ItemDetailsLookup;
+
+/**
+ * Access to details of an item associated with a {@link MotionEvent} instance.
+ */
+final class DemoDetailsLookup extends ItemDetailsLookup {
+
+    private final RecyclerView mRecView;
+
+    public DemoDetailsLookup(RecyclerView view) {
+        mRecView = view;
+    }
+
+    @Override
+    public boolean overItem(MotionEvent e) {
+        return getItemPosition(e) != RecyclerView.NO_POSITION;
+    }
+
+    @Override
+    public boolean overStableItem(MotionEvent e) {
+        return overItem(e) && getItemDetails(e).hasStableId();
+    }
+
+    @Override
+    public boolean inItemDragRegion(MotionEvent e) {
+        return overItem(e) && getItemDetails(e).inDragRegion(e);
+    }
+
+    @Override
+    public boolean inItemSelectRegion(MotionEvent e) {
+        return overItem(e) && getItemDetails(e).inSelectionHotspot(e);
+    }
+
+    @Override
+    public int getItemPosition(MotionEvent e) {
+        View child = mRecView.findChildViewUnder(e.getX(), e.getY());
+        return (child != null)
+                ? mRecView.getChildAdapterPosition(child)
+                : RecyclerView.NO_POSITION;
+    }
+
+    @Override
+    public ItemDetails getItemDetails(MotionEvent e) {
+        @Nullable DemoHolder holder = getDemoHolder(e);
+        return holder == null ? null : holder.getItemDetails();
+    }
+
+    private @Nullable DemoHolder getDemoHolder(MotionEvent e) {
+        View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
+        if (childView != null) {
+            ViewHolder holder = mRecView.getChildViewHolder(childView);
+            if (holder instanceof DemoHolder) {
+                return (DemoHolder) holder;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/documentsui/selection/demo/DemoHolder.java b/src/com/android/documentsui/selection/demo/DemoHolder.java
new file mode 100644
index 0000000..3a783b5
--- /dev/null
+++ b/src/com/android/documentsui/selection/demo/DemoHolder.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.demo;
+
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.documentsui.R;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+
+public final class DemoHolder extends RecyclerView.ViewHolder {
+
+        private final LinearLayout mContainer;
+        public final TextView mSelector;
+        public final TextView mLabel;
+        private final Details mDetails;
+        private DemoItem mItem;
+
+        DemoHolder(LinearLayout layout) {
+            super(layout);
+            mContainer = layout.findViewById(R.id.container);
+            mSelector = layout.findViewById(R.id.selector);
+            mLabel = layout.findViewById(R.id.label);
+            mDetails = new Details(this);
+        }
+
+        public void update(DemoItem demoItem) {
+            mItem = demoItem;
+            mLabel.setText(mItem.getName());
+        }
+
+        void setSelected(boolean selected) {
+            mContainer.setActivated(selected);
+            mSelector.setActivated(selected);
+        }
+
+        public String getStableId() {
+            return mItem != null ? mItem.getId() : null;
+        }
+
+        public boolean inDragRegion(MotionEvent e) {
+            // If itemView is activated = selected, then whole region is interactive
+            if (mContainer.isActivated()) {
+                return true;
+            }
+
+            if (inSelectRegion(e)) {
+                return true;
+            }
+
+            Rect rect = new Rect();
+            mLabel.getPaint().getTextBounds(
+                    mLabel.getText().toString(), 0, mLabel.getText().length(), rect);
+
+            // If the tap occurred inside the text, these are interactive spots.
+            return rect.contains((int) e.getRawX(), (int) e.getRawY());
+        }
+
+        public boolean inSelectRegion(MotionEvent e) {
+            Rect iconRect = new Rect();
+            mSelector.getGlobalVisibleRect(iconRect);
+            return iconRect.contains((int) e.getRawX(), (int) e.getRawY());
+        }
+
+        Details getItemDetails() {
+            return mDetails;
+        }
+
+        private static final class Details extends ItemDetails {
+
+            private final DemoHolder mHolder;
+
+            Details(DemoHolder holder) {
+                mHolder = holder;
+            }
+
+            @Override
+            public int getPosition() {
+                return mHolder.getAdapterPosition();
+            }
+
+            @Override
+            public String getStableId() {
+                return mHolder.getStableId();
+            }
+
+            @Override
+            public int getItemViewType() {
+                return mHolder.getItemViewType();
+            }
+
+            @Override
+            public boolean inDragRegion(MotionEvent e) {
+                return mHolder.inDragRegion(e);
+            }
+
+            @Override
+            public boolean inSelectionHotspot(MotionEvent e) {
+                return mHolder.inSelectRegion(e);
+            }
+        }
+    }
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/demo/DemoItem.java b/src/com/android/documentsui/selection/demo/DemoItem.java
new file mode 100644
index 0000000..15755a0
--- /dev/null
+++ b/src/com/android/documentsui/selection/demo/DemoItem.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.demo;
+
+public class DemoItem {
+
+    private final String mId;
+    private final String mName;
+
+    DemoItem(String id, String name) {
+        mId = id;
+        mName = name;
+    }
+
+    public String getId() {
+        return mId;
+    }
+
+    public String getName() {
+        return mName;
+    }
+}
diff --git a/src/com/android/documentsui/selection/demo/DemoStableIdProvider.java b/src/com/android/documentsui/selection/demo/DemoStableIdProvider.java
new file mode 100644
index 0000000..45cdd6c
--- /dev/null
+++ b/src/com/android/documentsui/selection/demo/DemoStableIdProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.demo;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+
+import java.util.List;
+
+/**
+ * Provides RecyclerView selection code access to stable ids backed
+ * by DocumentsAdapter.
+ */
+final class DemoStableIdProvider extends StableIdProvider {
+
+    private final SelectionDemoAdapter mAdapter;
+
+    public DemoStableIdProvider(SelectionDemoAdapter adapter) {
+        checkArgument(adapter != null);
+        mAdapter = adapter;
+    }
+
+    @Override
+    public String getStableId(int position) {
+        return mAdapter.getStableId(position);
+    }
+
+    @Override
+    public int getPosition(String id) {
+        return mAdapter.getPosition(id);
+    }
+
+    @Override
+    public List<String> getStableIds() {
+        return mAdapter.getStableIds();
+    }
+}
diff --git a/src/com/android/documentsui/selection/demo/SelectionDemoActivity.java b/src/com/android/documentsui/selection/demo/SelectionDemoActivity.java
new file mode 100644
index 0000000..6d348a8
--- /dev/null
+++ b/src/com/android/documentsui/selection/demo/SelectionDemoActivity.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.demo;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.CallSuper;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.view.GestureDetector;
+import android.view.HapticFeedbackConstants;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.widget.Toast;
+
+import com.android.documentsui.R;
+import com.android.documentsui.selection.BandSelectionHelper;
+import com.android.documentsui.selection.ContentLock;
+import com.android.documentsui.selection.DefaultBandHost;
+import com.android.documentsui.selection.DefaultBandPredicate;
+import com.android.documentsui.selection.DefaultSelectionHelper;
+import com.android.documentsui.selection.GestureRouter;
+import com.android.documentsui.selection.GestureSelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.selection.MotionInputHandler;
+import com.android.documentsui.selection.MouseInputHandler;
+import com.android.documentsui.selection.MutableSelection;
+import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+import com.android.documentsui.selection.TouchEventRouter;
+import com.android.documentsui.selection.TouchInputHandler;
+import com.android.documentsui.selection.demo.SelectionDemoAdapter.OnBindCallback;
+
+/**
+ * ContentPager demo activity.
+ */
+public class SelectionDemoActivity extends AppCompatActivity {
+
+    private static final String EXTRA_SAVED_SELECTION = "demo-saved-selection";
+    private static final String EXTRA_COLUMN_COUNT = "demo-column-count";
+
+    private Toolbar mToolbar;
+    private SelectionDemoAdapter mAdapter;
+    private SelectionHelper mSelectionHelper;
+
+    private RecyclerView mRecView;
+    private GridLayoutManager mLayout;
+    private int mColumnCount = 1;  // This will get updated when layout changes.
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.selection_demo_layout);
+        mToolbar = findViewById(R.id.toolbar);
+        setSupportActionBar(mToolbar);
+        mRecView = (RecyclerView) findViewById(R.id.list);
+
+        mLayout = new GridLayoutManager(this, mColumnCount);
+        mRecView.setLayoutManager(mLayout);
+
+        mAdapter = new SelectionDemoAdapter(this);
+        mRecView.setAdapter(mAdapter);
+
+        StableIdProvider stableIds = new DemoStableIdProvider(mAdapter);
+
+        // SelectionPredicate permits client control of which items can be selected.
+        SelectionPredicate canSelectAnything = new SelectionPredicate() {
+            @Override
+            public boolean canSetStateForId(String id, boolean nextState) {
+                return true;
+            }
+
+            @Override
+            public boolean canSetStateAtPosition(int position, boolean nextState) {
+                return true;
+            }
+        };
+
+        // TODO: Reload content when it changes. Could use CursorLoader.
+        // TODO: Retain selection. Restore when content changes.
+
+        mSelectionHelper = new DefaultSelectionHelper(
+                DefaultSelectionHelper.MODE_MULTIPLE,
+                mAdapter,
+                stableIds,
+                canSelectAnything);
+
+        // onBind event callback that allows items to be updated to reflect
+        // selection status when bound by recycler view.
+        // This allows us to defer initialization of the SelectionHelper dependency
+        // which itself depends on the Adapter.
+        mAdapter.addOnBindCallback(
+                new OnBindCallback() {
+                    @Override
+                    void onBound(DemoHolder holder, int position) {
+                        String id = mAdapter.getStableId(position);
+                        holder.setSelected(mSelectionHelper.isSelected(id));
+                    }
+                });
+
+        ItemDetailsLookup detailsLookup = new DemoDetailsLookup(mRecView);
+
+        // Setup basic input handling, with the touch handler as the default consumer
+        // of events. If mouse handling is configured as well, the mouse input
+        // related handlers will intercept mouse input events.
+
+        // GestureRouter is responsible for routing GestureDetector events
+        // to tool-type specific handlers.
+        GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>();
+        GestureDetector gestureDetector = new GestureDetector(this, gestureRouter);
+
+        // TouchEventRouter takes its name from RecyclerView#OnItemTouchListener.
+        // Despite "Touch" being in the name, it receives events for all types of tools.
+        // This class is responsible for routing events to tool-type specific handlers,
+        // and if not handled by a handler, on to a GestureDetector for analysis.
+        TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector);
+
+        // Content lock provides a mechanism to block content reload while selection
+        // activities are active. If using a loader to load content, route
+        // the call through the content lock using ContentLock#runWhenUnlocked.
+        // This is especially useful when listening on content change notification.
+        ContentLock contentLock = new ContentLock();
+
+        // GestureSelectionHelper provides logic that interprets a combination
+        // of motions and gestures in order to provide gesture driven selection support
+        // when used in conjunction with RecyclerView.
+        GestureSelectionHelper gestureHelper =
+                GestureSelectionHelper.create(mSelectionHelper, mRecView, contentLock);
+
+        // Finally hook the framework up to listening to recycle view events.
+        mRecView.addOnItemTouchListener(eventRouter);
+
+        // But before you move on, there's more work to do. Event plumbing has been
+        // installed, but we haven't registered any of our helpers or callbacks.
+        // Helpers contain predefined logic converting events into selection related events.
+        // Callbacks provide authors the ability to reponspond to other types of
+        // events (like "active" a tapped item). This is broken up into two main
+        // suites, one for "touch" and one for "mouse", though both can and should (usually)
+        // be configued to handle other types of input (to satisfy user expectation).
+
+        // TOUCH (+ UNKNOWN) handeling provides gesture based selection allowing
+        // the user to long press on an item, then drag her finger over other
+        // items in order to extend the selection.
+        TouchCallbacks touchCallbacks = new TouchCallbacks(this, mRecView);
+
+        // Provides high level glue for binding touch events and gestures to selection framework.
+        TouchInputHandler touchHandler = new TouchInputHandler(
+                mSelectionHelper, detailsLookup, canSelectAnything, gestureHelper, touchCallbacks);
+
+        eventRouter.register(MotionEvent.TOOL_TYPE_FINGER, gestureHelper);
+        eventRouter.register(MotionEvent.TOOL_TYPE_UNKNOWN, gestureHelper);
+
+        gestureRouter.register(MotionEvent.TOOL_TYPE_FINGER, touchHandler);
+        gestureRouter.register(MotionEvent.TOOL_TYPE_UNKNOWN, touchHandler);
+
+        // MOUSE (+ STYLUS) handeling provides band based selection allowing
+        // the user to click down in an empty area, then drag her mouse
+        // to create a band that covers the items she wants selected.
+        //
+        // PRO TIP: Don't skip installing mouse/stylus support. It provides
+        // improved productivity and demonstrates feature maturity that users
+        // will appreciate. See InputManager for details on more sophisticated
+        // strategies on detecting the presence of input tools.
+
+        // Provides high level glue for binding mouse/stylus events and gestures
+        // to selection framework.
+        MouseInputHandler mouseHandler = new MouseInputHandler(
+                mSelectionHelper, detailsLookup, new MouseCallbacks(this, mRecView));
+
+        DefaultBandHost host = new DefaultBandHost(
+                mRecView, R.drawable.selection_demo_band_overlay);
+
+        // BandSelectionHelper provides support for band selection on-top of a RecyclerView
+        // instance. Given the recycling nature of RecyclerView BandSelectionController
+        // necessarily models and caches list/grid information as the user's pointer
+        // interacts with the item in the RecyclerView. Selectable items that intersect
+        // with the band, both on and off screen, are selected.
+        BandSelectionHelper bandHelper = new BandSelectionHelper(
+                host,
+                mAdapter,
+                stableIds,
+                mSelectionHelper,
+                canSelectAnything,
+                new DefaultBandPredicate(detailsLookup),
+                contentLock);
+
+
+        eventRouter.register(MotionEvent.TOOL_TYPE_MOUSE, bandHelper);
+        eventRouter.register(MotionEvent.TOOL_TYPE_STYLUS, bandHelper);
+
+        gestureRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mouseHandler);
+        gestureRouter.register(MotionEvent.TOOL_TYPE_STYLUS, mouseHandler);
+
+        // Aaaaan, all done with mouse/stylus selection setup!
+
+        updateFromSavedState(savedInstanceState);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle state) {
+        super.onSaveInstanceState(state);
+        MutableSelection selection = new MutableSelection();
+        mSelectionHelper.copySelection(selection);
+        state.putParcelable(EXTRA_SAVED_SELECTION, selection);
+        state.putInt(EXTRA_COLUMN_COUNT, mColumnCount);
+    }
+
+    private void updateFromSavedState(Bundle state) {
+        // In order to preserve selection across various lifecycle events be sure to save
+        // the selection in onSaveInstanceState, and to restore it when present in the Bundle
+        // pass in via onCreate(Bundle).
+        if (state != null) {
+            if (state.containsKey(EXTRA_SAVED_SELECTION)) {
+                Selection savedSelection = state.getParcelable(EXTRA_SAVED_SELECTION);
+                if (!savedSelection.isEmpty()) {
+                    mSelectionHelper.restoreSelection(savedSelection);
+                    CharSequence text = "Selection restored.";
+                    Toast.makeText(this, "Selection restored.", Toast.LENGTH_SHORT).show();
+                }
+            }
+            if (state.containsKey(EXTRA_COLUMN_COUNT)) {
+                mColumnCount = state.getInt(EXTRA_COLUMN_COUNT);
+                mLayout.setSpanCount(mColumnCount);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        boolean showMenu = super.onCreateOptionsMenu(menu);
+        getMenuInflater().inflate(R.menu.selection_demo_actions, menu);
+        return showMenu;
+    }
+
+    @Override
+    @CallSuper
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        menu.findItem(R.id.option_menu_add_column).setEnabled(mColumnCount <= 3);
+        menu.findItem(R.id.option_menu_remove_column).setEnabled(mColumnCount > 1);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.option_menu_add_column:
+                // TODO: Add columns
+                mLayout.setSpanCount(++mColumnCount);
+                return true;
+
+            case R.id.option_menu_remove_column:
+                mLayout.setSpanCount(--mColumnCount);
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+
+    @Override
+    public void onBackPressed () {
+        if (mSelectionHelper.hasSelection()) {
+            mSelectionHelper.clearSelection();
+            mSelectionHelper.clearProvisionalSelection();
+        } else {
+            super.onBackPressed();
+        }
+    }
+
+    private static void toast(Context context, String msg) {
+        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    protected void onDestroy() {
+        mSelectionHelper.clearSelection();
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mAdapter.loadData();
+    }
+
+    // Implementation of MouseInputHandler.Callbacks allows handling
+    // of higher level events, like onActivated.
+    private static final class MouseCallbacks extends MouseInputHandler.Callbacks {
+
+        private final Context mContext;
+        private final RecyclerView mRecView;
+
+        MouseCallbacks(Context context, RecyclerView recView) {
+            mContext = context;
+            mRecView = recView;
+        }
+
+        @Override
+        public boolean onItemActivated(ItemDetails item, MotionEvent e) {
+            toast(mContext, "Activate item: " + item.getStableId());
+            return true;
+        }
+
+        @Override
+        public boolean onContextClick(MotionEvent e) {
+            toast(mContext, "Context click received.");
+            return true;
+        }
+
+        @Override
+        public void onPerformHapticFeedback() {
+            mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+        }
+    };
+
+    private static final class TouchCallbacks extends TouchInputHandler.Callbacks {
+
+        private final Context mContext;
+        private final RecyclerView mRecView;
+
+        private TouchCallbacks(Context context, RecyclerView recView) {
+
+            mContext = context;
+            mRecView = recView;
+        }
+
+        @Override
+        public boolean onItemActivated(ItemDetails item, MotionEvent e) {
+            toast(mContext, "Activate item: " + item.getStableId());
+            return true;
+        }
+
+        @Override
+        public void onPerformHapticFeedback() {
+            mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/demo/SelectionDemoAdapter.java b/src/com/android/documentsui/selection/demo/SelectionDemoAdapter.java
new file mode 100644
index 0000000..b896e91
--- /dev/null
+++ b/src/com/android/documentsui/selection/demo/SelectionDemoAdapter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.demo;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.documentsui.R;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+final class SelectionDemoAdapter extends RecyclerView.Adapter<DemoHolder> {
+
+    private static final Map<String, DemoItem> sDemoData = new HashMap<>();
+    static {
+        for (int i = 0; i < 1000; i++) {
+            String id = createId(i);
+            sDemoData.put(id, new DemoItem(id, "item" + i));
+        }
+    }
+
+    private final Context mContext;
+    private @Nullable OnBindCallback mBindCallback;
+
+    SelectionDemoAdapter(Context context) {
+        mContext = context;
+    }
+
+    void addOnBindCallback(OnBindCallback bindCallback) {
+        mBindCallback = bindCallback;
+    }
+
+    void loadData() {
+        onDataReady();
+    }
+
+    private void onDataReady() {
+        notifyDataSetChanged();
+    }
+
+    @Override
+    public int getItemCount() {
+        return sDemoData.size();
+    }
+
+    @Override
+    public void onBindViewHolder(DemoHolder holder, int position) {
+        String id = createId(position);
+        holder.update(sDemoData.get(id));
+        if (mBindCallback != null) {
+            mBindCallback.onBound(holder, position);
+        }
+    }
+
+    private static String createId(int position) {
+        return "id" + position;
+    }
+
+    @Override
+    public DemoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        LinearLayout layout = inflateLayout(mContext, parent, R.layout.selection_demo_list_item);
+        return new DemoHolder(layout);
+    }
+
+    String getStableId(int position) {
+        return createId(position);
+    }
+
+    int getPosition(String id) {
+        return Integer.parseInt(id.substring(2));
+    }
+
+    List<String> getStableIds() {
+        return new ArrayList<>(sDemoData.keySet());
+    }
+
+    @SuppressWarnings("TypeParameterUnusedInFormals")  // Convenience to avoid clumsy cast.
+    private static <V extends View> V inflateLayout(
+            Context context, ViewGroup parent, int layout) {
+
+        return (V) LayoutInflater.from(context).inflate(layout, parent, false);
+    }
+
+    static abstract class OnBindCallback {
+        abstract void onBound(DemoHolder holder, int position);
+    }
+}
diff --git a/src/com/android/documentsui/services/FileOperation.java b/src/com/android/documentsui/services/FileOperation.java
index 2ee12d5..1f0e9b9 100644
--- a/src/com/android/documentsui/services/FileOperation.java
+++ b/src/com/android/documentsui/services/FileOperation.java
@@ -16,12 +16,13 @@
 
 package com.android.documentsui.services;
 
-import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
 import static com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS;
-import static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT;
+import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
 import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
+import static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT;
 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
 import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
+import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.content.Context;
 import android.net.Uri;
@@ -57,8 +58,8 @@
 
     @VisibleForTesting
     FileOperation(@OpType int opType, UrisSupplier srcs, DocumentStack destination) {
-        assert(opType != OPERATION_UNKNOWN);
-        assert(srcs.getItemCount() > 0);
+        checkArgument(opType != OPERATION_UNKNOWN);
+        checkArgument(srcs.getItemCount() > 0);
 
         mOpType = opType;
         mSrcs = srcs;
@@ -133,6 +134,7 @@
             return builder.toString();
         }
 
+        @Override
         CopyJob createJob(Context service, Job.Listener listener, String id, Features features) {
             return new CopyJob(
                     service, listener, id, getDestination(), getSrc(), getMessenger(), features);
@@ -173,6 +175,7 @@
             return builder.toString();
         }
 
+        @Override
         CopyJob createJob(Context service, Job.Listener listener, String id, Features features) {
             return new CompressJob(service, listener, id, getDestination(), getSrc(),
                     getMessenger(), features);
@@ -214,6 +217,7 @@
         }
 
         // TODO: Replace CopyJob with ExtractJob.
+        @Override
         CopyJob createJob(Context service, Job.Listener listener, String id, Features features) {
             return new CopyJob(
                     service, listener, id, getDestination(), getSrc(), getMessenger(), features);
diff --git a/src/com/android/documentsui/services/FileOperationService.java b/src/com/android/documentsui/services/FileOperationService.java
index 6379237..046722e 100644
--- a/src/com/android/documentsui/services/FileOperationService.java
+++ b/src/com/android/documentsui/services/FileOperationService.java
@@ -354,7 +354,7 @@
                 job.id, NOTIFICATION_ID_PROGRESS, notification);
 
         // Set up related monitor
-        JobMonitor monitor = new JobMonitor(job, notificationManager, handler);
+        JobMonitor monitor = new JobMonitor(job, notificationManager, handler, mJobs);
         monitor.start();
     }
 
@@ -458,11 +458,14 @@
         private final Job mJob;
         private final NotificationManager mNotificationManager;
         private final Handler mHandler;
+        private final Object mJobsLock;
 
-        private JobMonitor(Job job, NotificationManager notificationManager, Handler handler) {
+        private JobMonitor(Job job, NotificationManager notificationManager, Handler handler,
+                Object jobsLock) {
             mJob = job;
             mNotificationManager = notificationManager;
             mHandler = handler;
+            mJobsLock = jobsLock;
         }
 
         private void start() {
@@ -471,19 +474,21 @@
 
         @Override
         public void run() {
-            if (mJob.isFinished()) {
-                // Finish notification is already shown. Progress notification is removed.
-                // Just finish itself.
-                return;
-            }
+            synchronized (mJobsLock) {
+                if (mJob.isFinished()) {
+                    // Finish notification is already shown. Progress notification is removed.
+                    // Just finish itself.
+                    return;
+                }
 
-            // Only job in set up state has progress bar
-            if (mJob.getState() == Job.STATE_SET_UP) {
-                mNotificationManager.notify(
-                        mJob.id, NOTIFICATION_ID_PROGRESS, mJob.getProgressNotification());
-            }
+                // Only job in set up state has progress bar
+                if (mJob.getState() == Job.STATE_SET_UP) {
+                    mNotificationManager.notify(
+                            mJob.id, NOTIFICATION_ID_PROGRESS, mJob.getProgressNotification());
+                }
 
-            mHandler.postDelayed(this, PROGRESS_INTERVAL_MILLIS);
+                mHandler.postDelayed(this, PROGRESS_INTERVAL_MILLIS);
+            }
         }
     }
 
diff --git a/src/com/android/documentsui/services/Job.java b/src/com/android/documentsui/services/Job.java
index 25ed4de..0605e53 100644
--- a/src/com/android/documentsui/services/Job.java
+++ b/src/com/android/documentsui/services/Job.java
@@ -172,8 +172,7 @@
         return true;
     }
 
-    void finish() {
-    }
+    abstract void finish();
 
     abstract void start();
     abstract Notification getSetupNotification();
diff --git a/src/com/android/documentsui/ui/Snackbars.java b/src/com/android/documentsui/ui/Snackbars.java
index 8fa84dc..933af97 100644
--- a/src/com/android/documentsui/ui/Snackbars.java
+++ b/src/com/android/documentsui/ui/Snackbars.java
@@ -76,7 +76,7 @@
 
         //Document Inspector uses a different view from other files app activities.
         final View view = activity.findViewById(R.id.fragment_container);
-        Snackbar.make(view, R.string.file_inspector_load_error, Snackbar.LENGTH_INDEFINITE).show();
+        Snackbar.make(view, R.string.inspector_load_error, Snackbar.LENGTH_INDEFINITE).show();
     }
 
     public static final void showCustomTextWithImage(Activity activity, String text, int imageRes) {
diff --git a/tests/Android.mk b/tests/Android.mk
index cb1d64c..1dd259b 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -12,13 +12,12 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 LOCAL_AAPT_FLAGS += -0 .zip
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 LOCAL_STATIC_JAVA_LIBRARIES := \
     mockito-target \
     ub-uiautomator \
     espresso-core \
-    guava \
-    legacy-android-test
+    guava
 LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
 LOCAL_PACKAGE_NAME := DocumentsUITests
 LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/tests/common/com/android/documentsui/PagingProvider.java b/tests/common/com/android/documentsui/PagingProvider.java
index ad5f32c..a113bd1 100644
--- a/tests/common/com/android/documentsui/PagingProvider.java
+++ b/tests/common/com/android/documentsui/PagingProvider.java
@@ -63,7 +63,7 @@
             String parentDocumentId, String[] projection, Bundle queryArgs)
             throws FileNotFoundException {
 
-        // TODO: Content notification.
+        queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY;
 
         MatrixCursor c = createDocCursor(projection);
         Bundle extras = c.getExtras();
diff --git a/tests/common/com/android/documentsui/bots/InspectorBot.java b/tests/common/com/android/documentsui/bots/InspectorBot.java
index 55f9044..448a7b7 100644
--- a/tests/common/com/android/documentsui/bots/InspectorBot.java
+++ b/tests/common/com/android/documentsui/bots/InspectorBot.java
@@ -15,19 +15,24 @@
  */
 package com.android.documentsui.bots;
 
-import android.annotation.StringRes;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
 import android.app.Activity;
 import android.content.Context;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiSelector;
+import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import com.android.documentsui.inspector.DetailsView;
 import com.android.documentsui.R;
+import com.android.documentsui.inspector.DetailsView;
+import com.android.documentsui.inspector.KeyValueRow;
+import com.android.documentsui.inspector.TableView;
+
+import java.util.HashMap;
+import java.util.Map;
 
 public class InspectorBot extends Bots.BaseBot {
 
@@ -42,23 +47,45 @@
         assertEquals(expected, text);
     }
 
-    public void assertRowPresent(@StringRes String key, String value, Activity activity)
+    public void assertRowPresent(String key, Activity activity)
             throws Exception {
-        assertTrue(isRowPresent(key, value, activity));
+        assertTrue(isRowPresent(key, activity));
     }
 
-    private boolean isRowPresent(@StringRes String key, String value, Activity activity)
+    public void assertRowEquals(String key, String value, Activity activity)
             throws Exception {
-        DetailsView detailsView = (DetailsView) activity.findViewById(R.id.inspector_details_view);
-        int children = detailsView.getChildCount();
+        assertTrue(isRowEquals(key, value, activity));
+    }
+
+    private static Map<String, String> getTableRows(TableView table)
+            throws Exception {
+        Map<String, String> rows = new HashMap<>();
+        int children = table.getChildCount();
         for (int i = 0; i < children; i++) {
-            LinearLayout child = (LinearLayout) detailsView.getChildAt(i);
-            TextView title = (TextView) child.getChildAt(0);
-            if (title.getText().equals(key)) {
-                TextView info = (TextView) child.getChildAt(1);
-                return info.getText().equals(value);
+            View view = table.getChildAt(i);
+            if (view instanceof KeyValueRow) {
+                LinearLayout row = (LinearLayout) table.getChildAt(i);
+                TextView key = (TextView) row.getChildAt(0);
+                TextView value = (TextView) row.getChildAt(1);
+                rows.put(
+                        String.valueOf(key.getText()),
+                        String.valueOf(value.getText()));
             }
         }
-        return false;
+        return rows;
+    }
+
+    private boolean isRowPresent(String key, Activity activity)
+            throws Exception {
+        DetailsView details = (DetailsView) activity.findViewById(R.id.inspector_details_view);
+        Map<String, String> rows = getTableRows(details);
+        return rows.containsKey(key);
+    }
+
+    private boolean isRowEquals(String key, String value, Activity activity)
+            throws Exception {
+        DetailsView details = (DetailsView) activity.findViewById(R.id.inspector_details_view);
+        Map<String, String> rows = getTableRows(details);
+        return rows.containsKey(key) && value.equals(rows.get(key));
     }
 }
diff --git a/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java b/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java
index c463bb2..e2160cf 100644
--- a/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java
+++ b/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java
@@ -16,10 +16,15 @@
 
 package com.android.documentsui.dirlist;
 
+import static org.junit.Assert.assertTrue;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.AdapterDataObserver;
 import android.view.ViewGroup;
 
-import com.android.documentsui.base.EventListener;
 import com.android.documentsui.Model.Update;
+import com.android.documentsui.base.EventListener;
+import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.testing.TestEventListener;
 
 import java.util.ArrayList;
@@ -30,11 +35,53 @@
  */
 public class TestDocumentsAdapter extends DocumentsAdapter {
 
-    List<String> mModelIds = new ArrayList<>();
     final TestEventListener<Update> mModelListener = new TestEventListener<>();
+    List<String> mModelIds = new ArrayList<>();
+    private final AdapterDataObserver mAdapterObserver;
+    private final List<Integer> mSelectionChanged = new ArrayList<>();
 
     public TestDocumentsAdapter(List<String> modelIds) {
         mModelIds = modelIds;
+
+        mAdapterObserver = new RecyclerView.AdapterDataObserver() {
+
+            @Override
+            public void onChanged() {
+            }
+
+            @Override
+            public void onItemRangeChanged(int startPosition, int itemCount, Object payload) {
+                if (SelectionHelper.SELECTION_CHANGED_MARKER.equals(payload)) {
+                    int last = startPosition + itemCount;
+                    for (int i = startPosition; i < last; i++) {
+                        mSelectionChanged.add(i);
+                    }
+                }
+            }
+
+            @Override
+            public void onItemRangeInserted(int startPosition, int itemCount) {
+            }
+
+            @Override
+            public void onItemRangeRemoved(int startPosition, int itemCount) {
+            }
+
+            @Override
+            public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+                throw new UnsupportedOperationException();
+            }
+        };
+
+        registerAdapterDataObserver(mAdapterObserver);
+    }
+
+    public void resetSelectionChanged() {
+        mSelectionChanged.clear();
+    }
+
+    public void assertSelectionChanged(int position) {
+        assertTrue(mSelectionChanged.contains(position));
     }
 
     @Override
@@ -43,16 +90,17 @@
     }
 
     @Override
-    public List<String> getModelIds() {
+    public List<String> getStableIds() {
         return mModelIds;
     }
 
     @Override
-    public void onItemSelectionChanged(String id) {
+    public int getPosition(String id) {
+        return mModelIds.indexOf(id);
     }
 
     @Override
-    public String getModelId(int position) {
+    public String getStableId(int position) {
         return mModelIds.get(position);
     }
 
diff --git a/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java b/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java
index 910a3c4..8dfbdea 100644
--- a/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java
+++ b/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java
@@ -16,6 +16,8 @@
 
 package com.android.documentsui.dirlist;
 
+import static org.junit.Assert.assertEquals;
+
 import android.view.KeyEvent;
 import android.view.View;
 
@@ -80,4 +82,12 @@
         focusModelId = null;
         focusPos = 0;
     }
-}
\ No newline at end of file
+
+    public void assertHasFocus(boolean focused) {
+        assertEquals(focused, hasFocusedItem());
+    }
+
+    public void assertFocused(String modelId) {
+        assertEquals(modelId, getFocusModelId());
+    }
+}
diff --git a/tests/common/com/android/documentsui/selection/TestItemSelectionListener.java b/tests/common/com/android/documentsui/selection/TestItemSelectionListener.java
deleted file mode 100644
index dfd8e2a..0000000
--- a/tests/common/com/android/documentsui/selection/TestItemSelectionListener.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.documentsui.selection;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class TestItemSelectionListener implements SelectionManager.ItemCallback {
-
-    private final Set<String> mSelected = new HashSet<>();
-
-    @Override
-    public void onItemStateChanged(String id, boolean selected) {
-        if (selected) {
-            assertNotSelected(id);
-            mSelected.add(id);
-        } else {
-            assertSelected(id);
-            mSelected.remove(id);
-        }
-    }
-
-    @Override
-    public void onSelectionReset() {
-        mSelected.clear();
-    }
-
-    void assertNoSelection() {
-        assertTrue(mSelected.isEmpty());
-    }
-
-    void assertSelectionSize(int expected) {
-        assertEquals(expected, mSelected.size());
-    }
-
-    void assertSelected(String id) {
-        assertTrue(id + " is not selected.", mSelected.contains(id));
-    }
-
-    void assertNotSelected(String id) {
-        assertFalse(id + " is already selected", mSelected.contains(id));
-    }
-}
diff --git a/tests/common/com/android/documentsui/selection/TestSelectionListener.java b/tests/common/com/android/documentsui/selection/TestSelectionListener.java
deleted file mode 100644
index 62a86b0..0000000
--- a/tests/common/com/android/documentsui/selection/TestSelectionListener.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.documentsui.selection.SelectionManager;
-
-public final class TestSelectionListener implements SelectionManager.Callback {
-
-    private boolean mSelectionChanged = false;
-
-    @Override
-    public void onSelectionChanged() {
-        mSelectionChanged = true;
-    }
-
-    @Override
-    public void onSelectionRestored() {}
-
-    public void reset() {
-        mSelectionChanged = false;
-    }
-
-    public void assertSelectionChanged() {
-        assertTrue(mSelectionChanged);
-    }
-
-    public void assertSelectionUnchanged() {
-        assertFalse(mSelectionChanged);
-    }
-}
\ No newline at end of file
diff --git a/tests/common/com/android/documentsui/services/TestJob.java b/tests/common/com/android/documentsui/services/TestJob.java
index 3c4da22..10addeb 100644
--- a/tests/common/com/android/documentsui/services/TestJob.java
+++ b/tests/common/com/android/documentsui/services/TestJob.java
@@ -107,4 +107,8 @@
                 service.getString(android.R.string.cancel),
                 R.drawable.ic_cab_cancel);
     }
+
+    @Override
+    void finish() {
+    }
 }
diff --git a/tests/common/com/android/documentsui/testing/IntentAsserts.java b/tests/common/com/android/documentsui/testing/IntentAsserts.java
index 6fc1ae0..cbd6f38 100644
--- a/tests/common/com/android/documentsui/testing/IntentAsserts.java
+++ b/tests/common/com/android/documentsui/testing/IntentAsserts.java
@@ -40,6 +40,14 @@
         assertEquals(expected, intent.getAction());
     }
 
+    public static void assertTargetsComponent(Intent intent, Class<?> expected) {
+        assertEquals(expected.getName(), intent.getComponent().getClassName());
+    }
+
+    public static void assertHasExtra(Intent intent, String key) {
+        assertTrue(intent.getExtras().containsKey(key));
+    }
+
     public static Intent assertHasExtraIntent(Intent intent) {
         Intent extra = (Intent) intent.getExtra(EXTRA_INTENT);
         assertNotNull(extra);
@@ -64,4 +72,8 @@
         Assert.assertEquals(size, list.size());
         return list;
     }
+
+    public static void assertHasData(Intent intent, Uri expected) {
+        assertEquals(expected, intent.getData());
+    }
 }
diff --git a/tests/common/com/android/documentsui/testing/SelectionHelpers.java b/tests/common/com/android/documentsui/testing/SelectionHelpers.java
new file mode 100644
index 0000000..70bc44d
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/SelectionHelpers.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.testing;
+
+import com.android.documentsui.DocsSelectionHelper;
+import com.android.documentsui.dirlist.DocsStableIdProvider;
+import com.android.documentsui.dirlist.DocumentsAdapter;
+import com.android.documentsui.dirlist.TestDocumentsAdapter;
+import com.android.documentsui.selection.DefaultSelectionHelper;
+import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SelectionHelpers {
+
+    public static final SelectionPredicate CAN_SET_ANYTHING = new SelectionPredicate() {
+        @Override
+        public boolean canSetStateForId(String id, boolean nextState) {
+            return true;
+        }
+
+        @Override
+        public boolean canSetStateAtPosition(int position, boolean nextState) {
+            return true;
+        }
+    };
+
+    private SelectionHelpers() {}
+
+    public static DocsSelectionHelper createTestInstance() {
+        return createTestInstance(Collections.emptyList());
+    }
+
+    public static DocsSelectionHelper createTestInstance(List<String> docs) {
+        return createTestInstance(docs, DefaultSelectionHelper.MODE_MULTIPLE);
+    }
+
+    public static DocsSelectionHelper createTestInstance(
+            List<String> docs, @SelectionMode int mode) {
+        return createTestInstance(new TestDocumentsAdapter(docs), mode, CAN_SET_ANYTHING);
+    }
+
+    public static DocsSelectionHelper createTestInstance(
+            DocumentsAdapter adapter, @SelectionMode int mode, SelectionPredicate canSetState) {
+        DocsSelectionHelper manager = mode == DefaultSelectionHelper.MODE_SINGLE
+                ? DocsSelectionHelper.createSingleSelect()
+                : DocsSelectionHelper.createMultiSelect();
+
+        manager.reset(adapter, new DocsStableIdProvider(adapter), canSetState);
+
+        return manager;
+    }
+}
diff --git a/tests/common/com/android/documentsui/testing/SelectionManagers.java b/tests/common/com/android/documentsui/testing/SelectionManagers.java
deleted file mode 100644
index c4f29a0..0000000
--- a/tests/common/com/android/documentsui/testing/SelectionManagers.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.testing;
-
-import com.android.documentsui.dirlist.DocumentsAdapter;
-import com.android.documentsui.dirlist.TestDocumentsAdapter;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionManager.SelectionMode;
-import com.android.documentsui.selection.SelectionManager.SelectionPredicate;
-
-import java.util.Collections;
-import java.util.List;
-
-public class SelectionManagers {
-    private SelectionManagers() {}
-
-    public static SelectionManager createTestInstance() {
-        return createTestInstance(Collections.emptyList());
-    }
-
-    public static SelectionManager createTestInstance(List<String> docs) {
-        return createTestInstance(docs, SelectionManager.MODE_MULTIPLE);
-    }
-
-    public static SelectionManager createTestInstance(
-            List<String> docs, @SelectionMode int mode) {
-        return createTestInstance(
-                new TestDocumentsAdapter(docs),
-                mode,
-                (String id, boolean nextState) -> true);
-    }
-
-    public static SelectionManager createTestInstance(
-            DocumentsAdapter adapter, @SelectionMode int mode, SelectionPredicate canSetState) {
-        SelectionManager manager = new SelectionManager(mode);
-        manager.reset(adapter, canSetState);
-
-        return manager;
-    }
-}
diff --git a/tests/common/com/android/documentsui/testing/TestActionHandler.java b/tests/common/com/android/documentsui/testing/TestActionHandler.java
index 8353569..cd3fb1a 100644
--- a/tests/common/com/android/documentsui/testing/TestActionHandler.java
+++ b/tests/common/com/android/documentsui/testing/TestActionHandler.java
@@ -22,7 +22,7 @@
 import com.android.documentsui.TestActivity;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.dirlist.DocumentDetails;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 import java.util.function.Consumer;
 
@@ -30,7 +30,7 @@
 
     private final TestEnv mEnv;
 
-    public final TestEventHandler<DocumentDetails> open = new TestEventHandler<>();
+    public final TestEventHandler<ItemDetails> open = new TestEventHandler<>();
     public boolean mDeleteHappened;
 
     public DocumentInfo nextRootDocument;
@@ -53,7 +53,7 @@
     }
 
     @Override
-    public boolean openDocument(DocumentDetails doc, @ViewType int type, @ViewType int fallback) {
+    public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
         return open.accept(doc);
     }
 
diff --git a/tests/common/com/android/documentsui/testing/TestEnv.java b/tests/common/com/android/documentsui/testing/TestEnv.java
index 96ee0b7..40b5e0a 100644
--- a/tests/common/com/android/documentsui/testing/TestEnv.java
+++ b/tests/common/com/android/documentsui/testing/TestEnv.java
@@ -15,10 +15,12 @@
  */
 package com.android.documentsui.testing;
 
+import android.content.Context;
 import android.provider.DocumentsContract.Document;
 import android.support.test.InstrumentationRegistry;
 import android.test.mock.MockContentResolver;
 
+import com.android.documentsui.DocsSelectionHelper;
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
 import com.android.documentsui.archives.ArchivesProvider;
@@ -27,12 +29,9 @@
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.TestFocusHandler;
-import com.android.documentsui.selection.SelectionManager;
 import com.android.documentsui.sorting.SortModel;
 import com.android.documentsui.ui.TestDialogController;
 
-import junit.framework.Assert;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -49,6 +48,7 @@
     public static DocumentInfo FILE_JPG;
     public static DocumentInfo FILE_GIF;
     public static DocumentInfo FILE_PDF;
+    public static DocumentInfo FILE_MP4;
     public static DocumentInfo FILE_APK;
     public static DocumentInfo FILE_PARTIAL;
     public static DocumentInfo FILE_ARCHIVE;
@@ -64,29 +64,27 @@
     public final TestDialogController dialogs = new TestDialogController();
     public final TestModel model;
     public final TestModel archiveModel;
-    public final SelectionManager selectionMgr;
+    public final DocsSelectionHelper selectionMgr;
     public final TestSearchViewManager searchViewManager;
-    public final Injector injector;
+    public final Injector<?> injector;
     public final Features features;
 
     public final MockContentResolver contentResolver;
     public final Map<String, TestDocumentsProvider> mockProviders;
 
-    private TestEnv(String authority) {
+    private TestEnv(Context context, Features features, String authority) {
+        this.features = features;
         state.sortModel = SortModel.createModel();
         mExecutor = new TestScheduledExecutorService();
-        features = new Features.RuntimeFeatures(
-                InstrumentationRegistry.getInstrumentation().getTargetContext().getResources(),
-                null);
         model = new TestModel(authority, features);
         archiveModel = new TestModel(ArchivesProvider.AUTHORITY, features);
-        selectionMgr = SelectionManagers.createTestInstance();
+        selectionMgr = SelectionHelpers.createTestInstance();
         searchViewManager = new TestSearchViewManager();
         injector = new Injector(
                 features,
                 new TestActivityConfig(),
-                null,       //ScopedPreferences are not required for tests
-                null,   //a MessageBuilder is not required for tests
+                null,       // ScopedPreferences are not currently required for tests
+                null,       // MessageBuilder is not currently required for tests
                 dialogs,
                 new TestFileTypeLookup(),
                 (roots) -> {},  // not sure why, but java gets angry when I declare roots type.
@@ -111,12 +109,28 @@
         }
     }
 
+    // Many terrible creational permutations == easy to user for test authors!
+    public static TestEnv create(Features features) {
+        return create(features, TestProvidersAccess.HOME.authority);
+    }
+
     public static TestEnv create() {
         return create(TestProvidersAccess.HOME.authority);
     }
 
+    public static TestEnv create(Features features, String authority) {
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        return create(context, features, authority);
+    }
+
     public static TestEnv create(String authority) {
-        TestEnv env = new TestEnv(authority);
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        Features features = new Features.RuntimeFeatures(context.getResources(), null);
+        return create(context, features, authority);
+    }
+
+    private static TestEnv create(Context context, Features features, String authority) {
+        TestEnv env = new TestEnv(context, features, authority);
         env.reset();
         return env;
     }
@@ -136,6 +150,7 @@
         FILE_JPG = model.createFile("jiffy.jpg");
         FILE_GIF = model.createFile("glibby.gif");
         FILE_PDF = model.createFile("busy.pdf");
+        FILE_MP4 = model.createFile("cameravideo.mp4");
         FILE_APK = model.createFile("becareful.apk");
         FILE_PARTIAL = model.createFile(
                 "UbuntuFlappyBird.iso",
@@ -157,8 +172,11 @@
 
     public void populateStack() {
         DocumentInfo rootDoc = model.getDocument("1");
-        Assert.assertNotNull(rootDoc);
-        Assert.assertEquals(rootDoc.displayName, FOLDER_0.displayName);
+
+        // These are test setup sanity checks, not test assertions.
+        assert rootDoc != null;
+        assert rootDoc.isDirectory();
+        assert FOLDER_0.equals(rootDoc);
 
         state.stack.changeRoot(TestProvidersAccess.HOME);
         state.stack.push(rootDoc);
@@ -177,4 +195,21 @@
         ids.add(info.documentId);
         selectionMgr.setItemsSelected(ids, true);
     }
+
+    // Easily copy docs, so we don't pollute static data across tests.
+    public static DocumentInfo clone(DocumentInfo a) {
+        DocumentInfo b = new DocumentInfo();
+        b.authority = a.authority;
+        b.documentId = a.documentId;
+        b.mimeType = a.mimeType;
+        b.displayName = a.displayName;
+        b.lastModified = a.lastModified;
+        b.flags = a.flags;
+        b.summary = a.summary;
+        b.size = a.size;
+        b.icon = a.icon;
+        b.derivedUri = a.derivedUri;
+
+        return b;
+    }
 }
diff --git a/tests/common/com/android/documentsui/testing/TestEvent.java b/tests/common/com/android/documentsui/testing/TestEvent.java
deleted file mode 100644
index bc77211..0000000
--- a/tests/common/com/android/documentsui/testing/TestEvent.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.testing;
-
-import android.annotation.IntDef;
-import android.graphics.Point;
-import android.support.v7.widget.RecyclerView;
-import android.text.TextUtils;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.dirlist.DocumentDetails;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Events and DocDetails are closely related. For the pursposes of this test
- * we coalesce the two in a single, handy-dandy test class.
- */
-public class TestEvent implements InputEvent {
-    private static final int ACTION_UNSET = -1;
-
-    // Add other actions from MotionEvent.ACTION_ as needed.
-    @IntDef(flag = true, value = {
-            MotionEvent.ACTION_DOWN,
-            MotionEvent.ACTION_MOVE,
-            MotionEvent.ACTION_UP
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Action {}
-
-    // Add other types from MotionEvent.TOOL_TYPE_ as needed.
-    @IntDef(flag = true, value = {
-            MotionEvent.TOOL_TYPE_FINGER,
-            MotionEvent.TOOL_TYPE_MOUSE,
-            MotionEvent.TOOL_TYPE_STYLUS,
-            MotionEvent.TOOL_TYPE_UNKNOWN
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ToolType {}
-
-    @IntDef(flag = true, value = {
-            MotionEvent.BUTTON_PRIMARY,
-            MotionEvent.BUTTON_SECONDARY
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Button {}
-
-    @IntDef(flag = true, value = {
-            KeyEvent.META_SHIFT_ON,
-            KeyEvent.META_CTRL_ON
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Key {}
-
-    private @Action int mAction;
-    private @ToolType int mToolType;
-    private int mPointerCount;
-    private Set<Integer> mButtons;
-    private Set<Integer> mKeys;
-    private Point mLocation;
-    private Point mRawLocation;
-    private Details mDetails;
-
-    private TestEvent() {
-        mAction = ACTION_UNSET;  // somebody has to set this, else we'll barf later.
-        mToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
-        mButtons = new HashSet<>();
-        mKeys = new HashSet<>();
-        mLocation = new Point(0, 0);
-        mRawLocation = new Point(0, 0);
-        mDetails = new Details();
-        mPointerCount = 0;
-    }
-
-    private TestEvent(TestEvent source) {
-        assert(source.mAction != ACTION_UNSET);
-        mAction = source.mAction;
-        mToolType = source.mToolType;
-        mButtons = source.mButtons;
-        mKeys = source.mKeys;
-        mLocation = source.mLocation;
-        mRawLocation = source.mRawLocation;
-        mDetails = new Details(source.mDetails);
-        mPointerCount = source.mPointerCount;
-    }
-
-    @Override
-    public Point getOrigin() {
-        return mLocation;
-    }
-
-    @Override
-    public float getX() {
-        return mLocation.x;
-    }
-
-    @Override
-    public float getY() {
-        return mLocation.y;
-    }
-
-    @Override
-    public float getRawX() {
-        return mRawLocation.x;
-    }
-
-    @Override
-    public float getRawY() {
-        return mRawLocation.y;
-    }
-
-    @Override
-    public int getPointerCount() {
-        return mPointerCount;
-    }
-
-    @Override
-    public boolean isMouseEvent() {
-        return mToolType == MotionEvent.TOOL_TYPE_MOUSE;
-    }
-
-    @Override
-    public boolean isPrimaryButtonPressed() {
-        return mButtons.contains(MotionEvent.BUTTON_PRIMARY);
-    }
-
-    @Override
-    public boolean isSecondaryButtonPressed() {
-        return mButtons.contains(MotionEvent.BUTTON_SECONDARY);
-    }
-
-    @Override
-    public boolean isTertiaryButtonPressed() {
-        return mButtons.contains(MotionEvent.BUTTON_TERTIARY);
-    }
-
-    @Override
-    public boolean isShiftKeyDown() {
-        return mKeys.contains(KeyEvent.META_SHIFT_ON);
-    }
-
-    @Override
-    public boolean isCtrlKeyDown() {
-        return mKeys.contains(KeyEvent.META_CTRL_ON);
-    }
-
-    @Override
-    public boolean isAltKeyDown() {
-        return mKeys.contains(KeyEvent.META_ALT_ON);
-    }
-
-    @Override
-    public boolean isActionDown() {
-        return mAction == MotionEvent.ACTION_DOWN;
-    }
-
-    @Override
-    public boolean isActionUp() {
-        return mAction == MotionEvent.ACTION_UP;
-    }
-
-    @Override
-    public boolean isMultiPointerActionDown() {
-        return mAction == MotionEvent.ACTION_POINTER_DOWN;
-    }
-
-    @Override
-    public boolean isMultiPointerActionUp() {
-        return mAction == MotionEvent.ACTION_POINTER_UP;
-    }
-
-    @Override
-    public boolean isActionMove() {
-        return mAction == MotionEvent.ACTION_MOVE;
-    }
-
-    @Override
-    public boolean isActionCancel() {
-        return mAction == MotionEvent.ACTION_CANCEL;
-    }
-
-    @Override
-    public boolean isOverItem() {
-        return mDetails.isOverItem();
-    }
-
-    @Override
-    public boolean isOverDocIcon() {
-        return mDetails.isOverDocIcon(this);
-    }
-
-    @Override
-    public boolean isOverDragHotspot() {
-        return isOverItem() && mDetails.isInDragHotspot(this);
-    }
-
-    @Override
-    public boolean isOverModelItem() {
-        if (isOverItem()) {
-            DocumentDetails doc = getDocumentDetails();
-            return doc != null && doc.hasModelId();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isTouchpadScroll() {
-        return isMouseEvent() && mButtons.isEmpty() && isActionMove();
-    }
-
-    @Override
-    public int getItemPosition() {
-        return mDetails.mPosition;
-    }
-
-    @Override
-    public DocumentDetails getDocumentDetails() {
-        return mDetails;
-    }
-
-    @Override
-    public void close() {}
-
-    @Override
-    public int hashCode() {
-        return mDetails.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) {
-          return true;
-      }
-
-      if (!(o instanceof TestEvent)) {
-          return false;
-      }
-
-      TestEvent other = (TestEvent) o;
-      return mAction == other.mAction
-              && mToolType == other.mToolType
-              && mButtons.equals(other.mButtons)
-              && mKeys.equals(other.mKeys)
-              && mLocation.equals(other.mLocation)
-              && mRawLocation.equals(other.mRawLocation)
-              && mDetails.equals(other.mDetails);
-    }
-
-    private static final class Details implements DocumentDetails {
-
-        private int mPosition;
-        private String mModelId;
-        private boolean mInSelectionHotspot;
-        private boolean mInDragHotspot;
-        private boolean mOverDocIcon;
-
-        public Details() {
-           mPosition = Integer.MIN_VALUE;
-        }
-
-        public Details(Details source) {
-            mPosition = source.mPosition;
-            mModelId = source.mModelId;
-            mInSelectionHotspot = source.mInSelectionHotspot;
-            mInDragHotspot = source.mInDragHotspot;
-            mOverDocIcon = source.mOverDocIcon;
-        }
-
-
-        private boolean isOverItem() {
-            return mPosition != Integer.MIN_VALUE && mPosition != RecyclerView.NO_POSITION;
-        }
-
-        @Override
-        public boolean hasModelId() {
-            return !TextUtils.isEmpty(mModelId);
-        }
-
-        @Override
-        public String getModelId() {
-            return mModelId;
-        }
-
-        @Override
-        public int getAdapterPosition() {
-            return mPosition;
-        }
-
-        @Override
-        public boolean isInSelectionHotspot(InputEvent event) {
-            return mInSelectionHotspot;
-        }
-
-        @Override
-        public boolean isInDragHotspot(InputEvent event) {
-            return mInDragHotspot;
-        }
-
-        @Override
-        public boolean isOverDocIcon(InputEvent event) {
-            return mOverDocIcon;
-        }
-
-        @Override
-        public int hashCode() {
-            return mModelId != null ? mModelId.hashCode() : ACTION_UNSET;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-          if (this == o) {
-              return true;
-          }
-
-          if (!(o instanceof Details)) {
-              return false;
-          }
-
-          Details other = (Details) o;
-          return mPosition == other.mPosition
-                  && mModelId == other.mModelId;
-        }
-    }
-
-    public static final Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Test event builder with convenience methods for common event attrs.
-     */
-    public static final class Builder {
-
-        private TestEvent mState = new TestEvent();
-
-        public Builder() {
-        }
-
-        public Builder(TestEvent state) {
-            mState = new TestEvent(state);
-        }
-
-        /**
-         * @param action Any action specified in {@link MotionEvent}.
-         * @return
-         */
-        public Builder action(int action) {
-            mState.mAction = action;
-            return this;
-        }
-
-        public Builder type(@ToolType int type) {
-            mState.mToolType = type;
-            return this;
-        }
-
-        public Builder location(int x, int y) {
-            mState.mLocation = new Point(x, y);
-            return this;
-        }
-
-        public Builder rawLocation(int x, int y) {
-            mState.mRawLocation = new Point(x, y);
-            return this;
-        }
-
-        public Builder pointerCount(int count) {
-            mState.mPointerCount = count;
-            return this;
-        }
-
-        /**
-         * Adds one or more button press attributes.
-         */
-        public Builder pressButton(@Button int... buttons) {
-            for (int button : buttons) {
-                mState.mButtons.add(button);
-            }
-            return this;
-        }
-
-        /**
-         * Removes one or more button press attributes.
-         */
-        public Builder releaseButton(@Button int... buttons) {
-            for (int button : buttons) {
-                mState.mButtons.remove(button);
-            }
-            return this;
-        }
-
-        /**
-         * Adds one or more key press attributes.
-         */
-        public Builder pressKey(@Key int... keys) {
-            for (int key : keys) {
-                mState.mKeys.add(key);
-            }
-            return this;
-        }
-
-        /**
-         * Removes one or more key press attributes.
-         */
-        public Builder releaseKey(@Button int... keys) {
-            for (int key : keys) {
-                mState.mKeys.remove(key);
-            }
-            return this;
-        }
-
-        public Builder at(int position) {
-            mState.mDetails.mPosition = position;  // this is both "adapter position" and "item position".
-            mState.mDetails.mModelId = String.valueOf(position);
-            return this;
-        }
-
-        public Builder inSelectionHotspot() {
-            mState.mDetails.mInSelectionHotspot = true;
-            return this;
-        }
-
-        public Builder inDragHotspot() {
-            mState.mDetails.mInDragHotspot = true;
-            return this;
-        }
-
-        public Builder notInDragHotspot() {
-            mState.mDetails.mInDragHotspot = false;
-            return this;
-        }
-
-        public Builder overDocIcon() {
-            mState.mDetails.mOverDocIcon = true;
-            return this;
-        }
-
-        public Builder notOverDocIcon() {
-            mState.mDetails.mOverDocIcon = false;
-            return this;
-        }
-
-        public Builder touch() {
-            type(MotionEvent.TOOL_TYPE_FINGER);
-            return this;
-        }
-
-        public Builder mouse() {
-            type(MotionEvent.TOOL_TYPE_MOUSE);
-            return this;
-        }
-
-        public Builder shift() {
-            pressKey(KeyEvent.META_SHIFT_ON);
-            return this;
-        }
-
-        /**
-         * Use {@link #remove(@Attribute int...)}
-         */
-        @Deprecated
-        public Builder unshift() {
-            releaseKey(KeyEvent.META_SHIFT_ON);
-            return this;
-        }
-
-        public Builder ctrl() {
-            pressKey(KeyEvent.META_CTRL_ON);
-            return this;
-        }
-
-        public Builder alt() {
-            pressKey(KeyEvent.META_ALT_ON);
-            return this;
-        }
-
-        public Builder primary() {
-            pressButton(MotionEvent.BUTTON_PRIMARY);
-            releaseButton(MotionEvent.BUTTON_SECONDARY);
-            releaseButton(MotionEvent.BUTTON_TERTIARY);
-            return this;
-        }
-
-        public Builder secondary() {
-            pressButton(MotionEvent.BUTTON_SECONDARY);
-            releaseButton(MotionEvent.BUTTON_PRIMARY);
-            releaseButton(MotionEvent.BUTTON_TERTIARY);
-            return this;
-        }
-
-        public Builder tertiary() {
-            pressButton(MotionEvent.BUTTON_TERTIARY);
-            releaseButton(MotionEvent.BUTTON_PRIMARY);
-            releaseButton(MotionEvent.BUTTON_SECONDARY);
-            return this;
-        }
-
-        public Builder reset() {
-            mState = new TestEvent();
-            return this;
-        }
-
-        @Override
-        public Builder clone() {
-            return new Builder(build());
-        }
-
-        public TestEvent build() {
-            // Return a copy, so nobody can mess w/ our internal state.
-            return new TestEvent(mState);
-        }
-    }
-}
diff --git a/tests/common/com/android/documentsui/testing/TestEvents.java b/tests/common/com/android/documentsui/testing/TestEvents.java
new file mode 100644
index 0000000..9aab9e8
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestEvents.java
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.testing;
+
+import android.annotation.IntDef;
+import android.graphics.Point;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Handy-dandy wrapper class to facilitate the creation of MotionEvents.
+ */
+public final class TestEvents {
+
+    /**
+     * Common mouse event types...for your convenience.
+     */
+    public static final class Mouse {
+        public static final MotionEvent CLICK =
+                TestEvents.builder().mouse().primary().build();
+        public static final MotionEvent CTRL_CLICK =
+                TestEvents.builder().mouse().primary().ctrl().build();
+        public static final MotionEvent ALT_CLICK =
+                TestEvents.builder().mouse().primary().alt().build();
+        public static final MotionEvent SHIFT_CLICK =
+                TestEvents.builder().mouse().primary().shift().build();
+        public static final MotionEvent SECONDARY_CLICK =
+                TestEvents.builder().mouse().secondary().build();
+        public static final MotionEvent TERTIARY_CLICK =
+                TestEvents.builder().mouse().tertiary().build();
+    }
+
+    /**
+     * Common touch event types...for your convenience.
+     */
+    public static final class Touch {
+        public static final MotionEvent TAP =
+                TestEvents.builder().touch().build();
+    }
+
+    static final int ACTION_UNSET = -1;
+
+    // Add other actions from MotionEvent.ACTION_ as needed.
+    @IntDef(flag = true, value = {
+            MotionEvent.ACTION_DOWN,
+            MotionEvent.ACTION_MOVE,
+            MotionEvent.ACTION_UP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Action {}
+
+    // Add other types from MotionEvent.TOOL_TYPE_ as needed.
+    @IntDef(flag = true, value = {
+            MotionEvent.TOOL_TYPE_FINGER,
+            MotionEvent.TOOL_TYPE_MOUSE,
+            MotionEvent.TOOL_TYPE_STYLUS,
+            MotionEvent.TOOL_TYPE_UNKNOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ToolType {}
+
+    @IntDef(flag = true, value = {
+            MotionEvent.BUTTON_PRIMARY,
+            MotionEvent.BUTTON_SECONDARY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Button {}
+
+    @IntDef(flag = true, value = {
+            KeyEvent.META_SHIFT_ON,
+            KeyEvent.META_CTRL_ON
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Key {}
+
+    private static final class State {
+        private @Action int mAction = ACTION_UNSET;
+        private @ToolType int mToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
+        private int mPointerCount = 1;
+        private Set<Integer> mButtons = new HashSet<>();
+        private Set<Integer> mKeys = new HashSet<>();
+        private Point mLocation = new Point(0, 0);
+        private Point mRawLocation = new Point(0, 0);
+    }
+
+    public static final Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Test event builder with convenience methods for common event attrs.
+     */
+    public static final class Builder {
+
+        private State mState = new State();
+
+        /**
+         * @param action Any action specified in {@link MotionEvent}.
+         * @return
+         */
+        public Builder action(int action) {
+            mState.mAction = action;
+            return this;
+        }
+
+        public Builder type(@ToolType int type) {
+            mState.mToolType = type;
+            return this;
+        }
+
+        public Builder location(int x, int y) {
+            mState.mLocation = new Point(x, y);
+            return this;
+        }
+
+        public Builder rawLocation(int x, int y) {
+            mState.mRawLocation = new Point(x, y);
+            return this;
+        }
+
+        public Builder pointerCount(int count) {
+            mState.mPointerCount = count;
+            return this;
+        }
+
+        /**
+         * Adds one or more button press attributes.
+         */
+        public Builder pressButton(@Button int... buttons) {
+            for (int button : buttons) {
+                mState.mButtons.add(button);
+            }
+            return this;
+        }
+
+        /**
+         * Removes one or more button press attributes.
+         */
+        public Builder releaseButton(@Button int... buttons) {
+            for (int button : buttons) {
+                mState.mButtons.remove(button);
+            }
+            return this;
+        }
+
+        /**
+         * Adds one or more key press attributes.
+         */
+        public Builder pressKey(@Key int... keys) {
+            for (int key : keys) {
+                mState.mKeys.add(key);
+            }
+            return this;
+        }
+
+        /**
+         * Removes one or more key press attributes.
+         */
+        public Builder releaseKey(@Button int... keys) {
+            for (int key : keys) {
+                mState.mKeys.remove(key);
+            }
+            return this;
+        }
+
+        public Builder touch() {
+            type(MotionEvent.TOOL_TYPE_FINGER);
+            return this;
+        }
+
+        public Builder mouse() {
+            type(MotionEvent.TOOL_TYPE_MOUSE);
+            return this;
+        }
+
+        public Builder shift() {
+            pressKey(KeyEvent.META_SHIFT_ON);
+            return this;
+        }
+
+        /**
+         * Use {@link #remove(@Attribute int...)}
+         */
+        public Builder unshift() {
+            releaseKey(KeyEvent.META_SHIFT_ON);
+            return this;
+        }
+
+        public Builder ctrl() {
+            pressKey(KeyEvent.META_CTRL_ON);
+            return this;
+        }
+
+        public Builder alt() {
+            pressKey(KeyEvent.META_ALT_ON);
+            return this;
+        }
+
+        public Builder primary() {
+            pressButton(MotionEvent.BUTTON_PRIMARY);
+            releaseButton(MotionEvent.BUTTON_SECONDARY);
+            releaseButton(MotionEvent.BUTTON_TERTIARY);
+            return this;
+        }
+
+        public Builder secondary() {
+            pressButton(MotionEvent.BUTTON_SECONDARY);
+            releaseButton(MotionEvent.BUTTON_PRIMARY);
+            releaseButton(MotionEvent.BUTTON_TERTIARY);
+            return this;
+        }
+
+        public Builder tertiary() {
+            pressButton(MotionEvent.BUTTON_TERTIARY);
+            releaseButton(MotionEvent.BUTTON_PRIMARY);
+            releaseButton(MotionEvent.BUTTON_SECONDARY);
+            return this;
+        }
+
+        public MotionEvent build() {
+
+            PointerProperties[] pointers = new PointerProperties[1];
+            pointers[0] = new PointerProperties();
+            pointers[0].id = 0;
+            pointers[0].toolType = mState.mToolType;
+
+            PointerCoords[] coords = new PointerCoords[1];
+            coords[0] = new PointerCoords();
+            coords[0].x = mState.mLocation.x;
+            coords[0].y = mState.mLocation.y;
+
+            int buttons = 0;
+            for (Integer button : mState.mButtons) {
+                buttons |= button;
+            }
+
+            int keys = 0;
+            for (Integer key : mState.mKeys) {
+                keys |= key;
+            }
+
+            return MotionEvent.obtain(
+                    0,     // down time
+                    1,     // event time
+                    mState.mAction,
+                    1,  // pointerCount,
+                    pointers,
+                    coords,
+                    keys,
+                    buttons,
+                    1.0f,  // x precision
+                    1.0f,  // y precision
+                    0,     // device id
+                    0,     // edge flags
+                    0,     // int source,
+                    0      // int flags
+                    );
+        }
+    }
+}
diff --git a/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java b/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java
new file mode 100644
index 0000000..f883e5e
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.testing;
+
+import android.content.Context;
+import android.support.v7.widget.GridLayoutManager;
+
+import org.mockito.Mockito;
+
+public class TestGridLayoutManager extends GridLayoutManager {
+
+    private int mFirstVisibleItemPosition;
+
+    public static TestGridLayoutManager create() {
+        final TestGridLayoutManager manager = Mockito.mock(TestGridLayoutManager.class,
+                Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
+        return manager;
+    }
+
+    @Override
+    public int findFirstVisibleItemPosition() { return mFirstVisibleItemPosition; }
+
+    public void setFirstVisibleItemPosition(int position) { mFirstVisibleItemPosition = position; }
+
+    private TestGridLayoutManager(Context context, int spanCount) {
+        super(context, spanCount);
+    }
+}
diff --git a/tests/common/com/android/documentsui/testing/TestMenu.java b/tests/common/com/android/documentsui/testing/TestMenu.java
index 9df06d9..6a46668 100644
--- a/tests/common/com/android/documentsui/testing/TestMenu.java
+++ b/tests/common/com/android/documentsui/testing/TestMenu.java
@@ -18,6 +18,7 @@
 
 import android.util.SparseArray;
 import android.view.Menu;
+import android.widget.SearchView;
 
 import com.android.documentsui.R;
 
@@ -48,8 +49,9 @@
                 R.id.dir_menu_rename,
                 R.id.dir_menu_delete,
                 R.id.dir_menu_view_in_owner,
-                R.id.dir_menu_open_in_new_window,
                 R.id.dir_menu_paste_into_folder,
+                R.id.dir_menu_inspect,
+                R.id.dir_menu_open_in_new_window,
                 R.id.root_menu_eject_root,
                 R.id.root_menu_open_in_new_window,
                 R.id.root_menu_paste_into_folder,
@@ -64,7 +66,7 @@
                 R.id.action_menu_move_to,
                 R.id.action_menu_compress,
                 R.id.action_menu_rename,
-                R.id.action_menu_inspector,
+                R.id.action_menu_inspect,
                 R.id.action_menu_view_in_owner,
                 R.id.option_menu_search,
                 R.id.option_menu_debug,
@@ -74,7 +76,8 @@
                 R.id.option_menu_create_dir,
                 R.id.option_menu_select_all,
                 R.id.option_menu_advanced,
-                R.id.option_menu_settings);
+                R.id.option_menu_settings,
+                R.id.option_menu_inspect);
     }
 
 
@@ -86,6 +89,11 @@
         for (int id : ids) {
             TestMenuItem item = TestMenuItem.create(id);
             menu.addMenuItem(id, item);
+
+            // Used by SearchViewManager
+            if (id == R.id.option_menu_search) {
+                item.setActionView(Mockito.mock(SearchView.class));
+            }
         }
         return menu;
     }
diff --git a/tests/common/com/android/documentsui/testing/TestMenuItem.java b/tests/common/com/android/documentsui/testing/TestMenuItem.java
index a955adc..9f4df28 100644
--- a/tests/common/com/android/documentsui/testing/TestMenuItem.java
+++ b/tests/common/com/android/documentsui/testing/TestMenuItem.java
@@ -21,6 +21,7 @@
 
 import android.annotation.StringRes;
 import android.view.MenuItem;
+import android.view.View;
 
 import org.mockito.Mockito;
 
@@ -37,6 +38,7 @@
 
     boolean enabled;
     boolean visible;
+    View actionView;
     @StringRes int title;
 
     public static TestMenuItem create(int id) {
@@ -83,6 +85,17 @@
         return this.enabled;
     }
 
+    @Override
+    final public MenuItem setActionView(View actionView) {
+        this.actionView = actionView;
+        return this;
+    }
+
+    @Override
+    final public View getActionView() {
+        return this.actionView;
+    }
+
     public void assertEnabled() {
         assertTrue(this.enabled);
     }
diff --git a/tests/common/com/android/documentsui/testing/TestModel.java b/tests/common/com/android/documentsui/testing/TestModel.java
index 517b1f4..0df9b3a 100644
--- a/tests/common/com/android/documentsui/testing/TestModel.java
+++ b/tests/common/com/android/documentsui/testing/TestModel.java
@@ -53,6 +53,7 @@
         reset();
     }
 
+    @Override
     public void reset() {
         mLastId = 0;
         mCursor = new MatrixCursor(COLUMNS);
diff --git a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java
index abe95d1..248bb53 100644
--- a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java
+++ b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java
@@ -16,6 +16,7 @@
 package com.android.documentsui.testing;
 
 import android.provider.DocumentsContract.Root;
+
 import com.android.documentsui.InspectorProvider;
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.RootInfo;
@@ -45,6 +46,7 @@
         }};
         DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS;
         DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS;
+        DOWNLOADS.title = "Downloads";
         DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY
                 | Root.FLAG_SUPPORTS_CREATE
                 | Root.FLAG_SUPPORTS_IS_CHILD
@@ -53,6 +55,7 @@
         HOME = new RootInfo();
         HOME.authority = Providers.AUTHORITY_STORAGE;
         HOME.rootId = Providers.ROOT_ID_HOME;
+        HOME.title = "Home";
         HOME.flags = Root.FLAG_LOCAL_ONLY
                 | Root.FLAG_SUPPORTS_CREATE
                 | Root.FLAG_SUPPORTS_IS_CHILD
@@ -61,10 +64,12 @@
         HAMMY = new RootInfo();
         HAMMY.authority = "yummies";
         HAMMY.rootId = "hamsandwich";
+        HAMMY.title = "Ham Sandwich";
 
         PICKLES = new RootInfo();
         PICKLES.authority = "yummies";
         PICKLES.rootId = "pickles";
+        PICKLES.title = "Pickles";
 
         RECENTS = new RootInfo() {{
             // Special root for recents
@@ -72,10 +77,12 @@
             flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD;
             availableBytes = -1;
         }};
+        RECENTS.title = "Recents";
 
         INSPECTOR = new RootInfo();
         INSPECTOR.authority = InspectorProvider.AUTHORITY;
         INSPECTOR.rootId = InspectorProvider.ROOT_ID;
+        INSPECTOR.title = "Inspector";
         INSPECTOR.flags = Root.FLAG_LOCAL_ONLY
             | Root.FLAG_SUPPORTS_CREATE;
     }
diff --git a/tests/common/com/android/documentsui/testing/TestRecyclerView.java b/tests/common/com/android/documentsui/testing/TestRecyclerView.java
index 8759a9a..a1f8e7f 100644
--- a/tests/common/com/android/documentsui/testing/TestRecyclerView.java
+++ b/tests/common/com/android/documentsui/testing/TestRecyclerView.java
@@ -17,6 +17,7 @@
 package com.android.documentsui.testing;
 
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
 
@@ -32,6 +33,7 @@
 
     private List<RecyclerView.ViewHolder> holders = new ArrayList<>();
     private TestDocumentsAdapter adapter;
+    private RecyclerView.LayoutManager mLayoutManager;
 
     public TestRecyclerView(Context context) {
         super(context);
@@ -55,6 +57,16 @@
         return adapter;
     }
 
+    @Override
+    public void setLayoutManager(LayoutManager manager) {
+        mLayoutManager = manager;
+    }
+
+    @Override
+    public RecyclerView.LayoutManager getLayoutManager() {
+        return mLayoutManager;
+    }
+
     public void setItems(List<String> modelIds) {
         holders = new ArrayList<>();
         for (String modelId: modelIds) {
@@ -64,8 +76,8 @@
     }
 
     public static TestRecyclerView create(List<String> modelIds) {
-        final TestRecyclerView view = Mockito.mock(TestRecyclerView.class,
-                Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
+        final TestRecyclerView view =
+                new TestRecyclerView(InstrumentationRegistry.getTargetContext());
         view.holders = new ArrayList<>();
         for (String modelId: modelIds) {
             view.holders.add(new TestViewHolder(Views.createTestView()));
diff --git a/tests/common/com/android/documentsui/testing/TestResources.java b/tests/common/com/android/documentsui/testing/TestResources.java
index 907d923..0bd21de 100644
--- a/tests/common/com/android/documentsui/testing/TestResources.java
+++ b/tests/common/com/android/documentsui/testing/TestResources.java
@@ -85,10 +85,12 @@
         return strings.get(id);
     }
 
+    @Override
     @NonNull
     public final String getString(
             @StringRes int id, Object... formatArgs) throws NotFoundException {
-        return getString(id);
+        final String raw = getString(id);
+        return String.format(raw, formatArgs);
     }
 
     @Override
@@ -106,6 +108,7 @@
         return null;
     }
 
+    @Override
     public final CharSequence getText(@StringRes int resId) {
         return getString(resId);
     }
diff --git a/tests/common/com/android/documentsui/testing/TestTimer.java b/tests/common/com/android/documentsui/testing/TestTimer.java
index e1a6610..89efb96 100644
--- a/tests/common/com/android/documentsui/testing/TestTimer.java
+++ b/tests/common/com/android/documentsui/testing/TestTimer.java
@@ -16,6 +16,7 @@
 
 package com.android.documentsui.testing;
 
+import java.lang.IllegalStateException;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -28,6 +29,7 @@
  */
 public class TestTimer extends Timer {
 
+    private boolean mIsCancelled;
     private long mNow = 0;
 
     private final LinkedList<Task> mTaskList = new LinkedList<>();
@@ -64,6 +66,7 @@
 
     @Override
     public void cancel() {
+        mIsCancelled = true;
         mTaskList.clear();
     }
 
@@ -114,6 +117,9 @@
     }
 
     public void scheduleAtTime(TimerTask task, long executeTime) {
+        if (mIsCancelled) {
+            throw new IllegalStateException("Timer already cancelled.");
+        }
         Task testTimerTask = (Task) task;
         testTimerTask.mExecuteTime = executeTime;
 
diff --git a/tests/functional/com/android/documentsui/FilesActivityUiTest.java b/tests/functional/com/android/documentsui/FilesActivityUiTest.java
index 87f3bac..90b6dd3 100644
--- a/tests/functional/com/android/documentsui/FilesActivityUiTest.java
+++ b/tests/functional/com/android/documentsui/FilesActivityUiTest.java
@@ -118,7 +118,7 @@
         Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
                 InspectorActivity.class.getName(), null, false);
         bots.directory.selectDocument("file0.log");
-        bots.main.clickActionItem("Properties");
+        bots.main.clickActionItem("Get info");
         monitor.waitForActivityWithTimeout(TIMEOUT);
     }
 
diff --git a/tests/functional/com/android/documentsui/InspectorUiTest.java b/tests/functional/com/android/documentsui/InspectorUiTest.java
index 724ba1d..a228de2 100644
--- a/tests/functional/com/android/documentsui/InspectorUiTest.java
+++ b/tests/functional/com/android/documentsui/InspectorUiTest.java
@@ -18,10 +18,12 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.provider.DocumentsContract;
+import android.support.test.filters.LargeTest;
 
 import com.android.documentsui.bots.UiBot;
 import com.android.documentsui.inspector.InspectorActivity;
 
+@LargeTest
 public class InspectorUiTest extends ActivityTest<InspectorActivity> {
 
     private static final String TEST_DOC_NAME = "test.txt";
@@ -56,11 +58,17 @@
         bots.inspector.assertTitle("test.txt");
     }
 
-    public void testDisplayFileType() throws Exception {
+    public void testFolderDetails() throws Exception {
         if (!features.isInspectorEnabled()) {
             return;
         }
-        bots.inspector.assertRowPresent(getActivity().getString(R.string.sort_dimension_file_type),
-                "vnd.android.document/directory", getActivity());
+        bots.inspector.assertRowEquals(
+                getActivity().getString(R.string.sort_dimension_file_type),
+                "Folder",
+                getActivity());
+        bots.inspector.assertRowEquals(
+                getActivity().getString(R.string.directory_items),
+                "4",
+                getActivity());
     }
 }
diff --git a/tests/res/raw/images.zip b/tests/res/raw/images.zip
new file mode 100644
index 0000000..b3013e9
--- /dev/null
+++ b/tests/res/raw/images.zip
Binary files differ
diff --git a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
index e094078..d9c5517 100644
--- a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
@@ -17,7 +17,7 @@
 package com.android.documentsui;
 
 import static junit.framework.Assert.assertTrue;
-
+import static junit.framework.Assert.fail;
 import static org.junit.Assert.assertEquals;
 
 import android.content.Intent;
@@ -31,8 +31,8 @@
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
-import com.android.documentsui.dirlist.DocumentDetails;
 import com.android.documentsui.files.LauncherActivity;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.sorting.SortDimension;
 import com.android.documentsui.sorting.SortModel;
 import com.android.documentsui.testing.DocumentStackAsserts;
@@ -77,8 +77,7 @@
             }
 
             @Override
-            public boolean openDocument(DocumentDetails doc, @ViewType int type,
-                    @ViewType int fallback) {
+            public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
                 throw new UnsupportedOperationException();
             }
 
@@ -106,7 +105,8 @@
     }
 
     @Test
-    public void testOpensContainerDocuments_jumpToNewLocation() throws Exception {
+    public void testOpensContainerDocuments_OpenFolderInSearch_JumpsToNewLocation()
+            throws Exception {
         if (!mEnv.features.isLaunchToDocumentEnabled()) {
             return;
         }
@@ -114,6 +114,7 @@
         mEnv.populateStack();
 
         mEnv.searchViewManager.isSearching = true;
+        mEnv.docs.nextIsDocumentsUri = true;
         mEnv.docs.nextPath = new Path(
                 TestProvidersAccess.HOME.rootId,
                 Arrays.asList(TestEnv.FOLDER_1.documentId, TestEnv.FOLDER_2.documentId));
@@ -124,15 +125,18 @@
         mEnv.beforeAsserts();
 
         assertEquals(mEnv.docs.nextPath.getPath().size(), mEnv.state.stack.size());
-        assertEquals(TestEnv.FOLDER_2, mEnv.state.stack.peek());
+        assertEquals(TestEnv.FOLDER_2, mEnv.state.stack.pop());
+        assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.pop());
     }
 
 
     @Test
-    public void testOpensContainerDocuments_pushToRootDoc_NoFindPathSupport() throws Exception {
+    public void testOpensContainerDocuments_ClickFolderInSearch_PushToRootDoc_NoFindPathSupport()
+            throws Exception {
         mEnv.populateStack();
 
         mEnv.searchViewManager.isSearching = true;
+        mEnv.docs.nextIsDocumentsUri = true;
         mEnv.docs.nextDocuments = Arrays.asList(TestEnv.FOLDER_1, TestEnv.FOLDER_2);
 
         mHandler.openContainerDocument(TestEnv.FOLDER_2);
@@ -145,15 +149,42 @@
     }
 
     @Test
-    public void testOpensDocument_AssertionErrorIfAlreadyInStack() throws Exception {
+    public void testOpensContainerDocuments_ClickArchiveInSearch_opensArchiveInArchiveProvider()
+            throws Exception {
+        if (!mEnv.features.isLaunchToDocumentEnabled()) {
+            return;
+        }
+
         mEnv.populateStack();
-        boolean threw = false;
+
+        mEnv.searchViewManager.isSearching = true;
+        mEnv.docs.nextIsDocumentsUri = true;
+        mEnv.docs.nextPath = new Path(
+                TestProvidersAccess.HOME.rootId,
+                Arrays.asList(TestEnv.FOLDER_1.documentId, TestEnv.FOLDER_2.documentId,
+                        TestEnv.FILE_ARCHIVE.documentId));
+        mEnv.docs.nextDocuments = Arrays.asList(
+                TestEnv.FOLDER_1, TestEnv.FOLDER_2, TestEnv.FILE_ARCHIVE);
+        mEnv.docs.nextDocument = TestEnv.FILE_IN_ARCHIVE;
+
+        mHandler.openContainerDocument(TestEnv.FILE_ARCHIVE);
+
+        mEnv.beforeAsserts();
+
+        assertEquals(mEnv.docs.nextPath.getPath().size(), mEnv.state.stack.size());
+        assertEquals(TestEnv.FILE_IN_ARCHIVE, mEnv.state.stack.pop());
+        assertEquals(TestEnv.FOLDER_2, mEnv.state.stack.pop());
+        assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.pop());
+    }
+
+    @Test
+    public void testOpensDocument_ExceptionIfAlreadyInStack() throws Exception {
+        mEnv.populateStack();
         try {
             mEnv.state.stack.push(TestEnv.FOLDER_0);
-        } catch (AssertionError e) {
-            threw = true;
+            fail("Should have thrown IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
         }
-        assertTrue(threw);
     }
 
     @Test
diff --git a/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java b/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java
new file mode 100644
index 0000000..845a5da
--- /dev/null
+++ b/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView.Adapter;
+
+import com.android.documentsui.DocsSelectionHelper.DelegateFactory;
+import com.android.documentsui.selection.DefaultSelectionHelper;
+import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for the specialized behaviors provided by DocsSelectionManager.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DocsSelectionHelperTest {
+
+    private DocsSelectionHelper mSelectionMgr;
+    private List<TestSelectionManager> mCreated;
+    private DelegateFactory mFactory;
+
+    @Before
+    public void setup() {
+        mCreated = new ArrayList<>();
+        mFactory = new DelegateFactory() {
+            @Override
+            TestSelectionManager create(
+                    int mode,
+                    Adapter<?> adapter,
+                    StableIdProvider stableIds,
+                    SelectionPredicate canSetState) {
+
+                TestSelectionManager mgr = new TestSelectionManager();
+                mCreated.add(mgr);
+                return mgr;
+            }
+        };
+
+        mSelectionMgr = new DocsSelectionHelper(mFactory, DefaultSelectionHelper.MODE_MULTIPLE);
+    }
+
+    @Test
+    public void testReset_CreatesNewInstances() {
+        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+
+        assertCreated(2);
+    }
+
+    @Test
+    public void testReset_ClearsPreviousSelection() {
+        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+
+        mCreated.get(0).assertCleared(true);
+        mCreated.get(1).assertCleared(false);
+    }
+
+    @Test
+    public void testReplaceSelection() {
+        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+
+        List<String> ids = new ArrayList<>();
+        ids.add("poodles");
+        ids.add("hammy");
+        mSelectionMgr.replaceSelection(ids);
+        mCreated.get(0).assertCleared(true);
+        mCreated.get(0).assertSelected("poodles", "hammy");
+    }
+
+    void assertCreated(int count) {
+        assertEquals(count, mCreated.size());
+    }
+
+    private static final class TestSelectionManager extends SelectionHelper {
+
+        private boolean mCleared;
+        private Map<String, Boolean> mSelected = new HashMap<>();
+
+        void assertCleared(boolean expected) {
+            assertEquals(expected, mCleared);
+        }
+
+        void assertSelected(String... expected) {
+            for (String id : expected) {
+                assertTrue(mSelected.containsKey(id));
+                assertTrue(mSelected.get(id));
+            }
+            assertEquals(expected.length, mSelected.size());
+        }
+
+        @Override
+        public void addObserver(SelectionObserver listener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean hasSelection() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Selection getSelection() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void copySelection(Selection dest) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isSelected(String id) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void restoreSelection(Selection other) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
+            for (String id : ids) {
+                mSelected.put(id, selected);
+            }
+            return true;
+        }
+
+        @Override
+        public void clearSelection() {
+            mCleared = true;
+        }
+
+        @Override
+        public boolean select(String itemId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean deselect(String itemId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void startRange(int pos) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void extendRange(int pos) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void endRange() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isRangeActive() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void anchorRange(int position) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void extendProvisionalRange(int pos) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void clearProvisionalSelection() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void mergeProvisionalSelection() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setProvisionalSelection(Set<String> newSelection) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/tests/unit/com/android/documentsui/FocusManagerTest.java b/tests/unit/com/android/documentsui/FocusManagerTest.java
index d4d7648..b386f82 100644
--- a/tests/unit/com/android/documentsui/FocusManagerTest.java
+++ b/tests/unit/com/android/documentsui/FocusManagerTest.java
@@ -16,15 +16,17 @@
 
 package com.android.documentsui;
 
+import android.support.v7.widget.RecyclerView;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.documentsui.base.Features;
 import com.android.documentsui.dirlist.TestData;
+import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.testing.TestModel;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.testing.SelectionManagers;
+import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestFeatures;
+import com.android.documentsui.testing.TestGridLayoutManager;
 import com.android.documentsui.testing.TestRecyclerView;
 
 import java.util.ArrayList;
@@ -39,13 +41,17 @@
 
     private FocusManager mManager;
     private TestRecyclerView mView;
-    private SelectionManager mSelectionMgr;
+    private TestGridLayoutManager mTestGridLayoutManager;
+    private SelectionHelper mSelectionMgr;
     private TestFeatures mFeatures;
 
     @Override
     public void setUp() throws Exception {
         mView = TestRecyclerView.create(ITEMS);
-        mSelectionMgr = SelectionManagers.createTestInstance(ITEMS);
+        mTestGridLayoutManager = TestGridLayoutManager.create();
+        mView.setLayoutManager(mTestGridLayoutManager);
+
+        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
         mFeatures = new TestFeatures();
         mManager = new FocusManager(mFeatures, mSelectionMgr, null, null, 0)
                 .reset(mView, new TestModel(TEST_AUTHORITY, mFeatures));
@@ -68,13 +74,18 @@
     public void testFocusDirectoryList_noItemsToFocus() {
         mView = TestRecyclerView.create(new ArrayList<>());
         mManager = new FocusManager(
-                mFeatures, SelectionManagers.createTestInstance(), null, null, 0)
+                mFeatures, SelectionHelpers.createTestInstance(), null, null, 0)
                 .reset(mView, new TestModel(TEST_AUTHORITY, mFeatures));
         assertFalse(mManager.focusDirectoryList());
     }
 
+    public void testFocusDirectoryList_noVisibleItems() {
+        mTestGridLayoutManager.setFirstVisibleItemPosition(RecyclerView.NO_POSITION);
+        assertFalse(mManager.focusDirectoryList());
+    }
+
     public void testFocusDirectoryList_hasSelection() {
-        mSelectionMgr.toggleSelection("0");
+        mSelectionMgr.select("0");
         assertFalse(mManager.focusDirectoryList());
     }
 }
diff --git a/tests/unit/com/android/documentsui/SharedInputHandlerTest.java b/tests/unit/com/android/documentsui/SharedInputHandlerTest.java
index 0f5c280..9c28094 100644
--- a/tests/unit/com/android/documentsui/SharedInputHandlerTest.java
+++ b/tests/unit/com/android/documentsui/SharedInputHandlerTest.java
@@ -27,8 +27,8 @@
 
 import com.android.documentsui.base.Procedure;
 import com.android.documentsui.dirlist.TestFocusHandler;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.testing.SelectionManagers;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestFeatures;
 
 import org.junit.Before;
@@ -40,7 +40,7 @@
 public class SharedInputHandlerTest {
 
     private SharedInputHandler mSharedInputHandler;
-    private SelectionManager mSelectionMgr = SelectionManagers.createTestInstance();
+    private SelectionHelper mSelectionMgr = SelectionHelpers.createTestInstance();
     private TestFeatures mFeatures = new TestFeatures();
     private TestFocusHandler mFocusHandler = new TestFocusHandler();
     private boolean mDirPopHappened;
@@ -75,10 +75,10 @@
 
     @Test
     public void testBackButton_CancelsSearch() {
-        mSelectionMgr.toggleSelection("1");
+        mSelectionMgr.select("1");
         mSharedInputHandler = new SharedInputHandler(
                 new TestFocusHandler(),
-                SelectionManagers.createTestInstance(),
+                SelectionHelpers.createTestInstance(),
                 () -> {
                         mCanceledSearch = true;
                         return true;
@@ -96,7 +96,7 @@
 
     @Test
     public void testBackButton_ClearsSelection() {
-        mSelectionMgr.toggleSelection("1");
+        mSelectionMgr.select("1");
         assertEquals(mSelectionMgr.getSelection().size(), 1);
         KeyEvent backEvent =
                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
@@ -120,10 +120,10 @@
 
     @Test
     public void testEscButton_CancelsSearch() {
-        mSelectionMgr.toggleSelection("1");
+        mSelectionMgr.select("1");
         mSharedInputHandler = new SharedInputHandler(
                 new TestFocusHandler(),
-                SelectionManagers.createTestInstance(),
+                SelectionHelpers.createTestInstance(),
                 () -> {
                         mCanceledSearch = true;
                         return true;
@@ -141,7 +141,7 @@
 
     @Test
     public void testEscButton_ClearsSelection() {
-        mSelectionMgr.toggleSelection("1");
+        mSelectionMgr.select("1");
         assertEquals(mSelectionMgr.getSelection().size(), 1);
         KeyEvent escapeEvent =
                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ESCAPE, 0, 0);
diff --git a/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java b/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
index 7b2504a..cc40e56 100644
--- a/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
+++ b/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
@@ -28,11 +28,11 @@
 import android.content.Context;
 import android.database.ContentObserver;
 import android.database.Cursor;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.provider.DocumentsContract;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
@@ -264,4 +264,35 @@
 
         client.release();
     }
+
+    @Test
+    public void testGetDocumentMetadata() throws InterruptedException, RemoteException {
+        final Uri sourceUri = DocumentsContract.buildDocumentUri(
+                ResourcesProvider.AUTHORITY, "images.zip");
+        final Uri archiveUri = ArchivesProvider.buildUriForArchive(sourceUri,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        final ContentResolver resolver = mContext.getContentResolver();
+        final ContentProviderClient client =
+                resolver.acquireUnstableContentProviderClient(archiveUri);
+
+        ArchivesProvider.acquireArchive(client, archiveUri);
+
+        Uri archivedImageUri = Uri.parse(
+                "content://com.android.documentsui.archives/document/content%3A%2F%2F"
+                + "com.android.documentsui.archives.resourcesprovider%2F"
+                + "document%2Fimages.zip%23268435456%23%2Ffreddy.jpg");
+
+        Bundle metadata = DocumentsContract.getDocumentMetadata(client, archivedImageUri);
+        assertNotNull(metadata);
+        Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
+        assertNotNull(exif);
+
+        assertEquals(3036, exif.getInt(ExifInterface.TAG_IMAGE_WIDTH));
+        assertEquals(4048, exif.getInt(ExifInterface.TAG_IMAGE_LENGTH));
+        assertEquals("Pixel", exif.getString(ExifInterface.TAG_MODEL));
+
+        ArchivesProvider.releaseArchive(client, archiveUri);
+        client.release();
+    }
 }
diff --git a/tests/unit/com/android/documentsui/archives/ResourcesProvider.java b/tests/unit/com/android/documentsui/archives/ResourcesProvider.java
index 988b495..b9ddb92 100644
--- a/tests/unit/com/android/documentsui/archives/ResourcesProvider.java
+++ b/tests/unit/com/android/documentsui/archives/ResourcesProvider.java
@@ -56,9 +56,10 @@
     private static final Map<String, Integer> RESOURCES = new HashMap<>();
     static {
         RESOURCES.put("archive.zip", R.raw.archive);
-        RESOURCES.put("empty_dirs.zip", R.raw.empty_dirs);
-        RESOURCES.put("no_dirs.zip", R.raw.no_dirs);
         RESOURCES.put("broken.zip", R.raw.broken);
+        RESOURCES.put("empty_dirs.zip", R.raw.empty_dirs);
+        RESOURCES.put("images.zip", R.raw.images);
+        RESOURCES.put("no_dirs.zip", R.raw.no_dirs);
     }
 
     private ExecutorService mExecutor = null;
diff --git a/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java b/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java
index 68169bc..c25e43f 100644
--- a/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java
@@ -66,6 +66,17 @@
         assertEquals(mEnv.model.getItemCount() + 1, mAdapter.getItemCount());
     }
 
+    public void testGetPosition() {
+        mEnv.model.createFolder("a");  // id will be "1"...derived from insert position.
+        mEnv.model.createFile("b");  // id will be "2"
+        mEnv.model.update();
+
+        assertEquals(0, mAdapter.getPosition("1"));
+        // adapter inserts a view between item 0 and 1 to force layout
+        // break between folders and files. This is reflected by an offset position.
+        assertEquals(2, mAdapter.getPosition("2"));
+    }
+
     // Tests that the item count is correct for a directory containing only subdirs.
     public void testItemCount_allDirs() {
         String[] names = {"Trader Joe's", "Alphabeta", "Lucky", "Vons", "Gelson's"};
@@ -187,8 +198,11 @@
     }
 
     private static class DummyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+        @Override
         public int getItemCount() { return 0; }
+        @Override
         public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}
+        @Override
         public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
             return null;
         }
diff --git a/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java b/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java
index 9d9256d..f2187e4 100644
--- a/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java
@@ -20,9 +20,9 @@
 import android.database.Cursor;
 import android.graphics.Rect;
 import android.os.SystemClock;
+import android.support.test.filters.SmallTest;
 import android.support.test.filters.Suppress;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -30,6 +30,7 @@
 import android.view.MotionEvent.PointerProperties;
 
 import com.android.documentsui.R;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 @SmallTest
 public class DocumentHolderTest extends AndroidTestCase {
@@ -98,9 +99,9 @@
                 );
     }
 
-    private class TestListener implements DocumentHolder.KeyboardEventListener {
+    private class TestListener extends KeyboardEventListener {
         @Override
-        public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event) {
+        public boolean onKey(ItemDetails item, int keyCode, KeyEvent event) {
             return false;
         }
 
diff --git a/tests/unit/com/android/documentsui/dirlist/DragHostTest.java b/tests/unit/com/android/documentsui/dirlist/DragHostTest.java
index 4331ac4..7db69dc 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragHostTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragHostTest.java
@@ -28,10 +28,10 @@
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.files.TestActivity;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.testing.ClipDatas;
 import com.android.documentsui.testing.DragEvents;
-import com.android.documentsui.testing.SelectionManagers;
+import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestActionHandler;
 import com.android.documentsui.testing.TestDragAndDropManager;
 import com.android.documentsui.testing.TestEnv;
@@ -55,7 +55,7 @@
     private TestDialogController mDialogs;
     private DragHost<?> dragHost;
     private TestDragAndDropManager mDragAndDropManager;
-    private SelectionManager mSelectionMgr;
+    private SelectionHelper mSelectionMgr;
     private boolean mIsDocumentView;
     private DocumentHolder mNextDocumentHolder;
     private DocumentInfo mNextDocumentInfo;
@@ -66,7 +66,7 @@
         mActivity = TestActivity.create(mEnv);
         mDialogs = new TestDialogController();
         mDragAndDropManager = new TestDragAndDropManager();
-        mSelectionMgr = SelectionManagers.createTestInstance(ITEMS);
+        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
         mActionHandler = new TestActionHandler();
         dragHost = new DragHost<>(
                 mActivity,
diff --git a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java b/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
index f779334..f0e9f9a 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
@@ -24,17 +24,14 @@
 import android.view.View;
 
 import com.android.documentsui.ItemDragListener;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
 import com.android.documentsui.testing.DragEvents;
-import com.android.documentsui.testing.TestTimer;
 import com.android.documentsui.testing.Views;
-import com.android.documentsui.ui.ViewAutoScroller.ScrollActionDelegate;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Timer;
-
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class DragScrollListenerTest {
@@ -204,7 +201,7 @@
         public void onDragEnded() {}
     }
 
-    private class TestScrollActionDelegate implements ScrollActionDelegate {
+    private class TestScrollActionDelegate extends ScrollerCallbacks {
 
         private int mDy;
 
diff --git a/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java b/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
index 635e249..faa86a3 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
@@ -18,7 +18,7 @@
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
-import static junit.framework.TestCase.fail;
+import static junit.framework.Assert.fail;
 
 import android.provider.DocumentsContract;
 import android.support.test.filters.SmallTest;
@@ -26,20 +26,22 @@
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.android.documentsui.MenuManager;
+import com.android.documentsui.DocsSelectionHelper;
 import com.android.documentsui.MenuManager.SelectionDetails;
 import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Events;
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.State;
-import com.android.documentsui.dirlist.DragStartListener.ActiveListener;
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.dirlist.DragStartListener.RuntimeDragStartListener;
+import com.android.documentsui.selection.MutableSelection;
 import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.TestItemDetailsLookup;
+import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestDragAndDropManager;
-import com.android.documentsui.testing.TestEvent;
-import com.android.documentsui.testing.SelectionManagers;
+import com.android.documentsui.testing.TestEvents;
 import com.android.documentsui.testing.TestSelectionDetails;
 import com.android.documentsui.testing.Views;
+import com.android.internal.widget.RecyclerView;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -51,18 +53,20 @@
 @SmallTest
 public class DragStartListenerTest {
 
-    private ActiveListener mListener;
-    private TestEvent.Builder mEvent;
-    private SelectionManager mMultiSelectManager;
+    private RuntimeDragStartListener mListener;
+    private TestEvents.Builder mEvent;
+    private DocsSelectionHelper mSelectionMgr;
+    private TestItemDetailsLookup mDocLookup;
     private SelectionDetails mSelectionDetails;
     private String mViewModelId;
     private TestDragAndDropManager mManager;
 
     @Before
     public void setUp() throws Exception {
-        mMultiSelectManager = SelectionManagers.createTestInstance();
+        mSelectionMgr = SelectionHelpers.createTestInstance();
         mManager = new TestDragAndDropManager();
         mSelectionDetails = new TestSelectionDetails();
+        mDocLookup = new TestItemDetailsLookup();
 
         DocumentInfo doc = new DocumentInfo();
         doc.authority = Providers.AUTHORITY_STORAGE;
@@ -71,10 +75,12 @@
 
         State state = new State();
         state.stack.push(doc);
-        mListener = new DragStartListener.ActiveListener(
+
+        mListener = new DragStartListener.RuntimeDragStartListener(
                 null, // icon helper
                 state,
-                mMultiSelectManager,
+                mDocLookup,
+                mSelectionMgr,
                 mSelectionDetails,
                 // view finder
                 (float x, float y) -> {
@@ -86,21 +92,25 @@
                 },
                 // docInfo Converter
                 (Selection selection) -> {
-                    return new ArrayList<DocumentInfo>();
+                    return new ArrayList<>();
                 },
                 mManager);
 
         mViewModelId = "1234";
 
-        mEvent = TestEvent.builder()
+        mDocLookup.initAt(1).setInItemDragRegion(true);
+        mEvent = TestEvents.builder()
                 .action(MotionEvent.ACTION_MOVE)
                 .mouse()
-                .at(1)
-                .inDragHotspot()
                 .primary();
     }
 
     @Test
+    public void testMouseEvent() {
+        assertTrue(Events.isMouseDragEvent(mEvent.build()));
+    }
+
+    @Test
     public void testDragStarted_OnMouseMove() {
         assertTrue(mListener.onMouseDragEvent(mEvent.build()));
         mManager.startDragHandler.assertCalled();
@@ -115,15 +125,13 @@
 
     @Test
     public void testThrows_OnNonMouseMove() {
-        TestEvent e = TestEvent.builder()
-                .at(1)
-                .action(MotionEvent.ACTION_MOVE).build();
-        assertThrows(e);
+        assertThrows(mEvent.touch().build());
     }
 
     @Test
     public void testThrows_OnNonPrimaryMove() {
-        assertThrows(mEvent.pressButton(MotionEvent.BUTTON_PRIMARY).build());
+        mEvent.releaseButton(MotionEvent.BUTTON_PRIMARY);
+        assertThrows(mEvent.pressButton(MotionEvent.BUTTON_SECONDARY).build());
     }
 
     @Test
@@ -133,7 +141,8 @@
 
     @Test
     public void testThrows_WhenNotOnItem() {
-        assertThrows(mEvent.at(-1).build());
+        mDocLookup.initAt(RecyclerView.NO_POSITION);
+        assertThrows(mEvent.build());
     }
 
     @Test
@@ -146,10 +155,10 @@
 
     @Test
     public void testDragStart_selectedItem() {
-        Selection selection = new Selection();
+        MutableSelection selection = new MutableSelection();
         selection.add("1234");
         selection.add("5678");
-        mMultiSelectManager.replaceSelection(selection);
+        mSelectionMgr.replaceSelection(selection);
 
         selection = mListener.getSelectionToBeCopied("1234",
                 mEvent.action(MotionEvent.ACTION_MOVE).build());
@@ -160,23 +169,23 @@
 
     @Test
     public void testDragStart_newNonSelectedItem() {
-        Selection selection = new Selection();
+        MutableSelection selection = new MutableSelection();
         selection.add("5678");
-        mMultiSelectManager.replaceSelection(selection);
+        mSelectionMgr.replaceSelection(selection);
 
         selection = mListener.getSelectionToBeCopied("1234",
                 mEvent.action(MotionEvent.ACTION_MOVE).build());
         assertTrue(selection.size() == 1);
         assertTrue(selection.contains("1234"));
         // After this, selection should be cleared
-        assertFalse(mMultiSelectManager.hasSelection());
+        assertFalse(mSelectionMgr.hasSelection());
     }
 
     @Test
     public void testCtrlDragStart_newNonSelectedItem() {
-        Selection selection = new Selection();
+        MutableSelection selection = new MutableSelection();
         selection.add("5678");
-        mMultiSelectManager.replaceSelection(selection);
+        mSelectionMgr.replaceSelection(selection);
 
         selection = mListener.getSelectionToBeCopied("1234",
                 mEvent.action(MotionEvent.ACTION_MOVE).ctrl().build());
@@ -185,10 +194,10 @@
         assertTrue(selection.contains("5678"));
     }
 
-    private void assertThrows(InputEvent e) {
+    private void assertThrows(MotionEvent e) {
         try {
-            assertFalse(mListener.onMouseDragEvent(e));
+            mListener.onMouseDragEvent(e);
             fail();
-        } catch (AssertionError expected) {}
+        } catch (IllegalArgumentException expected) {}
     }
 }
diff --git a/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java b/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java
new file mode 100644
index 0000000..fdf9a59
--- /dev/null
+++ b/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.annotation.Nullable;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.KeyEvent;
+
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.selection.testing.SelectionPredicates;
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestData;
+import com.android.documentsui.testing.SelectionHelpers;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class KeyInputHandlerTest {
+
+    private static final List<String> ITEMS = TestData.create(100);
+
+    private KeyInputHandler mInputHandler;
+    private SelectionHelper mSelectionHelper;
+    private TestFocusHandler mFocusHandler;
+    private SelectionProbe mSelection;
+    private TestCallbacks mCallbacks;
+
+    @Before
+    public void setUp() {
+        mSelectionHelper = SelectionHelpers.createTestInstance(ITEMS);
+        mSelection = new SelectionProbe(mSelectionHelper);
+        mFocusHandler = new TestFocusHandler();
+        mCallbacks = new TestCallbacks();
+
+        mInputHandler = new KeyInputHandler(
+                mSelectionHelper,
+                SelectionPredicates.CAN_SET_ANYTHING,
+                mCallbacks);
+    }
+
+    @Test
+    public void testArrowKey_nonShiftClearsSelection() {
+        mSelectionHelper.select("11");
+
+        mFocusHandler.handleKey = true;
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP);
+        mInputHandler.onKey(null, event.getKeyCode(), event);
+
+        mSelection.assertNoSelection();
+    }
+
+    private static final class TestCallbacks extends KeyInputHandler.Callbacks {
+
+        private @Nullable ItemDetails mActivated;
+
+        @Override
+        public boolean isInteractiveItem(ItemDetails item, KeyEvent e) {
+            return true;
+        }
+
+        @Override
+        public boolean onItemActivated(ItemDetails item, KeyEvent e) {
+            mActivated = item;
+            return false;
+        }
+
+        private void assertActivated(ItemDetails expected) {
+            assertEquals(expected, mActivated);
+        }
+
+        @Override
+        public void onPerformHapticFeedback() {
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_KeyboardTest.java b/tests/unit/com/android/documentsui/dirlist/UserInputHandler_KeyboardTest.java
deleted file mode 100644
index 97dd027..0000000
--- a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_KeyboardTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionProbe;
-import com.android.documentsui.testing.SelectionManagers;
-import com.android.documentsui.testing.TestActionHandler;
-import com.android.documentsui.testing.TestEvent;
-import com.android.documentsui.testing.TestEvent.Builder;
-import com.android.documentsui.testing.TestEventHandler;
-import com.android.documentsui.testing.TestPredicate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class UserInputHandler_KeyboardTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private UserInputHandler<TestEvent> mInputHandler;
-    private TestActionHandler mActionHandler;
-    private TestFocusHandler mFocusHandler;
-    private SelectionProbe mSelection;
-
-    private TestPredicate<DocumentDetails> mCanSelect;
-    private TestEventHandler<InputEvent> mRightClickHandler;
-    private TestEventHandler<InputEvent> mDragAndDropHandler;
-    private TestEventHandler<InputEvent> mGestureSelectHandler;
-    private TestEventHandler<Void> mPerformHapticFeedback;
-
-    private Builder mEvent;
-
-    @Before
-    public void setUp() {
-        SelectionManager selectionMgr = SelectionManagers.createTestInstance(ITEMS);
-
-        mActionHandler = new TestActionHandler();
-        mSelection = new SelectionProbe(selectionMgr);
-        mFocusHandler = new TestFocusHandler();
-        mCanSelect = new TestPredicate<>();
-        mRightClickHandler = new TestEventHandler<>();
-        mDragAndDropHandler = new TestEventHandler<>();
-        mGestureSelectHandler = new TestEventHandler<>();
-
-        mInputHandler = new UserInputHandler<>(
-                mActionHandler,
-                mFocusHandler,
-                selectionMgr,
-                (MotionEvent event) -> {
-                    throw new UnsupportedOperationException("Not exercised in tests.");
-                },
-                mCanSelect,
-                mRightClickHandler::accept,
-                mDragAndDropHandler::accept,
-                mGestureSelectHandler::accept,
-                () -> mPerformHapticFeedback.accept(null));
-
-        mEvent = TestEvent.builder().mouse().overDocIcon();
-    }
-
-    @Test
-    public void testArrowKey_nonShiftClearsSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(11).build());
-        mSelection.assertSelection(11);
-
-        mFocusHandler.handleKey = true;
-        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP);
-        mInputHandler.onKey(null, event.getKeyCode(), event);
-
-        mSelection.assertNoSelection();
-    }
-}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java b/tests/unit/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java
deleted file mode 100644
index 2c916c6..0000000
--- a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionProbe;
-import com.android.documentsui.testing.SelectionManagers;
-import com.android.documentsui.testing.TestActionHandler;
-import com.android.documentsui.testing.TestEvent;
-import com.android.documentsui.testing.TestEvent.Builder;
-import com.android.documentsui.testing.TestEventHandler;
-import com.android.documentsui.testing.TestPredicate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class UserInputHandler_MouseTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private UserInputHandler<TestEvent> mInputHandler;
-    private TestActionHandler mActionHandler;
-    private TestFocusHandler mFocusHandler;
-    private SelectionProbe mSelection;
-    private SelectionManager mSelectionMgr;
-    private TestPredicate<DocumentDetails> mCanSelect;
-    private TestEventHandler<InputEvent> mContextMenuClickHandler;
-    private TestEventHandler<InputEvent> mDragAndDropHandler;
-    private TestEventHandler<InputEvent> mGestureSelectHandler;
-    private TestEventHandler<Void> mPerformHapticFeedback;
-
-    private Builder mEvent;
-
-    @Before
-    public void setUp() {
-
-        mSelectionMgr = SelectionManagers.createTestInstance(ITEMS);
-        mActionHandler = new TestActionHandler();
-
-        mSelection = new SelectionProbe(mSelectionMgr);
-        mCanSelect = new TestPredicate<>();
-        mContextMenuClickHandler = new TestEventHandler<>();
-        mDragAndDropHandler = new TestEventHandler<>();
-        mGestureSelectHandler = new TestEventHandler<>();
-        mFocusHandler = new TestFocusHandler();
-
-        mInputHandler = new UserInputHandler<>(
-                mActionHandler,
-                mFocusHandler,
-                mSelectionMgr,
-                (MotionEvent event) -> {
-                    throw new UnsupportedOperationException("Not exercised in tests.");
-                },
-                mCanSelect,
-                mContextMenuClickHandler::accept,
-                mDragAndDropHandler::accept,
-                mGestureSelectHandler::accept,
-                () -> mPerformHapticFeedback.accept(null));
-
-        mEvent = TestEvent.builder().mouse().overDocIcon();
-    }
-
-    @Test
-    public void testConfirmedClick_StartsSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(11).build());
-        mSelection.assertSelection(11);
-    }
-
-    @Test
-    public void testClickOnIconWithExistingSelection_AddsToSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(11).build());
-        mInputHandler.onSingleTapUp(mEvent.at(10).build());
-        mSelection.assertSelected(10, 11);
-    }
-
-    @Test
-    public void testClickOnIconOfSelectedItem_RemovesFromSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(8).build());
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mSelection.assertSelected(8, 9, 10, 11);
-
-        mInputHandler.onSingleTapUp(mEvent.at(9).unshift().build());
-        mSelection.assertSelected(8, 10, 11);
-    }
-
-    @Test
-    public void testRightClickDown_StartsContextMenu() {
-        mInputHandler.onDown(mEvent.secondary().build());
-        mContextMenuClickHandler.assertLastArgument(mEvent.secondary().build());
-    }
-
-    @Test
-    public void testAltClickDown_StartsContextMenu() {
-        mInputHandler.onDown(mEvent.primary().alt().build());
-        mContextMenuClickHandler.assertLastArgument(mEvent.primary().alt().build());
-    }
-
-    @Test
-    public void testScroll_shouldTrap() {
-        assertTrue(mInputHandler.onScroll(mEvent.at(0).action(MotionEvent.ACTION_MOVE).primary().build()));
-    }
-
-    @Test
-    public void testScroll_NoTrapForTwoFinger() {
-        assertFalse(mInputHandler.onScroll(mEvent.at(0).action(MotionEvent.ACTION_MOVE).build()));
-    }
-
-    @Test
-    public void testUnconfirmedCtrlClick_AddsToExistingSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-
-        mInputHandler.onSingleTapUp(mEvent.at(11).ctrl().build());
-        mSelection.assertSelection(7, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftClick_ExtendsSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-    }
-
-    @Test
-    public void testConfirmedShiftClick_ExtendsSelectionFromOriginFocus() {
-        mFocusHandler.focusPos = 7;
-        mFocusHandler.focusModelId = "7";
-        // This is a hack-y test, since the real FocusManager would've set range begin itself.
-        mSelectionMgr.setSelectionRangeBegin(7);
-        mSelection.assertNoSelection();
-
-        mInputHandler.onSingleTapConfirmed(mEvent.at(11).shift().build());
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftClick_RotatesAroundOrigin() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-
-        mInputHandler.onSingleTapUp(mEvent.at(5).shift().build());
-        mSelection.assertSelection(5, 6, 7);
-        mSelection.assertNotSelected(8, 9, 10, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftCtrlClick_Combination() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-
-        mInputHandler.onSingleTapUp(mEvent.at(5).unshift().ctrl().build());
-
-        mSelection.assertSelection(5, 7, 8, 9, 10, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftCtrlClick_ShiftTakesPriority() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-
-        mInputHandler.onSingleTapUp(mEvent.at(11).ctrl().shift().build());
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-    }
-
-    // TODO: Add testSpaceBar_Previews, but we need to set a system property
-    // to have a deterministic state.
-
-    @Test
-    public void testDoubleClick_Opens() {
-        mInputHandler.onDoubleTap(mEvent.at(11).build());
-        mActionHandler.open.assertLastArgument(mEvent.build().getDocumentDetails());
-    }
-
-    @Test
-    public void testMiddleClick_DoesNothing() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(11).tertiary().build());
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testClickOff_ClearsSelection() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(11).build());
-        mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build());
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testClick_Focuses() {
-        int id = 11;
-        mInputHandler.onSingleTapConfirmed(mEvent.at(id).notOverDocIcon().build());
-        assertTrue(mFocusHandler.getFocusModelId().equals(Integer.toString(id)));
-    }
-
-    @Test
-    public void testClickOff_ClearsFocus() {
-        int id = 11;
-        mInputHandler.onSingleTapConfirmed(mEvent.at(id).notOverDocIcon().build());
-        assertTrue(mFocusHandler.hasFocusedItem());
-        mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build());
-        assertFalse(mFocusHandler.hasFocusedItem());
-    }
-
-    @Test
-    public void testClickOffSelection_RemovesSelectionAndFocuses() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(1).build());
-        mInputHandler.onSingleTapUp(mEvent.at(5).shift().build());
-        mSelection.assertSelection(1, 2, 3, 4, 5);
-
-        int id = 11;
-        mInputHandler.onSingleTapUp(mEvent.at(id).unshift().notOverDocIcon().build());
-        assertTrue(mFocusHandler.getFocusModelId().equals(Integer.toString(id)));
-        mSelection.assertNoSelection();
-    }
-}
diff --git a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java b/tests/unit/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java
deleted file mode 100644
index 7ce85e1..0000000
--- a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.MotionEvent;
-
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionProbe;
-import com.android.documentsui.testing.SelectionManagers;
-import com.android.documentsui.testing.TestActionHandler;
-import com.android.documentsui.testing.TestEvent;
-import com.android.documentsui.testing.TestEvent.Builder;
-import com.android.documentsui.testing.TestEventHandler;
-import com.android.documentsui.testing.TestPredicate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * UserInputHandler / MultiSelectManager integration test covering the shared
- * responsibility of range selection.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class UserInputHandler_RangeTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private UserInputHandler<TestEvent> mInputHandler;
-    private TestActionHandler mActionHandler;
-
-    private SelectionProbe mSelection;
-    private TestFocusHandler mFocusHandler;
-    private TestPredicate<DocumentDetails> mCanSelect;
-    private TestEventHandler<InputEvent> mRightClickHandler;
-    private TestEventHandler<InputEvent> mDragAndDropHandler;
-    private TestEventHandler<InputEvent> mGestureSelectHandler;
-    private TestEventHandler<Void> mPerformHapticFeedback;
-    private Builder mEvent;
-
-    @Before
-    public void setUp() {
-
-        SelectionManager selectionMgr = SelectionManagers.createTestInstance(ITEMS);
-        mActionHandler = new TestActionHandler();
-        mFocusHandler = new TestFocusHandler();
-        mSelection = new SelectionProbe(selectionMgr);
-        mCanSelect = new TestPredicate<>();
-        mRightClickHandler = new TestEventHandler<>();
-        mDragAndDropHandler = new TestEventHandler<>();
-        mGestureSelectHandler = new TestEventHandler<>();
-
-        mInputHandler = new UserInputHandler<>(
-                mActionHandler,
-                mFocusHandler,
-                selectionMgr,
-                (MotionEvent event) -> {
-                    throw new UnsupportedOperationException("Not exercised in tests.");
-                },
-                mCanSelect,
-                mRightClickHandler::accept,
-                mDragAndDropHandler::accept,
-                mGestureSelectHandler::accept,
-                () -> mPerformHapticFeedback.accept(null));
-
-        mEvent = TestEvent.builder().mouse().overDocIcon();
-    }
-
-    @Test
-    public void testExtendRange() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mSelection.assertRangeSelection(7, 11);
-    }
-
-    @Test
-    public void testExtendRangeContinues() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mInputHandler.onSingleTapUp(mEvent.at(21).shift().build());
-        mSelection.assertRangeSelection(7, 21);
-    }
-
-    @Test
-    public void testMultipleContiguousRanges() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-
-        // click without shift sets a new range start point.
-        mInputHandler.onSingleTapUp(mEvent.at(20).unshift().notOverDocIcon().build());
-        mInputHandler.onSingleTapConfirmed(mEvent.at(20).notOverDocIcon().build());
-        mFocusHandler.focusPos = 20;
-        mInputHandler.onSingleTapUp(mEvent.at(25).shift().notOverDocIcon().build());
-        mInputHandler.onSingleTapConfirmed(mEvent.at(25).shift().notOverDocIcon().build());
-
-        mSelection.assertRangeNotSelected(7, 11);
-        mSelection.assertRangeSelected(20, 25);
-        mSelection.assertSelectionSize(6);
-    }
-
-    @Test
-    public void testReducesSelectionRange() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(17).shift().build());
-        mInputHandler.onSingleTapUp(mEvent.at(10).shift().build());
-        mSelection.assertRangeSelection(7, 10);
-    }
-
-    @Test
-    public void testReducesSelectionRange_Reverse() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(17).build());
-        mInputHandler.onSingleTapUp(mEvent.at(7).shift().build());
-        mInputHandler.onSingleTapUp(mEvent.at(14).shift().build());
-        mSelection.assertRangeSelection(14, 17);
-    }
-
-    @Test
-    public void testExtendsRange_Reverse() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(12).build());
-        mInputHandler.onSingleTapUp(mEvent.at(5).shift().build());
-        mSelection.assertRangeSelection(5, 12);
-    }
-
-    @Test
-    public void testExtendsRange_ReversesAfterForwardClick() {
-        mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
-        mInputHandler.onSingleTapUp(mEvent.at(0).shift().build());
-        mSelection.assertRangeSelection(0, 7);
-    }
-
-    @Test
-    public void testRightClickEstablishesRange() {
-
-        TestEvent fistClick = mEvent.at(7).secondary().build();
-        mInputHandler.onDown(fistClick);
-        // This next method call simulates the behavior of the system event dispatch code.
-        // UserInputHandler depends on a specific sequence of events for internal
-        // state to remain valid. It's not an awesome arrangement, but it is currently
-        // necessary.
-        //
-        // See: UserInputHandler.MouseDelegate#mHandledOnDown;
-        mInputHandler.onSingleTapUp(fistClick);
-
-        // Now we can send a subsequent event that should extend selection.
-        TestEvent secondClick = mEvent.at(11).primary().shift().build();
-        mInputHandler.onDown(secondClick);
-        mInputHandler.onSingleTapUp(secondClick);
-
-        mSelection.assertRangeSelection(7, 11);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java b/tests/unit/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java
deleted file mode 100644
index 86d49d0..0000000
--- a/tests/unit/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.dirlist;
-
-import static org.junit.Assert.assertFalse;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import com.android.documentsui.base.Events.InputEvent;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.selection.SelectionProbe;
-import com.android.documentsui.testing.SelectionManagers;
-import com.android.documentsui.testing.TestActionHandler;
-import com.android.documentsui.testing.TestEvent;
-import com.android.documentsui.testing.TestEvent.Builder;
-import com.android.documentsui.testing.TestEventHandler;
-import com.android.documentsui.testing.TestPredicate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class UserInputHandler_TouchTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private UserInputHandler<TestEvent> mInputHandler;
-    private TestActionHandler mActionHandler;
-
-    private SelectionProbe mSelection;
-    private TestPredicate<DocumentDetails> mCanSelect;
-    private TestEventHandler<InputEvent> mRightClickHandler;
-    private TestEventHandler<InputEvent> mDragAndDropHandler;
-    private TestEventHandler<InputEvent> mGestureSelectHandler;
-    private TestEventHandler<Void> mPerformHapticFeedback;
-
-    private Builder mEvent;
-
-    @Before
-    public void setUp() {
-        SelectionManager selectionMgr = SelectionManagers.createTestInstance(ITEMS);
-
-        mActionHandler = new TestActionHandler();
-
-        mSelection = new SelectionProbe(selectionMgr);
-        mCanSelect = new TestPredicate<>();
-        mRightClickHandler = new TestEventHandler<>();
-        mDragAndDropHandler = new TestEventHandler<>();
-        mGestureSelectHandler = new TestEventHandler<>();
-        mPerformHapticFeedback = new TestEventHandler<>();
-
-        mInputHandler = new UserInputHandler<>(
-                mActionHandler,
-                new TestFocusHandler(),
-                selectionMgr,
-                (MotionEvent event) -> {
-                    throw new UnsupportedOperationException("Not exercised in tests.");
-                },
-                mCanSelect,
-                mRightClickHandler::accept,
-                mDragAndDropHandler::accept,
-                mGestureSelectHandler::accept,
-                () -> mPerformHapticFeedback.accept(null));
-
-        mEvent = TestEvent.builder();
-    }
-
-    @Test
-    public void testTap_ActivatesWhenNoExistingSelection() {
-        mInputHandler.onSingleTapUp(mEvent.at(11).build());
-        mActionHandler.open.assertLastArgument(mEvent.build().getDocumentDetails());
-    }
-
-    @Test
-    public void testScroll_shouldNotBeTrapped() {
-        assertFalse(mInputHandler.onScroll(mEvent.build()));
-    }
-
-    @Test
-    public void testLongPress_StartsSelectionMode() {
-        mCanSelect.nextReturn(true);
-        TestEvent event = mEvent.at(7).build();
-        mInputHandler.onLongPress(event);
-        mSelection.assertSelection(7);
-        mPerformHapticFeedback.assertCalled();
-    }
-
-    @Test
-    public void testLongPress_SecondPressAddsSelection() {
-        mCanSelect.nextReturn(true);
-        TestEvent event1 = mEvent.at(7).build();
-        TestEvent event2 = mEvent.at(99).build();
-        TestEvent event3 = mEvent.at(13).build();
-        mInputHandler.onLongPress(event1);
-        mPerformHapticFeedback.assertCalled();
-        mPerformHapticFeedback.reset();
-        mInputHandler.onLongPress(event2);
-        mPerformHapticFeedback.assertCalled();
-        mPerformHapticFeedback.reset();
-        mInputHandler.onLongPress(event3);
-        mPerformHapticFeedback.assertCalled();
-        mPerformHapticFeedback.reset();
-        mSelection.assertSelection(7, 13, 99);
-    }
-
-    @Test
-    public void testTap_UnselectsSelectedItem() {
-        mInputHandler.onLongPress(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(7).build());
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testTapOff_ClearsSelection() {
-        mInputHandler.onLongPress(mEvent.at(7).build());
-        mInputHandler.onSingleTapUp(mEvent.at(11).build());
-        mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build());
-        mSelection.assertNoSelection();
-    }
-}
diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
index 9b35ee1..34c3142 100644
--- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
@@ -17,9 +17,12 @@
 package com.android.documentsui.files;
 
 import static com.android.documentsui.testing.IntentAsserts.assertHasAction;
+import static com.android.documentsui.testing.IntentAsserts.assertHasData;
+import static com.android.documentsui.testing.IntentAsserts.assertHasExtra;
 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraIntent;
 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraList;
 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraUri;
+import static com.android.documentsui.testing.IntentAsserts.assertTargetsComponent;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -35,8 +38,8 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Path;
-import android.support.test.filters.MediumTest;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Pair;
 import android.view.DragEvent;
@@ -49,6 +52,7 @@
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
+import com.android.documentsui.inspector.InspectorActivity;
 import com.android.documentsui.testing.ClipDatas;
 import com.android.documentsui.testing.DocumentStackAsserts;
 import com.android.documentsui.testing.Roots;
@@ -56,8 +60,10 @@
 import com.android.documentsui.testing.TestDocumentClipper;
 import com.android.documentsui.testing.TestDragAndDropManager;
 import com.android.documentsui.testing.TestEnv;
+import com.android.documentsui.testing.TestFeatures;
 import com.android.documentsui.testing.TestProvidersAccess;
 import com.android.documentsui.ui.TestDialogController;
+import com.android.internal.util.Preconditions;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -76,11 +82,13 @@
     private ActionHandler<TestActivity> mHandler;
     private TestDocumentClipper mClipper;
     private TestDragAndDropManager mDragAndDropManager;
+    private TestFeatures mFeatures;
     private boolean refreshAnswer = false;
 
     @Before
     public void setUp() {
-        mEnv = TestEnv.create();
+        mFeatures = new TestFeatures();
+        mEnv = TestEnv.create(mFeatures);
         mActivity = TestActivity.create(mEnv);
         mActionModeAddons = new TestActionModeAddons();
         mDialogs = new TestDialogController();
@@ -326,6 +334,15 @@
     }
 
     @Test
+    public void testDocumentPicked_Home_SendsActionViewForApks() throws Exception {
+        mActivity.currentRoot = TestProvidersAccess.HOME;
+
+        mHandler.openDocument(TestEnv.FILE_APK, ActionHandler.VIEW_TYPE_PREVIEW,
+                ActionHandler.VIEW_TYPE_REGULAR);
+        mActivity.assertActivityStarted(Intent.ACTION_VIEW);
+    }
+
+    @Test
     public void testDocumentPicked_Downloads_ManagesPartialFiles() throws Exception {
         mActivity.currentRoot = TestProvidersAccess.DOWNLOADS;
 
@@ -534,6 +551,78 @@
         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
     }
 
+    @Test
+    public void testShowInspector() throws Exception {
+        mHandler.showInspector(TestEnv.FILE_GIF);
+
+        mActivity.startActivity.assertCalled();
+        Intent intent = mActivity.startActivity.getLastValue();
+        assertTargetsComponent(intent, InspectorActivity.class);
+        assertHasData(intent, TestEnv.FILE_GIF.derivedUri);
+
+        // should only send this under especial circumstances. See test below.
+        assertFalse(intent.getExtras().containsKey(Intent.EXTRA_TITLE));
+    }
+
+    @Test
+    public void testShowInspector_DebugDisabled() throws Exception {
+        mFeatures.debugSupport = false;
+
+        mHandler.showInspector(TestEnv.FILE_GIF);
+        Intent intent = mActivity.startActivity.getLastValue();
+
+        assertHasExtra(intent, Shared.EXTRA_SHOW_DEBUG);
+        assertFalse(intent.getExtras().getBoolean(Shared.EXTRA_SHOW_DEBUG));
+    }
+
+    @Test
+    public void testShowInspector_DebugEnabled() throws Exception {
+        mFeatures.debugSupport = true;
+
+        mHandler.showInspector(TestEnv.FILE_GIF);
+        Intent intent = mActivity.startActivity.getLastValue();
+
+        assertHasExtra(intent, Shared.EXTRA_SHOW_DEBUG);
+        assertTrue(intent.getExtras().getBoolean(Shared.EXTRA_SHOW_DEBUG));
+    }
+
+    @Test
+    public void testShowInspector_OverridesRootDocumentName() throws Exception {
+        mActivity.currentRoot = TestProvidersAccess.PICKLES;
+        mEnv.populateStack();
+
+        // Verify test setup is correct, but not an assert related to the logic of our test.
+        Preconditions.checkState(mEnv.state.stack.size() == 1);
+        Preconditions.checkNotNull(mEnv.state.stack.peek());
+
+        DocumentInfo rootDoc = mEnv.state.stack.peek();
+        rootDoc.displayName = "poodles";
+
+        mHandler.showInspector(rootDoc);
+        Intent intent = mActivity.startActivity.getLastValue();
+        assertEquals(
+                TestProvidersAccess.PICKLES.title,
+                intent.getExtras().getString(Intent.EXTRA_TITLE));
+    }
+
+    @Test
+    public void testShowInspector_OverridesRootDocumentNameX() throws Exception {
+        mActivity.currentRoot = TestProvidersAccess.PICKLES;
+        mEnv.populateStack();
+        mEnv.state.stack.push(TestEnv.FOLDER_2);
+
+        // Verify test setup is correct, but not an assert related to the logic of our test.
+        Preconditions.checkState(mEnv.state.stack.size() == 2);
+        Preconditions.checkNotNull(mEnv.state.stack.peek());
+
+        DocumentInfo rootDoc = mEnv.state.stack.peek();
+        rootDoc.displayName = "poodles";
+
+        mHandler.showInspector(rootDoc);
+        Intent intent = mActivity.startActivity.getLastValue();
+        assertFalse(intent.getExtras().containsKey(Intent.EXTRA_TITLE));
+    }
+
     private void assertRootPicked(Uri expectedUri) throws Exception {
         mEnv.beforeAsserts();
 
diff --git a/tests/unit/com/android/documentsui/files/MenuManagerTest.java b/tests/unit/com/android/documentsui/files/MenuManagerTest.java
index 3420210..3a42015 100644
--- a/tests/unit/com/android/documentsui/files/MenuManagerTest.java
+++ b/tests/unit/com/android/documentsui/files/MenuManagerTest.java
@@ -32,8 +32,8 @@
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.TestContext;
 import com.android.documentsui.dirlist.TestData;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.testing.SelectionManagers;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestDirectoryDetails;
 import com.android.documentsui.testing.TestEnv;
 import com.android.documentsui.testing.TestFeatures;
@@ -66,8 +66,9 @@
     private TestMenuItem dirRename;
     private TestMenuItem dirDelete;
     private TestMenuItem dirViewInOwner;
-    private TestMenuItem dirOpenInNewWindow;
     private TestMenuItem dirPasteIntoFolder;
+    private TestMenuItem dirInspect;
+    private TestMenuItem dirOpenInNewWindow;
 
     /* Root List Context Menu items */
     private TestMenuItem rootEjectRoot;
@@ -99,6 +100,7 @@
     private TestMenuItem optionSelectAll;
     private TestMenuItem optionAdvanced;
     private TestMenuItem optionSettings;
+    private TestMenuItem optionInspector;
 
     private TestFeatures features;
     private TestSelectionDetails selectionDetails;
@@ -110,11 +112,13 @@
     private State state = new State();
     private MenuManager mgr;
     private TestActivity activity = TestActivity.create(TestEnv.create());
-    private SelectionManager selectionManager;
+    private SelectionHelper selectionManager;
 
     @Before
     public void setUp() {
         testMenu = TestMenu.create();
+
+        // The context menu on anything in DirectoryList (including no selection).
         dirShare = testMenu.findItem(R.id.dir_menu_share);
         dirOpen = testMenu.findItem(R.id.dir_menu_open);
         dirOpenWith = testMenu.findItem(R.id.dir_menu_open_with);
@@ -126,14 +130,16 @@
         dirRename = testMenu.findItem(R.id.dir_menu_rename);
         dirDelete = testMenu.findItem(R.id.dir_menu_delete);
         dirViewInOwner = testMenu.findItem(R.id.dir_menu_view_in_owner);
-        dirOpenInNewWindow = testMenu.findItem(R.id.dir_menu_open_in_new_window);
         dirPasteIntoFolder = testMenu.findItem(R.id.dir_menu_paste_into_folder);
+        dirInspect = testMenu.findItem(R.id.dir_menu_inspect);
+        dirOpenInNewWindow = testMenu.findItem(R.id.dir_menu_open_in_new_window);
 
         rootEjectRoot = testMenu.findItem(R.id.root_menu_eject_root);
         rootOpenInNewWindow = testMenu.findItem(R.id.root_menu_open_in_new_window);
         rootPasteIntoFolder = testMenu.findItem(R.id.root_menu_paste_into_folder);
         rootSettings = testMenu.findItem(R.id.root_menu_settings);
 
+        // Menu actions (including overflow) when action mode *is* active.
         actionModeOpen = testMenu.findItem(R.id.action_menu_open);
         actionModeOpenWith = testMenu.findItem(R.id.action_menu_open_with);
         actionModeShare = testMenu.findItem(R.id.action_menu_share);
@@ -144,9 +150,10 @@
         actionModeMoveTo = testMenu.findItem(R.id.action_menu_move_to);
         actionModeCompress = testMenu.findItem(R.id.action_menu_compress);
         actionModeRename = testMenu.findItem(R.id.action_menu_rename);
-        actionModeInspector = testMenu.findItem(R.id.action_menu_inspector);
+        actionModeInspector = testMenu.findItem(R.id.action_menu_inspect);
         actionModeViewInOwner = testMenu.findItem(R.id.action_menu_view_in_owner);
 
+        // Menu actions (including overflow) when action mode is not active.
         optionSearch = testMenu.findItem(R.id.option_menu_search);
         optionDebug = testMenu.findItem(R.id.option_menu_debug);
         optionGrid = testMenu.findItem(R.id.option_menu_grid);
@@ -156,6 +163,7 @@
         optionSelectAll = testMenu.findItem(R.id.option_menu_select_all);
         optionAdvanced = testMenu.findItem(R.id.option_menu_advanced);
         optionSettings = testMenu.findItem(R.id.option_menu_settings);
+        optionInspector = testMenu.findItem(R.id.option_menu_inspect);
 
         features = new TestFeatures();
 
@@ -168,8 +176,8 @@
         dirDetails = new TestDirectoryDetails();
         testSearchManager = new TestSearchViewManager();
         preferences = new TestScopedPreferences();
-        selectionManager = SelectionManagers.createTestInstance(TestData.create(1));
-        selectionManager.toggleSelection("0");
+        selectionManager = SelectionHelpers.createTestInstance(TestData.create(1));
+        selectionManager.select("0");
 
         mgr = new MenuManager(
                 features,
@@ -271,6 +279,7 @@
 
     @Test
     public void testActionsMenu_canViewInOwner() {
+        activity.resources.strings.put(R.string.menu_view_in_owner, "Insert name here! %s");
         selectionDetails.canViewInOwner = true;
         mgr.updateActionMenu(testMenu, selectionDetails);
 
@@ -351,6 +360,26 @@
     }
 
     @Test
+    public void testActionMenu_InspectorEnabledForSingleSelection() {
+        features.inspector = true;
+        selectionDetails.size = 1;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeInspector.assertVisible();
+        actionModeInspector.assertEnabled();
+    }
+
+    @Test
+    public void testActionMenu_InspectorDisabledForMultiSelection() {
+        features.inspector = true;
+        selectionDetails.size = 2;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeInspector.assertVisible();
+        actionModeInspector.assertDisabled();
+    }
+
+    @Test
     public void testOptionMenu() {
         mgr.updateOptionMenu(testMenu);
 
@@ -388,6 +417,27 @@
     }
 
     @Test
+    public void testOptionMenu_InspectorAvailable() {
+        features.inspector = true;
+        mgr.updateOptionMenu(testMenu);
+        optionInspector.assertVisible();
+        optionInspector.assertEnabled();
+    }
+
+    @Test
+    public void testOptionMenu_InspectorDisabledInRecentsFolder() {
+        features.inspector = true;
+
+        // synthesize a fake recents root. Not setting an authority or id == recents.
+        RootInfo recents = new RootInfo();
+        assert recents.isRecents();
+        state.stack.changeRoot(recents);
+        mgr.updateOptionMenu(testMenu);
+        optionInspector.assertVisible();
+        optionInspector.assertDisabled();
+    }
+
+    @Test
     public void testInflateContextMenu_Files() {
         TestMenuInflater inflater = new TestMenuInflater();
 
@@ -560,6 +610,13 @@
     }
 
     @Test
+    public void testContextMenu_CanInspectContainer() {
+        mgr.updateContextMenuForContainer(testMenu);
+        dirInspect.assertVisible();
+        dirInspect.assertEnabled();
+    }
+
+    @Test
     public void testContextMenu_OnWritableDirectory_NothingToPaste() {
         selectionDetails.canPasteInto = true;
         selectionDetails.size = 1;
@@ -624,6 +681,14 @@
     }
 
     @Test
+    public void testContextMenu_CanInspectSingleSelection() {
+        selectionDetails.size = 1;
+        mgr.updateContextMenuForFiles(testMenu, selectionDetails);
+        dirInspect.assertVisible();
+        dirInspect.assertEnabled();
+    }
+
+    @Test
     public void testRootContextMenu() {
         testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE;
 
diff --git a/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java b/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java
index 8fd130c..ad87726 100644
--- a/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java
+++ b/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java
@@ -59,9 +59,10 @@
         Set<String> features = new HashSet<>(
                 Arrays.asList(intent.getStringArrayExtra(Intent.EXTRA_QUICK_VIEW_FEATURES)));
 
-        assertEquals("Unexpected features set: " + features, 5, features.size());
+        assertEquals("Unexpected features set: " + features, 6, features.size());
         assertTrue(features.contains(QuickViewConstants.FEATURE_VIEW));
         assertTrue(features.contains(QuickViewConstants.FEATURE_EDIT));
+        assertTrue(features.contains(QuickViewConstants.FEATURE_DELETE));
         assertTrue(features.contains(QuickViewConstants.FEATURE_SEND));
         assertTrue(features.contains(QuickViewConstants.FEATURE_DOWNLOAD));
         assertTrue(features.contains(QuickViewConstants.FEATURE_PRINT));
diff --git a/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java b/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java
index 7c9bb02..cd487b6 100644
--- a/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java
+++ b/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java
@@ -25,7 +25,7 @@
 import com.android.documentsui.InspectorProvider;
 import android.test.suitebuilder.annotation.MediumTest;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.inspector.InspectorController.Loader;
+import com.android.documentsui.inspector.InspectorController.DataSupplier;
 import com.android.documentsui.testing.TestLoaderManager;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -46,7 +46,7 @@
 
     private Context mContext;
     private TestLoaderManager mLoaderManager;
-    private Loader mLoader;
+    private DataSupplier mLoader;
     private ContentResolver mResolver;
 
     @Before
@@ -55,7 +55,7 @@
         mContext = InstrumentationRegistry.getTargetContext();
         mResolver = mContext.getContentResolver();
         mLoaderManager = new TestLoaderManager();
-        mLoader = new DocumentLoader(mContext, mLoaderManager);
+        mLoader = new RuntimeDataSupplier(mContext, mLoaderManager);
 
         if (Looper.myLooper() == null) {
             Looper.prepare();
diff --git a/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java b/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java
new file mode 100644
index 0000000..8610ea7
--- /dev/null
+++ b/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.content.pm.PackageManager;
+import android.os.LocaleList;
+import android.support.test.InstrumentationRegistry;
+
+import android.content.Context;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import com.android.documentsui.testing.TestPackageManager;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for testing recognizing geo coordinates.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GpsCoordinatesTextClassifierTest {
+
+    private GpsCoordinatesTextClassifier mClassifier;
+
+    @Before
+    public void setUp() throws Exception {
+        PackageManager pm = TestPackageManager.create();
+        Context context = InstrumentationRegistry.getTargetContext();
+
+        TextClassifier defaultClassifier =
+                context.getSystemService(TextClassificationManager.class).getTextClassifier();
+        mClassifier = new GpsCoordinatesTextClassifier(pm, defaultClassifier);
+    }
+
+    @Test
+    public void testBasicPatterns() throws Exception {
+        assertClassifiedGeo("0,0", true);
+        assertClassifiedGeo("0, 0", true);
+        assertClassifiedGeo("0.0,0.0", true);
+        assertClassifiedGeo("0.0, 0.0", true);
+        assertClassifiedGeo("90,180", true);
+        assertClassifiedGeo("90, 180", true);
+        assertClassifiedGeo("90.0000,180.0000", true);
+        assertClassifiedGeo("90.000, 180.000000000000000", true);
+        assertClassifiedGeo("-77.5646564,133.656554654", true);
+        assertClassifiedGeo("33, -179.324234242423", true);
+        assertClassifiedGeo("44.4545454,70.0", true);
+        assertClassifiedGeo("60.0, 60.0", true);
+        assertClassifiedGeo("-33.33,-180", true);
+        assertClassifiedGeo("-88.888888, -33.3333", true);
+        assertClassifiedGeo("90.0, 180.000000", true);
+        assertClassifiedGeo("-90.00000, -180.0", true);
+    }
+
+    @Test
+    public void testInvalidPatterns() throws Exception {
+        assertClassifiedGeo("0", false);
+        assertClassifiedGeo("Geo Intent", false);
+        assertClassifiedGeo("GeoIntent", false);
+        assertClassifiedGeo("A.B, C.D", false);
+        assertClassifiedGeo("90.165464, 180.1", false);
+        // TODO: Failing tests below
+        // assertClassifiedGeo("-90.1, -180.156754", false);
+        // assertClassifiedGeo("5000, 5000", false);
+        // assertClassifiedGeo("500, 500", false);
+    }
+
+    private void assertClassifiedGeo(CharSequence text, boolean expectClassified) {
+        boolean wasClassified;
+        TextClassification test = mClassifier.classifyText(
+                text,
+                0,
+                text.length(),
+                new LocaleList());
+        try {
+            wasClassified = "geo".equals(test.getIntent().getData().getScheme());
+        } catch (NullPointerException intentNotSet) {
+            wasClassified = false;
+        }
+        assertEquals(wasClassified, expectClassified);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java b/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java
new file mode 100644
index 0000000..58b533b
--- /dev/null
+++ b/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.widget.TextView;
+import com.android.documentsui.inspector.HeaderTextSelector.Selector;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class HeaderTextSelectorTest {
+
+    private Context mContext;
+    private TestTextView mTestTextView;
+    private TestSelector mTestSelector;
+    private HeaderTextSelector mSelector;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mTestTextView = new TestTextView(mContext);
+        mTestSelector = new TestSelector();
+        mSelector = new HeaderTextSelector(mTestTextView, mTestSelector);
+    }
+
+    @Test
+    public void testSimpleFileName() throws Exception {
+        CharSequence fileName = "filename";
+        String extension = ".txt";
+        String testSequence = fileName + extension;
+
+        mTestTextView.setText(testSequence);
+        mSelector.onCreateActionMode(null, null);
+        mTestSelector.assertCalled();
+
+        CharSequence selectedSequence =
+                testSequence.subSequence(mTestSelector.mStart, mTestSelector.mStop);
+        assertEquals(selectedSequence, fileName);
+    }
+
+
+    @Test
+    public void testLotsOfPeriodsInFileName() throws Exception {
+        CharSequence fileName = "filename";
+        String extension = ".jpg.zip.pdf.txt";
+        String testSequence = fileName + extension;
+
+        mTestTextView.setText(testSequence);
+        mSelector.onCreateActionMode(null, null);
+        mTestSelector.assertCalled();
+
+        CharSequence selectedSequence =
+            testSequence.subSequence(mTestSelector.mStart, mTestSelector.mStop);
+        assertEquals(selectedSequence, fileName);
+    }
+
+    @Test
+    public void testNoPeriodsInFileName() throws Exception {
+        String testSequence = "filename";
+
+        mTestTextView.setText(testSequence);
+        mSelector.onCreateActionMode(null, null);
+        mTestSelector.assertCalled();
+
+        CharSequence selectedSequence =
+            testSequence.subSequence(mTestSelector.mStart, mTestSelector.mStop);
+        assertEquals(selectedSequence, testSequence);
+    }
+
+    private static class TestTextView extends TextView {
+
+        public TestTextView(Context context) {
+            super(context);
+        }
+
+        private String textViewString;
+
+        public void setText(String text) {
+            textViewString = text;
+        }
+
+        @Override
+        public CharSequence getText() {
+            return new SpannableString(textViewString);
+        }
+    }
+
+    private static class TestSelector implements Selector {
+
+        private boolean mCalled;
+        private int mStart;
+        private int mStop;
+
+        public TestSelector() {
+            mCalled = false;
+            mStart = -1;
+            mStop = -1;
+        }
+
+        @Override
+        public void select(Spannable text, int start, int stop) {
+            mCalled = true;
+            mStart = start;
+            mStop = stop;
+        }
+
+        public void assertCalled() {
+            assertTrue(mCalled);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java b/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java
index 68520ef..8f70477 100644
--- a/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java
+++ b/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java
@@ -15,102 +15,116 @@
  */
 package com.android.documentsui.inspector;
 
-import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_SETTINGS;
+import static junit.framework.Assert.fail;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
 import android.app.Activity;
-import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Looper;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.support.annotation.Nullable;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View.OnClickListener;
+
 import com.android.documentsui.InspectorProvider;
-import com.android.documentsui.ProviderExecutor;
+import com.android.documentsui.R;
+import com.android.documentsui.TestProviderActivity;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.inspector.InspectorController.DetailsDisplay;
-import com.android.documentsui.inspector.InspectorController.Loader;
-import com.android.documentsui.inspector.actions.Action;
+import com.android.documentsui.base.Shared;
 import com.android.documentsui.inspector.InspectorController.ActionDisplay;
+import com.android.documentsui.inspector.InspectorController.DataSupplier;
+import com.android.documentsui.inspector.InspectorController.DebugDisplay;
+import com.android.documentsui.inspector.InspectorController.DetailsDisplay;
+import com.android.documentsui.inspector.InspectorController.HeaderDisplay;
+import com.android.documentsui.inspector.InspectorController.MediaDisplay;
+import com.android.documentsui.inspector.actions.Action;
 import com.android.documentsui.testing.TestConsumer;
 import com.android.documentsui.testing.TestEnv;
 import com.android.documentsui.testing.TestLoaderManager;
 import com.android.documentsui.testing.TestPackageManager;
 import com.android.documentsui.testing.TestPackageManager.TestResolveInfo;
 import com.android.documentsui.testing.TestProvidersAccess;
-import java.util.ArrayList;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class InspectorControllerTest  {
 
     private static final String OPEN_IN_PROVIDER_DOC = "OpenInProviderTest";
 
-    private TestActivity mContext;
+    private TestActivity mActivity;
     private TestLoaderManager mLoaderManager;
-    private Loader mLoader;
+    private TestDataSupplier mDataSupplier;
     private TestPackageManager mPm;
     private InspectorController mController;
     private TestEnv mEnv;
-    private TestConsumer<DocumentInfo> mHeaderTestDouble;
+    private TestHeader mHeaderTestDouble;
     private TestDetails mDetailsTestDouble;
+    private TestMedia mMedia;
     private TestAction mShowInProvider;
     private TestAction mDefaultsTestDouble;
-    private TestConsumer<DocumentInfo> mDebugTestDouble;
-    private Boolean mShowSnackbarsCalled;
+    private TestDebug mDebugTestDouble;
+    private TestRunnable mErrCallback;
+    private Bundle mTestArgs;
 
     @Before
     public void setUp() throws Exception {
 
-        //Needed to create a non null loader for the InspectorController.
-        Context loader = InstrumentationRegistry.getTargetContext();
         mEnv = TestEnv.create();
         mPm = TestPackageManager.create();
         mLoaderManager = new TestLoaderManager();
-        mLoader = new DocumentLoader(loader, mLoaderManager);
-        mHeaderTestDouble = new TestConsumer<>();
+        mDataSupplier = new TestDataSupplier();
+        mHeaderTestDouble = new TestHeader();
         mDetailsTestDouble = new TestDetails();
+        mMedia = new TestMedia();
         mShowInProvider = new TestAction();
         mDefaultsTestDouble = new TestAction();
-        mDebugTestDouble = new TestConsumer<>();
+        mDebugTestDouble = new TestDebug();
+        mErrCallback = new TestRunnable();
+        mTestArgs = new Bundle();
 
-        mShowSnackbarsCalled = false;
+        // Add some fake data.
+        mDataSupplier.mDoc = TestEnv.FILE_JPG;
+        mDataSupplier.mMetadata = new Bundle();
+        TestMetadata.populateExifData(mDataSupplier.mMetadata);
 
-        //Crashes if not called before "new TestActivity".
+        // Crashes if not called before "new TestActivity".
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
-        mContext = new TestActivity();
+        mActivity = new TestActivity();
+        recreateController();
+    }
 
+    private void recreateController() {
         mController = new InspectorController(
-                mContext,
-                mLoader,
+                mActivity,
+                mDataSupplier,
                 mPm,
                 new TestProvidersAccess(),
-                false,
                 mHeaderTestDouble,
                 mDetailsTestDouble,
+                mMedia,
                 mShowInProvider,
                 mDefaultsTestDouble,
                 mDebugTestDouble,
-                ProviderExecutor::forAuthority,
-                () -> {
-                    mShowSnackbarsCalled = true;
-                }
-        );
+                mTestArgs,
+                mErrCallback);
     }
 
     /**
@@ -118,8 +132,9 @@
      */
     @Test
     public void testHideDebugByDefault() throws Exception {
-        mController.updateView(new DocumentInfo());
-        mDebugTestDouble.assertNotCalled();
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
+        mDebugTestDouble.assertVisible(false);
+        mDebugTestDouble.assertEmpty();
     }
 
     /**
@@ -127,25 +142,22 @@
      */
     @Test
     public void testShowDebugUpdatesView() throws Exception {
-        mController = new InspectorController(
-            mContext,
-            mLoader,
-            mPm,
-            new TestProvidersAccess(),
-            true,
-            mHeaderTestDouble,
-            mDetailsTestDouble,
-            mShowInProvider,
-            mDefaultsTestDouble,
-            mDebugTestDouble,
-            ProviderExecutor::forAuthority,
-            () -> {
-                mShowSnackbarsCalled = true;
-            }
-        );
+        mTestArgs.putBoolean(Shared.EXTRA_SHOW_DEBUG, true);
+        recreateController();
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
+        mDebugTestDouble.assertVisible(true);
+        mDebugTestDouble.assertNotEmpty();
+    }
 
-        mController.updateView(new DocumentInfo());
-        mDebugTestDouble.assertCalled();
+    /**
+     * Tests Debug view should be updated when visible.
+     */
+    @Test
+    public void testExtraTitleOverridesDisplayName() throws Exception {
+        mTestArgs.putString(Intent.EXTRA_TITLE, "hammy!");
+        recreateController();
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
+        mHeaderTestDouble.assertTitle("hammy!");
     }
 
     /**
@@ -165,9 +177,9 @@
             OPEN_IN_PROVIDER_DOC);
         mController.showInProvider(uri);
 
-        assertNotNull(mContext.started);
-        assertEquals("com.android.documentsui", mContext.started.getPackage());
-        assertEquals(uri, mContext.started.getData());
+        assertNotNull(mActivity.started);
+        assertEquals("com.android.documentsui", mActivity.started.getPackage());
+        assertEquals(uri, mActivity.started.getData());
     }
     /**
      * Test that valid input will update the view properly. The test uses a test double for header
@@ -177,7 +189,7 @@
      */
     @Test
     public void testUpdateViewWithValidInput() throws Exception {
-        mController.updateView(new DocumentInfo());
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
         mHeaderTestDouble.assertCalled();
         mDetailsTestDouble.assertCalled();
     }
@@ -193,9 +205,9 @@
         DocumentInfo doc = new DocumentInfo();
         doc.derivedUri =
             DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, OPEN_IN_PROVIDER_DOC);
-
         doc.flags = doc.flags | Document.FLAG_SUPPORTS_SETTINGS;
-        mController.updateView(doc);
+        mDataSupplier.mDoc = doc;
+        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
         assertTrue(mShowInProvider.becameVisible);
     }
 
@@ -206,11 +218,7 @@
      */
     @Test
     public void testShowInProvider_invisible() throws Exception {
-        DocumentInfo doc = new DocumentInfo();
-        doc.derivedUri =
-            DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, OPEN_IN_PROVIDER_DOC);
-
-        mController.updateView(doc);
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
         assertFalse(mShowInProvider.becameVisible);
     }
 
@@ -220,7 +228,6 @@
      */
     @Test
     public void testAppDefaults_visible() throws Exception {
-
         mPm.queryIntentProvidersResults = new ArrayList<>();
         mPm.queryIntentProvidersResults.add(new TestResolveInfo());
         mPm.queryIntentProvidersResults.add(new TestResolveInfo());
@@ -228,7 +235,8 @@
         doc.derivedUri =
             DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, OPEN_IN_PROVIDER_DOC);
 
-        mController.updateView(doc);
+        mDataSupplier.mDoc = doc;
+        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
         assertTrue(mDefaultsTestDouble.becameVisible);
     }
 
@@ -244,7 +252,8 @@
         doc.derivedUri =
             DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, OPEN_IN_PROVIDER_DOC);
 
-        mController.updateView(doc);
+        mDataSupplier.mDoc = doc;
+        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
         assertFalse(mDefaultsTestDouble.becameVisible);
     }
 
@@ -255,13 +264,60 @@
      * @throws Exception
      */
     @Test
-    public void testUpdateViewWithNullValue() throws Exception {
-        mController.updateView(null);
-        assertTrue(mShowSnackbarsCalled);
+    public void testUpdateView_withNullValue() throws Exception {
+        mDataSupplier.mDoc = null;
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
+
+        mErrCallback.assertCalled();
         mHeaderTestDouble.assertNotCalled();
         mDetailsTestDouble.assertNotCalled();
     }
 
+    @Test
+    public void testMetadata_GeoHandlerInstalled() {
+        DocumentInfo doc = TestEnv.clone(TestEnv.FILE_JPG);
+        doc.flags |= DocumentsContract.Document.FLAG_SUPPORTS_METADATA;
+        mDataSupplier.mDoc = doc;
+        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
+        mMedia.assertGeoCallbackInstalled();
+    }
+
+    @Test
+    public void testMetadata_notDisplayedWhenNotReturned() {
+        DocumentInfo doc = TestEnv.clone(TestEnv.FILE_JPG);
+        doc.flags |= DocumentsContract.Document.FLAG_SUPPORTS_METADATA;
+        mDataSupplier.mDoc = doc;
+        mDataSupplier.mMetadata = null;  // sorry, no results sucka!
+        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
+    }
+
+    @Test
+    public void testMetadata_notDisplayedDocWithoutSupportFlag() {
+        assert !TestEnv.FILE_JPG.isMetadataSupported();
+        mDataSupplier.mDoc = TestEnv.FILE_JPG;  // this is the default value. For "good measure".
+        mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
+        mMedia.assertVisible(false);
+        mMedia.assertEmpty();
+    }
+
+    @Test
+    public void testMetadata_GeoHandlerStartsAction() {
+        DocumentInfo doc = TestEnv.clone(TestEnv.FILE_JPG);
+        doc.flags |= DocumentsContract.Document.FLAG_SUPPORTS_METADATA;
+        mDataSupplier.mDoc = doc;
+        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
+        mMedia.mGeoClickCallback.run();
+        Intent geoIntent = mActivity.started;
+        assertEquals(Intent.ACTION_VIEW, geoIntent.getAction());
+        assertNotNull(geoIntent);
+        Uri uri = geoIntent.getData();
+        assertEquals("geo", uri.getScheme());
+        String strUri = uri.toSafeString();
+        assertTrue(strUri.contains("33."));
+        assertTrue(strUri.contains("-118."));
+        assertTrue(strUri.contains(TestEnv.FILE_JPG.displayName));
+    }
+
     private static class TestActivity extends Activity {
 
         private @Nullable Intent started;
@@ -311,6 +367,31 @@
         }
     }
 
+
+    private static class TestHeader implements HeaderDisplay {
+
+        private boolean mCalled = false;
+        private @Nullable String mTitle;
+
+        @Override
+        public void accept(DocumentInfo info, String displayName) {
+            mCalled = true;
+            mTitle = displayName;
+        }
+
+        public void assertTitle(String expected) {
+            Assert.assertEquals(expected, mTitle);
+        }
+
+        public void assertCalled() {
+            Assert.assertTrue(mCalled);
+        }
+
+        public void assertNotCalled() {
+            Assert.assertFalse(mCalled);
+        }
+    }
+
     private static class TestDetails implements DetailsDisplay {
 
         private boolean mCalled = false;
@@ -332,4 +413,71 @@
             Assert.assertFalse(mCalled);
         }
     }
+
+    private static class TestMedia extends TestTable implements MediaDisplay {
+
+        private @Nullable Runnable mGeoClickCallback;
+
+        @Override
+        public void accept(DocumentInfo info, Bundle metadata, Runnable geoClickCallback) {
+            mGeoClickCallback = geoClickCallback;
+        }
+
+        void assertGeoCallbackInstalled() {
+            assertNotNull(mGeoClickCallback);
+        }
+    }
+
+    private static class TestDebug extends TestTable implements DebugDisplay {
+
+        @Override
+        public void accept(DocumentInfo info) {
+            // We have to emulate some of the real DebugView behavior
+            // because the controller makes us visible if we're not-empty.
+            put(R.string.debug_content_uri, info.derivedUri.toString());
+        }
+
+        @Override
+        public void accept(Bundle metadata) {
+        }
+    }
+
+    private static final class TestDataSupplier implements DataSupplier {
+
+        private @Nullable DocumentInfo mDoc;
+        private @Nullable Bundle mMetadata;
+
+        @Override
+        public void loadDocInfo(Uri uri, Consumer<DocumentInfo> callback) {
+            callback.accept(mDoc);
+        }
+
+        @Override
+        public void getDocumentMetadata(Uri uri, Consumer<Bundle> callback) {
+            callback.accept(mMetadata);
+        }
+
+        @Override
+        public void loadDirCount(DocumentInfo directory, Consumer<Integer> callback) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void reset() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static final class TestRunnable implements Runnable {
+        private boolean mCalled;
+
+        @Override
+        public void run() {
+            mCalled = true;
+        }
+
+        void assertCalled() {
+            assertTrue(mCalled);
+        }
+    }
 }
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/inspector/MediaViewTest.java b/tests/unit/com/android/documentsui/inspector/MediaViewTest.java
new file mode 100644
index 0000000..7cf7b21
--- /dev/null
+++ b/tests/unit/com/android/documentsui/inspector/MediaViewTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import android.media.ExifInterface;
+import android.media.MediaMetadata;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.documentsui.R;
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.testing.TestEnv;
+import com.android.documentsui.testing.TestResources;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaViewTest {
+
+    private TestResources mResources;
+    private TestTable mTable;
+    private Bundle mMetadata;
+    private Consumer<float[]> mGeo = (float[] coords) -> {
+        mTable.put(R.string.metadata_address, "1234 Street Street\n"
+                + "City, State, 56789");
+    };
+
+    @Before
+    public void setUp() {
+        mResources = TestResources.create();
+        // TODO: We should just be using the real underlying resources.
+        mResources.strings.put(R.string.metadata_dimensions_format, "%d x %d, %.1fMP");
+        mResources.strings.put(R.string.metadata_aperture_format, "f/%.1f");
+        mResources.strings.put(R.string.metadata_coordinates_format, "%.3f, %.3f");
+        mResources.strings.put(R.string.metadata_camera_format, "%s %s");
+        mTable = new TestTable();
+        mMetadata = new Bundle();
+        TestMetadata.populateExifData(mMetadata);
+        TestMetadata.populateVideoData(mMetadata);
+        TestMetadata.populateAudioData(mMetadata);
+    }
+
+    /**
+     * Test that the updateMetadata method is printing metadata for selected items found in the
+     * bundle.
+     */
+    @Test
+    public void testShowExifData() throws Exception {
+        mResources.strings.put(R.string.metadata_focal_format, "%.2f mm");
+        mResources.strings.put(R.string.metadata_iso_format, "ISO %d");
+        Bundle exif = mMetadata.getBundle(DocumentsContract.METADATA_EXIF);
+        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, exif, null, mGeo);
+
+        mTable.assertHasRow(R.string.metadata_dimensions, "3840 x 2160, 8.3MP");
+        mTable.assertHasRow(R.string.metadata_date_time, "Jan 01, 1970, 12:16 AM");
+        mTable.assertHasRow(R.string.metadata_coordinates, "33.996, -118.475");
+        mTable.assertHasRow(R.string.metadata_altitude, "1244.0");
+        mTable.assertHasRow(R.string.metadata_camera, "Google Pixel");
+        mTable.assertHasRow(R.string.metadata_shutter_speed, "1/100");
+        mTable.assertHasRow(R.string.metadata_aperture, "f/2.0");
+        mTable.assertHasRow(R.string.metadata_iso_speed_ratings, "ISO 120");
+        mTable.assertHasRow(R.string.metadata_focal_length, "4.27 mm");
+        mTable.assertHasRow(R.string.metadata_address, "1234 Street Street\n"
+                + "City, State, 56789");
+    }
+
+    /**
+     * Bundle only supplies half of the values for the pairs that print in printMetaData. No put
+     * method should be called as the correct conditions have not been met.
+     * @throws Exception
+     */
+    @Test
+    public void testShowExifData_PartialGpsTags() throws Exception {
+        Bundle data = new Bundle();
+        data.putDouble(ExifInterface.TAG_GPS_LATITUDE, 37.7749);
+
+        mMetadata.putBundle(DocumentsContract.METADATA_EXIF, data);
+        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null, mGeo);
+        mTable.assertEmpty();
+    }
+
+    /**
+     * Bundle only supplies half of the values for the pairs that print in printMetaData. No put
+     * method should be called as the correct conditions have not been met.
+     * @throws Exception
+     */
+    @Test
+    public void testShowExifData_PartialDimensionTags() throws Exception {
+        Bundle data = new Bundle();
+        data.putInt(ExifInterface.TAG_IMAGE_WIDTH, 3840);
+
+        mMetadata.putBundle(DocumentsContract.METADATA_EXIF, data);
+        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null, mGeo);
+        mTable.assertEmpty();
+    }
+
+    /**
+     * Test that the updateMetadata method is printing metadata for selected items found in the
+     * bundle.
+     */
+    @Test
+    public void testShowVideoData() throws Exception {
+        Bundle data = mMetadata.getBundle(Shared.METADATA_KEY_VIDEO);
+        MediaView.showVideoData(mTable, mResources, TestEnv.FILE_MP4, data, null);
+
+        mTable.assertHasRow(R.string.metadata_duration, "01:12");
+        mTable.assertHasRow(R.string.metadata_dimensions, "1920 x 1080, 2.1MP");
+    }
+
+    @Test
+    public void testShowAudioData() throws Exception {
+        Bundle data = mMetadata.getBundle(Shared.METADATA_KEY_AUDIO);
+        MediaView.showAudioData(mTable, data);
+
+        mTable.assertHasRow(R.string.metadata_duration, "01:12");
+        mTable.assertHasRow(R.string.metadata_artist, "artist");
+        mTable.assertHasRow(R.string.metadata_composer, "composer");
+        mTable.assertHasRow(R.string.metadata_album, "album");
+    }
+
+    /**
+     * Test that the updateMetadata method is printing metadata for selected items found in the
+     * bundle.
+     */
+    @Test
+    public void testShowVideoData_HourPlusDuration() throws Exception {
+        Bundle data = mMetadata.getBundle(Shared.METADATA_KEY_VIDEO);
+        data.putInt(MediaMetadata.METADATA_KEY_DURATION, 21660000);
+        MediaView.showVideoData(mTable, mResources, TestEnv.FILE_MP4, data, null);
+
+        mTable.assertHasRow(R.string.metadata_duration, "6:01:00");
+    }
+
+    @Test
+    public void testGetAddress() throws Exception {
+        Consumer<float[]> badAddress = (float[] coords) -> {
+        };
+        Bundle data = new Bundle();
+        data.putInt(ExifInterface.TAG_IMAGE_WIDTH, 3840);
+        data.putInt(ExifInterface.TAG_IMAGE_LENGTH, 2160);
+
+        mMetadata.getBundle(DocumentsContract.METADATA_EXIF);
+        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null, badAddress);
+        mTable.assertNotInTable(R.string.metadata_address);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/inspector/TestMetadata.java b/tests/unit/com/android/documentsui/inspector/TestMetadata.java
new file mode 100644
index 0000000..a6801ad
--- /dev/null
+++ b/tests/unit/com/android/documentsui/inspector/TestMetadata.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import android.media.ExifInterface;
+import android.media.MediaMetadata;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+
+import com.android.documentsui.base.Shared;
+
+final class TestMetadata {
+    private TestMetadata() {}
+
+    static void populateExifData(Bundle container) {
+        Bundle data = new Bundle();
+        container.putBundle(DocumentsContract.METADATA_EXIF, data);
+
+        data.putInt(ExifInterface.TAG_IMAGE_WIDTH, 3840);
+        data.putInt(ExifInterface.TAG_IMAGE_LENGTH, 2160);
+        data.putString(ExifInterface.TAG_DATETIME, "Jan 01, 1970, 12:16 AM");
+        data.putString(ExifInterface.TAG_GPS_LATITUDE, "33/1,59/1,4530/100");
+        data.putString(ExifInterface.TAG_GPS_LONGITUDE, "118/1,28/1,3124/100");
+        data.putString(ExifInterface.TAG_GPS_LATITUDE_REF, "N");
+        data.putString(ExifInterface.TAG_GPS_LONGITUDE_REF, "W");
+        data.putDouble(ExifInterface.TAG_GPS_ALTITUDE, 1244);
+        data.putString(ExifInterface.TAG_MAKE, "Google");
+        data.putString(ExifInterface.TAG_MODEL, "Pixel");
+        data.putDouble(ExifInterface.TAG_SHUTTER_SPEED_VALUE, 6.643);
+        data.putDouble(ExifInterface.TAG_APERTURE, 2.0);
+        data.putInt(ExifInterface.TAG_ISO_SPEED_RATINGS, 120);
+        data.putDouble(ExifInterface.TAG_FOCAL_LENGTH, 4.27);
+    }
+
+    static void populateVideoData(Bundle container) {
+        Bundle data = new Bundle();
+        container.putBundle(Shared.METADATA_KEY_VIDEO, data);
+
+        // By convention we reuse exif tags for dimensions.
+        data.putInt(ExifInterface.TAG_IMAGE_WIDTH, 1920);
+        data.putInt(ExifInterface.TAG_IMAGE_LENGTH, 1080);
+        data.putInt(MediaMetadata.METADATA_KEY_DURATION, 72000);
+    }
+
+    static void populateAudioData(Bundle container) {
+        Bundle data = new Bundle();
+        container.putBundle(Shared.METADATA_KEY_AUDIO, data);
+
+        data.putInt(MediaMetadata.METADATA_KEY_DURATION, 72000);
+        data.putString(MediaMetadata.METADATA_KEY_ARTIST, "artist");
+        data.putString(MediaMetadata.METADATA_KEY_COMPOSER, "composer");
+        data.putString(MediaMetadata.METADATA_KEY_ALBUM, "album");
+    }
+}
diff --git a/tests/unit/com/android/documentsui/inspector/TestTable.java b/tests/unit/com/android/documentsui/inspector/TestTable.java
new file mode 100644
index 0000000..f1bd0b7
--- /dev/null
+++ b/tests/unit/com/android/documentsui/inspector/TestTable.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.inspector;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import android.view.View.OnClickListener;
+
+import com.android.documentsui.inspector.InspectorController.TableDisplay;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Friendly testable table implementation.
+ */
+class TestTable implements TableDisplay {
+
+    private Map<Integer, CharSequence> mRows;
+    private boolean mVisible;
+
+    public TestTable() {
+        mRows = new HashMap<>();
+    }
+
+    public void assertHasRow(int keyId, CharSequence expected) {
+        assertEquals(expected, mRows.get(keyId));
+    }
+
+    public void assertNotInTable (int keyId) {
+        assertNull(mRows.get(keyId));
+    }
+
+    @Override
+    public void put(int keyId, CharSequence value) {
+        mRows.put(keyId, value);
+    }
+
+    @Override
+    public void put(int keyId, CharSequence value, OnClickListener callback) {
+        mRows.put(keyId, value);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        mVisible = visible;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return mRows.isEmpty();
+    }
+
+    void assertEmpty() {
+        assertTrue(mRows.isEmpty());
+    }
+
+    void assertNotEmpty() {
+        assertFalse(mRows.isEmpty());
+    }
+
+    void assertVisible(boolean expected) {
+        assertEquals(expected, mVisible);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
index 8a502bf..5d41565 100644
--- a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
@@ -80,7 +80,7 @@
 
         mEnv.dialogs.confirmNext();
 
-        mEnv.selectionMgr.toggleSelection("1");
+        mEnv.selectionMgr.select("1");
 
         AsyncTask.setDefaultExecutor(mEnv.mExecutor);
     }
diff --git a/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java b/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java
index 91ce1ce..3c421c3 100644
--- a/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java
+++ b/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java
@@ -27,6 +27,7 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -54,9 +55,20 @@
     public void setUp() {
         mDefaultPrefs = InstrumentationRegistry.getContext().getSharedPreferences("prefs1", 0);
         mBackupPrefs = InstrumentationRegistry.getContext().getSharedPreferences("prefs2", 0);
+        clearSharedPrefs();
         mPrefsBackupHelper = new PrefsBackupHelper(mDefaultPrefs);
     }
 
+    @After
+    public void tearDown() {
+        clearSharedPrefs();
+    }
+
+    private void clearSharedPrefs() {
+        mDefaultPrefs.edit().clear().commit();
+        mBackupPrefs.edit().clear().commit();
+    }
+
     @Test
     public void testPrepareBackupFile_BackupLocalPreferences() {
         mDefaultPrefs.edit().putInt(LOCAL_PREFERENCE_1, 1).commit();
diff --git a/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java b/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java
new file mode 100644
index 0000000..feffaec
--- /dev/null
+++ b/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.queries;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Handler;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.R;
+import com.android.documentsui.base.EventHandler;
+import com.android.documentsui.queries.SearchViewManager.SearchManagerListener;
+import com.android.documentsui.queries.SearchViewManager;
+import com.android.documentsui.testing.TestEventHandler;
+import com.android.documentsui.testing.TestHandler;
+import com.android.documentsui.testing.TestMenu;
+import com.android.documentsui.testing.TestTimer;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class SearchViewManagerTest {
+
+    private TestEventHandler<String> mTestEventHandler;
+    private TestTimer mTestTimer;
+    private TestHandler mTestHandler;
+    private SearchViewManager mSearchViewManager;
+
+    private boolean mListenerOnSearchChangedCalled;
+
+    @Before
+    public void setUp() {
+        mTestEventHandler = new TestEventHandler<>();
+        mTestTimer = new TestTimer();
+        mTestHandler = new TestHandler();
+
+        final SearchManagerListener searchListener = new SearchManagerListener() {
+            @Override
+            public void onSearchChanged(@Nullable String query) {
+                mListenerOnSearchChangedCalled = true;
+            }
+            @Override
+            public void onSearchFinished() {}
+            @Override
+            public void onSearchViewChanged(boolean opened) {}
+        };
+
+        mSearchViewManager = new TestableSearchViewManager(
+                searchListener, mTestEventHandler, null, mTestTimer, mTestHandler);
+
+        final TestMenu testMenu = TestMenu.create();
+        mSearchViewManager.install(testMenu, true);
+    }
+
+    private static class TestableSearchViewManager extends SearchViewManager {
+        public TestableSearchViewManager(
+                SearchManagerListener listener,
+                EventHandler<String> commandProcessor,
+                @Nullable Bundle savedState,
+                Timer timer,
+                Handler handler) {
+            super(listener, commandProcessor, savedState, timer, handler);
+        }
+
+        @Override
+        public TimerTask createSearchTask(String newText) {
+            TimerTask task = super.createSearchTask(newText);
+            TestTimer.Task testTask = new TestTimer.Task(task);
+            return testTask;
+        }
+    }
+
+    private void fastForwardTo(long timeMs) {
+        mTestTimer.fastForwardTo(timeMs);
+        mTestHandler.dispatchAllMessages();
+    }
+
+    @Test
+    public void testIsExpanded_ExpandsOnClick() {
+        mSearchViewManager.onClick(null);
+        assertTrue(mSearchViewManager.isExpanded());
+    }
+
+    @Test
+    public void testIsExpanded_CollapsesOnMenuItemActionCollapse() {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onMenuItemActionCollapse(null);
+        assertFalse(mSearchViewManager.isExpanded());
+    }
+
+    @Test
+    public void testIsSearching_FalseOnClick() throws Exception {
+        mSearchViewManager.onClick(null);
+        assertFalse(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testIsSearching_TrueOnQueryTextSubmit() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextSubmit("query");
+        assertTrue(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testIsSearching_FalseImmediatelyAfterOnQueryTextChange() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        assertFalse(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testIsSearching_TrueAfterOnQueryTextChangeAndWait() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        assertTrue(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testIsSearching_FalseWhenSecondOnQueryTextChangeResetsTimer() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS - 1);
+        mSearchViewManager.onQueryTextChange("qu");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        assertFalse(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testIsSearching_TrueAfterSecondOnQueryTextChangeResetsTimer() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS - 1);
+        mSearchViewManager.onQueryTextChange("qu");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS * 2);
+        assertTrue(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testIsSearching_FalseIfSearchCanceled() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        mSearchViewManager.cancelSearch();
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        assertFalse(mSearchViewManager.isSearching());
+    }
+
+    @Test
+    public void testOnSearchChanged_CalledAfterOnQueryTextSubmit() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextSubmit("q");
+        assertTrue(mListenerOnSearchChangedCalled);
+    }
+
+    @Test
+    public void testOnSearchChanged_NotCalledImmediatelyAfterOnQueryTextChanged() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        assertFalse(mListenerOnSearchChangedCalled);
+    }
+
+    @Test
+    public void testOnSearchChanged_CalledAfterOnQueryTextChangedAndWait() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        assertTrue(mListenerOnSearchChangedCalled);
+    }
+
+    @Test
+    public void testOnSearchChanged_CalledOnlyOnceAfterOnQueryTextSubmit() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        mSearchViewManager.onQueryTextSubmit("q");
+
+        // Clear the flag to check if it gets set again.
+        mListenerOnSearchChangedCalled = false;
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        assertFalse(mListenerOnSearchChangedCalled);
+    }
+
+    @Test
+    public void testOnSearchChanged_NotCalledForOnQueryTextSubmitIfSearchAlreadyFinished()
+            throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        // Clear the flag to check if it gets set again.
+        mListenerOnSearchChangedCalled = false;
+        mSearchViewManager.onQueryTextSubmit("q");
+        assertFalse(mListenerOnSearchChangedCalled);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/BandControllerTest.java b/tests/unit/com/android/documentsui/selection/BandControllerTest.java
deleted file mode 100644
index 6a32147..0000000
--- a/tests/unit/com/android/documentsui/selection/BandControllerTest.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.documentsui.selection;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.support.v7.widget.RecyclerView.OnScrollListener;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.MotionEvent;
-
-import com.android.documentsui.DirectoryReloadLock;
-import com.android.documentsui.dirlist.TestData;
-import com.android.documentsui.dirlist.TestDocumentsAdapter;
-import com.android.documentsui.dirlist.TestFocusHandler;
-import com.android.documentsui.testing.SelectionManagers;
-import com.android.documentsui.testing.TestEvent.Builder;
-
-import java.util.Collections;
-import java.util.List;
-
-@SmallTest
-public class BandControllerTest extends AndroidTestCase {
-
-    private static final List<String> ITEMS = TestData.create(10);
-    private BandController mBandController;
-    private boolean mIsActive;
-
-    @Override
-    public void setUp() throws Exception {
-        mIsActive = false;
-        mBandController = new BandController(new TestSelectionEnvironment(),
-                new TestDocumentsAdapter(ITEMS), SelectionManagers.createTestInstance(ITEMS),
-                new DirectoryReloadLock(), null) {
-          @Override
-          public boolean isActive() {
-              return mIsActive;
-          }
-        };
-    }
-
-    public void testGoodStart() {
-        assertTrue(mBandController.shouldStart(goodStartEventBuilder().build()));
-    }
-
-    public void testBadStart_NoButtons() {
-        assertFalse(mBandController.shouldStart(
-                goodStartEventBuilder().releaseButton(MotionEvent.BUTTON_PRIMARY).build()));
-    }
-
-    public void testBadStart_SecondaryButton() {
-        assertFalse(
-                mBandController.shouldStart(goodStartEventBuilder().secondary().build()));
-    }
-
-    public void testBadStart_TertiaryButton() {
-        assertFalse(
-                mBandController.shouldStart(goodStartEventBuilder().tertiary().build()));
-    }
-
-    public void testBadStart_Touch() {
-        assertFalse(mBandController.shouldStart(
-                goodStartEventBuilder().touch().releaseButton(MotionEvent.BUTTON_PRIMARY).build()));
-    }
-
-    public void testBadStart_inDragSpot() {
-        assertFalse(
-                mBandController.shouldStart(goodStartEventBuilder().at(1).inDragHotspot().build()));
-    }
-
-    public void testBadStart_ActionDown() {
-        assertFalse(mBandController
-                .shouldStart(goodStartEventBuilder().action(MotionEvent.ACTION_DOWN).build()));
-    }
-
-    public void testBadStart_ActionUp() {
-        assertFalse(mBandController
-                .shouldStart(goodStartEventBuilder().action(MotionEvent.ACTION_UP).build()));
-    }
-
-    public void testBadStart_ActionPointerDown() {
-        assertFalse(mBandController.shouldStart(
-                goodStartEventBuilder().action(MotionEvent.ACTION_POINTER_DOWN).build()));
-    }
-
-    public void testBadStart_ActionPointerUp() {
-        assertFalse(mBandController.shouldStart(
-                goodStartEventBuilder().action(MotionEvent.ACTION_POINTER_UP).build()));
-    }
-
-    public void testBadStart_NoItems() {
-        mBandController = new BandController(new TestSelectionEnvironment(),
-                new TestDocumentsAdapter(Collections.EMPTY_LIST),
-                SelectionManagers.createTestInstance(ITEMS),
-                new DirectoryReloadLock(), null);
-        assertFalse(mBandController.shouldStart(goodStartEventBuilder().build()));
-    }
-
-    public void testBadStart_alreadyActive() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStart(goodStartEventBuilder().build()));
-    }
-
-    public void testGoodStop() {
-        mIsActive = true;
-        assertTrue(mBandController.shouldStop(goodStopEventBuilder().build()));
-    }
-
-    public void testGoodStop_PointerUp() {
-        mIsActive = true;
-        assertTrue(mBandController
-                .shouldStop(goodStopEventBuilder().action(MotionEvent.ACTION_POINTER_UP).build()));
-    }
-
-    public void testGoodStop_Cancel() {
-        mIsActive = true;
-        assertTrue(mBandController
-                .shouldStop(goodStopEventBuilder().action(MotionEvent.ACTION_CANCEL).build()));
-    }
-
-    public void testBadStop_NotActive() {
-        assertFalse(mBandController.shouldStop(goodStopEventBuilder().build()));
-    }
-
-    public void testBadStop_NonMouse() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStop(goodStopEventBuilder().touch().build()));
-    }
-
-    public void testBadStop_Move() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStop(
-                goodStopEventBuilder().action(MotionEvent.ACTION_MOVE).touch().build()));
-    }
-
-    public void testBadStop_Down() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStop(
-                goodStopEventBuilder().action(MotionEvent.ACTION_DOWN).touch().build()));
-    }
-
-
-    private Builder goodStartEventBuilder() {
-        return new Builder().mouse().primary().action(MotionEvent.ACTION_MOVE).notInDragHotspot();
-    }
-
-    private Builder goodStopEventBuilder() {
-        return new Builder().mouse().action(MotionEvent.ACTION_UP).notInDragHotspot();
-    }
-
-    private final class TestSelectionEnvironment implements BandController.SelectionEnvironment {
-        @Override
-        public void scrollBy(int dy) {
-        }
-
-        @Override
-        public void runAtNextFrame(Runnable r) {
-        }
-
-        @Override
-        public void removeCallback(Runnable r) {
-        }
-
-        @Override
-        public void showBand(Rect rect) {
-        }
-
-        @Override
-        public void hideBand() {
-        }
-
-        @Override
-        public void addOnScrollListener(OnScrollListener listener) {
-        }
-
-        @Override
-        public void removeOnScrollListener(OnScrollListener listener) {
-        }
-
-        @Override
-        public int getHeight() {
-            return 0;
-        }
-
-        @Override
-        public void invalidateView() {
-        }
-
-        @Override
-        public Point createAbsolutePoint(Point relativePoint) {
-            return null;
-        }
-
-        @Override
-        public Rect getAbsoluteRectForChildViewAt(int index) {
-            return null;
-        }
-
-        @Override
-        public int getAdapterPositionAt(int index) {
-            return 0;
-        }
-
-        @Override
-        public int getColumnCount() {
-            return 0;
-        }
-
-        @Override
-        public int getChildCount() {
-            return 0;
-        }
-
-        @Override
-        public int getVisibleChildCount() {
-            return 0;
-        }
-
-        @Override
-        public boolean hasView(int adapterPosition) {
-            return false;
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/BandSelectionHelperTest.java b/tests/unit/com/android/documentsui/selection/BandSelectionHelperTest.java
new file mode 100644
index 0000000..87b7a1d
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/BandSelectionHelperTest.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.BandSelectionHelper.BandHost;
+import com.android.documentsui.selection.testing.SelectionPredicates;
+import com.android.documentsui.selection.testing.TestAdapter;
+import com.android.documentsui.selection.testing.TestBandPredicate;
+import com.android.documentsui.selection.testing.TestEvents.Builder;
+import com.android.documentsui.selection.testing.TestStableIdProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BandSelectionHelperTest {
+
+    private List<String> mItems;
+    private BandSelectionHelper mBandController;
+    private boolean mIsActive;
+    private Builder mStartBuilder;
+    private Builder mStopBuilder;
+    private MotionEvent mStartEvent;
+    private MotionEvent mStopEvent;
+    private TestBandHost mBandHost;
+    private TestBandPredicate mBandPredicate;
+
+    @Before
+    public void setup() throws Exception {
+        mItems = TestAdapter.createItemList(10);
+        mIsActive = false;
+        TestAdapter adapter = new TestAdapter();
+        adapter.updateTestModelIds(mItems);
+        mBandHost = new TestBandHost();
+        mBandPredicate = new TestBandPredicate();
+
+        SelectionHelper helper = new DefaultSelectionHelper(
+                DefaultSelectionHelper.MODE_SINGLE,
+                adapter,
+                new TestStableIdProvider(adapter),
+                SelectionPredicates.CAN_SET_ANYTHING);
+
+        mBandController = new BandSelectionHelper(
+                mBandHost,
+                adapter,
+                new TestStableIdProvider(adapter),
+                helper,
+                SelectionPredicates.CAN_SET_ANYTHING,
+                mBandPredicate,
+                new ContentLock()) {
+                    @Override
+                    public boolean isActive() {
+                        return mIsActive;
+                    }
+                };
+
+        mStartBuilder = new Builder().mouse().primary().action(MotionEvent.ACTION_MOVE);
+        mStopBuilder = new Builder().mouse().action(MotionEvent.ACTION_UP);
+        mStartEvent = mStartBuilder.build();
+        mStopEvent = mStopBuilder.build();
+    }
+
+    @Test
+    public void testGoodStart() {
+        assertTrue(mBandController.shouldStart(mStartEvent));
+    }
+
+    @Test
+    public void testBadStart_NoButtons() {
+        assertFalse(mBandController.shouldStart(
+                mStartBuilder.releaseButton(MotionEvent.BUTTON_PRIMARY).build()));
+    }
+
+    @Test
+    public void testBadStart_SecondaryButton() {
+        assertFalse(
+                mBandController.shouldStart(mStartBuilder.secondary().build()));
+    }
+
+    @Test
+    public void testBadStart_TertiaryButton() {
+        assertFalse(
+                mBandController.shouldStart(mStartBuilder.tertiary().build()));
+    }
+
+    @Test
+    public void testBadStart_Touch() {
+        assertFalse(mBandController.shouldStart(
+                mStartBuilder.touch().releaseButton(MotionEvent.BUTTON_PRIMARY).build()));
+    }
+
+    @Test
+    public void testBadStart_RespectsCanInitiateBand() {
+        mBandPredicate.setCanInitiate(false);
+        assertFalse(mBandController.shouldStart(mStartEvent));
+    }
+
+    @Test
+    public void testBadStart_ActionDown() {
+        assertFalse(mBandController
+                .shouldStart(mStartBuilder.action(MotionEvent.ACTION_DOWN).build()));
+    }
+
+    @Test
+    public void testBadStart_ActionUp() {
+        assertFalse(mBandController
+                .shouldStart(mStartBuilder.action(MotionEvent.ACTION_UP).build()));
+    }
+
+    @Test
+    public void testBadStart_ActionPointerDown() {
+        assertFalse(mBandController.shouldStart(
+                mStartBuilder.action(MotionEvent.ACTION_POINTER_DOWN).build()));
+    }
+
+    @Test
+    public void testBadStart_ActionPointerUp() {
+        assertFalse(mBandController.shouldStart(
+                mStartBuilder.action(MotionEvent.ACTION_POINTER_UP).build()));
+    }
+
+    @Test
+    public void testBadStart_NoItems() {
+        TestAdapter emptyAdapter = new TestAdapter();
+        emptyAdapter.updateTestModelIds(Collections.EMPTY_LIST);
+
+        SelectionHelper helper = new DefaultSelectionHelper(
+                DefaultSelectionHelper.MODE_SINGLE,
+                emptyAdapter,
+                new TestStableIdProvider(emptyAdapter),
+                SelectionPredicates.CAN_SET_ANYTHING);
+
+        mBandController = new BandSelectionHelper(
+                new TestBandHost(),
+                emptyAdapter,
+                new TestStableIdProvider(emptyAdapter),
+                helper,
+                SelectionPredicates.CAN_SET_ANYTHING,
+                mBandPredicate,
+                new ContentLock());
+
+        assertFalse(mBandController.shouldStart(mStartEvent));
+    }
+
+    @Test
+    public void testBadStart_alreadyActive() {
+        mIsActive = true;
+        assertFalse(mBandController.shouldStart(mStartEvent));
+    }
+
+    @Test
+    public void testGoodStop() {
+        mIsActive = true;
+        assertTrue(mBandController.shouldStop(mStopEvent));
+    }
+
+    @Test
+    public void testGoodStop_PointerUp() {
+        mIsActive = true;
+        assertTrue(mBandController
+                .shouldStop(mStopBuilder.action(MotionEvent.ACTION_POINTER_UP).build()));
+    }
+
+    @Test
+    public void testGoodStop_Cancel() {
+        mIsActive = true;
+        assertTrue(mBandController
+                .shouldStop(mStopBuilder.action(MotionEvent.ACTION_CANCEL).build()));
+    }
+
+    @Test
+    public void testBadStop_NotActive() {
+        assertFalse(mBandController.shouldStop(mStopEvent));
+    }
+
+    @Test
+    public void testBadStop_NonMouse() {
+        mIsActive = true;
+        assertFalse(mBandController.shouldStop(mStopBuilder.touch().build()));
+    }
+
+    @Test
+    public void testBadStop_Move() {
+        mIsActive = true;
+        assertFalse(mBandController.shouldStop(
+                mStopBuilder.action(MotionEvent.ACTION_MOVE).touch().build()));
+    }
+
+    @Test
+    public void testBadStop_Down() {
+        mIsActive = true;
+        assertFalse(mBandController.shouldStop(
+                mStopBuilder.action(MotionEvent.ACTION_DOWN).touch().build()));
+    }
+
+    private final class TestBandHost extends BandHost {
+        @Override
+        public void scrollBy(int dy) {
+        }
+
+        @Override
+        public void runAtNextFrame(Runnable r) {
+        }
+
+        @Override
+        public void removeCallback(Runnable r) {
+        }
+
+        @Override
+        public void showBand(Rect rect) {
+        }
+
+        @Override
+        public void hideBand() {
+        }
+
+        @Override
+        public void addOnScrollListener(OnScrollListener listener) {
+        }
+
+        @Override
+        public void removeOnScrollListener(OnScrollListener listener) {
+        }
+
+        @Override
+        public int getHeight() {
+            return 0;
+        }
+
+        @Override
+        public void invalidateView() {
+        }
+
+        @Override
+        public Point createAbsolutePoint(Point relativePoint) {
+            return null;
+        }
+
+        @Override
+        public Rect getAbsoluteRectForChildViewAt(int index) {
+            return null;
+        }
+
+        @Override
+        public int getAdapterPositionAt(int index) {
+            return 0;
+        }
+
+        @Override
+        public int getColumnCount() {
+            return 0;
+        }
+
+        @Override
+        public int getChildCount() {
+            return 0;
+        }
+
+        @Override
+        public int getVisibleChildCount() {
+            return 0;
+        }
+
+        @Override
+        public boolean hasView(int adapterPosition) {
+            return false;
+        }
+    }
+}
diff --git a/tests/unit/com/android/documentsui/DirectoryReloadLockTest.java b/tests/unit/com/android/documentsui/selection/ContentLockTest.java
similarity index 63%
rename from tests/unit/com/android/documentsui/DirectoryReloadLockTest.java
rename to tests/unit/com/android/documentsui/selection/ContentLockTest.java
index dbbc9c6..71b6b0f 100644
--- a/tests/unit/com/android/documentsui/DirectoryReloadLockTest.java
+++ b/tests/unit/com/android/documentsui/selection/ContentLockTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.documentsui;
+package com.android.documentsui.selection;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -28,45 +28,49 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class DirectoryReloadLockTest {
+public class ContentLockTest {
 
-    private DirectoryReloadLock lock = new DirectoryReloadLock();
-    private boolean called;
-    private Runnable callback = () -> {
-        called = true;
+    private ContentLock mLock = new ContentLock();
+    private boolean mCalled;
+
+    private Runnable mRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mCalled = true;
+        }
     };
 
     @Before
     public void setUp() {
-        called = false;
+        mCalled = false;
     }
 
     @Test
     public void testNotBlocking_callbackNotBlocked() {
-        lock.tryUpdate(callback);
-        assertTrue(called);
+        mLock.runWhenUnlocked(mRunnable);
+        assertTrue(mCalled);
     }
 
     @Test
     public void testToggleBlocking_callbackNotBlocked() {
-        lock.block();
-        lock.unblock();
-        lock.tryUpdate(callback);
-        assertTrue(called);
+        mLock.block();
+        mLock.unblock();
+        mLock.runWhenUnlocked(mRunnable);
+        assertTrue(mCalled);
     }
 
     @Test
     public void testBlocking_callbackBlocked() {
-        lock.block();
-        lock.tryUpdate(callback);
-        assertFalse(called);
+        mLock.block();
+        mLock.runWhenUnlocked(mRunnable);
+        assertFalse(mCalled);
     }
 
     @Test
     public void testBlockthenUnblock_callbackNotBlocked() {
-        lock.block();
-        lock.tryUpdate(callback);
-        lock.unblock();
-        assertTrue(called);
+        mLock.block();
+        mLock.runWhenUnlocked(mRunnable);
+        mLock.unblock();
+        assertTrue(mCalled);
     }
 }
diff --git a/tests/unit/com/android/documentsui/selection/DefaultSelectionHelperTest.java b/tests/unit/com/android/documentsui/selection/DefaultSelectionHelperTest.java
new file mode 100644
index 0000000..48c0b2a
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/DefaultSelectionHelperTest.java
@@ -0,0 +1,409 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+import static org.junit.Assert.assertFalse;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseBooleanArray;
+
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestAdapter;
+import com.android.documentsui.selection.testing.TestSelectionObserver;
+import com.android.documentsui.selection.testing.TestStableIdProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DefaultSelectionHelperTest {
+
+    private List<String> mItems;
+    private Set<String> mIgnored;
+    private TestAdapter mAdapter;
+    private DefaultSelectionHelper mHelper;
+    private TestSelectionObserver mListener;
+    private SelectionProbe mSelection;
+
+    @Before
+    public void setUp() throws Exception {
+        mIgnored = new HashSet<>();
+        mItems = TestAdapter.createItemList(100);
+        mListener = new TestSelectionObserver();
+        mAdapter = new TestAdapter();
+        mAdapter.updateTestModelIds(mItems);
+
+        SelectionPredicate canSelect = new SelectionPredicate() {
+
+            @Override
+            public boolean canSetStateForId(String id, boolean nextState) {
+                return !nextState || !mIgnored.contains(id);
+            }
+
+            @Override
+            public boolean canSetStateAtPosition(int position, boolean nextState) {
+                throw new UnsupportedOperationException("Not implemented.");
+            }
+        };
+        mHelper = new DefaultSelectionHelper(
+                DefaultSelectionHelper.MODE_MULTIPLE,
+                mAdapter,
+                new TestStableIdProvider(mAdapter),
+                canSelect);
+
+        mHelper.addObserver(mListener);
+
+        mSelection = new SelectionProbe(mHelper, mListener);
+
+        mIgnored.clear();
+    }
+
+    @Test
+    public void testSelect() {
+        mHelper.select(mItems.get(7));
+
+        mSelection.assertSelection(7);
+    }
+
+    @Test
+    public void testDeselect() {
+        mHelper.select(mItems.get(7));
+        mHelper.deselect(mItems.get(7));
+
+        mSelection.assertNoSelection();
+    }
+
+    @Test
+    public void testSelection_DoNothingOnUnselectableItem() {
+        mIgnored.add(mItems.get(7));
+        boolean selected = mHelper.select(mItems.get(7));
+
+        assertFalse(selected);
+        mSelection.assertNoSelection();
+    }
+
+    @Test
+    public void testSelect_NotifiesListenersOfChange() {
+        mHelper.select(mItems.get(7));
+
+        mListener.assertSelectionChanged();
+    }
+
+    @Test
+    public void testSelect_NotifiesAdapterOfSelect() {
+        mHelper.select(mItems.get(7));
+
+        mAdapter.assertNotifiedOfSelectionChange(7);
+    }
+
+    @Test
+    public void testSelect_NotifiesAdapterOfDeselect() {
+        mHelper.select(mItems.get(7));
+        mAdapter.resetSelectionNotifications();
+        mHelper.deselect(mItems.get(7));
+        mAdapter.assertNotifiedOfSelectionChange(7);
+    }
+
+    @Test
+    public void testDeselect_NotifiesSelectionChanged() {
+        mHelper.select(mItems.get(7));
+        mHelper.deselect(mItems.get(7));
+
+        mListener.assertSelectionChanged();
+    }
+
+    @Test
+    public void testSelection_PersistsOnUpdate() {
+        mHelper.select(mItems.get(7));
+        mAdapter.updateTestModelIds(mItems);
+
+        mSelection.assertSelection(7);
+    }
+
+    @Test
+    public void testSelection_IntersectsWithNewDataSet() {
+        mHelper.select(mItems.get(99));
+        mHelper.select(mItems.get(7));
+
+        mAdapter.updateTestModelIds(TestAdapter.createItemList(50));
+
+        mSelection.assertSelection(7);
+    }
+
+    @Test
+    public void testSetItemsSelected() {
+        mHelper.setItemsSelected(getStringIds(6, 7, 8), true);
+
+        mSelection.assertRangeSelected(6, 8);
+    }
+
+    @Test
+    public void testSetItemsSelected_SkipUnselectableItem() {
+        mIgnored.add(mItems.get(7));
+
+        mHelper.setItemsSelected(getStringIds(6, 7, 8), true);
+
+        mSelection.assertSelected(6);
+        mSelection.assertNotSelected(7);
+        mSelection.assertSelected(8);
+    }
+
+    @Test
+    public void testRangeSelection() {
+        mHelper.startRange(15);
+        mHelper.extendRange(19);
+        mSelection.assertRangeSelection(15, 19);
+    }
+
+    @Test
+    public void testRangeSelection_SkipUnselectableItem() {
+        mIgnored.add(mItems.get(17));
+
+        mHelper.startRange(15);
+        mHelper.extendRange(19);
+
+        mSelection.assertRangeSelected(15, 16);
+        mSelection.assertNotSelected(17);
+        mSelection.assertRangeSelected(18, 19);
+    }
+
+    @Test
+    public void testRangeSelection_snapExpand() {
+        mHelper.startRange(15);
+        mHelper.extendRange(19);
+        mHelper.extendRange(27);
+        mSelection.assertRangeSelection(15, 27);
+    }
+
+    @Test
+    public void testRangeSelection_snapContract() {
+        mHelper.startRange(15);
+        mHelper.extendRange(27);
+        mHelper.extendRange(19);
+        mSelection.assertRangeSelection(15, 19);
+    }
+
+    @Test
+    public void testRangeSelection_snapInvert() {
+        mHelper.startRange(15);
+        mHelper.extendRange(27);
+        mHelper.extendRange(3);
+        mSelection.assertRangeSelection(3, 15);
+    }
+
+    @Test
+    public void testRangeSelection_multiple() {
+        mHelper.startRange(15);
+        mHelper.extendRange(27);
+        mHelper.endRange();
+        mHelper.startRange(42);
+        mHelper.extendRange(57);
+        mSelection.assertSelectionSize(29);
+        mSelection.assertRangeSelected(15, 27);
+        mSelection.assertRangeSelected(42, 57);
+    }
+
+    @Test
+    public void testProvisionalRangeSelection() {
+        mHelper.startRange(13);
+        mHelper.extendProvisionalRange(15);
+        mSelection.assertRangeSelection(13, 15);
+        mHelper.getSelection().mergeProvisionalSelection();
+        mHelper.endRange();
+        mSelection.assertSelectionSize(3);
+    }
+
+    @Test
+    public void testProvisionalRangeSelection_endEarly() {
+        mHelper.startRange(13);
+        mHelper.extendProvisionalRange(15);
+        mSelection.assertRangeSelection(13, 15);
+
+        mHelper.endRange();
+        // If we end range selection prematurely for provision selection, nothing should be selected
+        // except the first item
+        mSelection.assertSelectionSize(1);
+    }
+
+    @Test
+    public void testProvisionalRangeSelection_snapExpand() {
+        mHelper.startRange(13);
+        mHelper.extendProvisionalRange(15);
+        mSelection.assertRangeSelection(13, 15);
+        mHelper.getSelection().mergeProvisionalSelection();
+        mHelper.extendRange(18);
+        mSelection.assertRangeSelection(13, 18);
+    }
+
+    @Test
+    public void testCombinationRangeSelection_IntersectsOldSelection() {
+        mHelper.startRange(13);
+        mHelper.extendRange(15);
+        mSelection.assertRangeSelection(13, 15);
+
+        mHelper.startRange(11);
+        mHelper.extendProvisionalRange(18);
+        mSelection.assertRangeSelected(11, 18);
+        mHelper.endRange();
+        mSelection.assertRangeSelected(13, 15);
+        mSelection.assertRangeSelected(11, 11);
+        mSelection.assertSelectionSize(4);
+    }
+
+    @Test
+    public void testProvisionalSelection() {
+        Selection s = mHelper.getSelection();
+        mSelection.assertNoSelection();
+
+        // Mimicking band selection case -- BandController notifies item callback by itself.
+        mListener.onItemStateChanged(mItems.get(1), true);
+        mListener.onItemStateChanged(mItems.get(2), true);
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        mSelection.assertSelection(1, 2);
+    }
+
+    @Test
+    public void testProvisionalSelection_Replace() {
+        Selection s = mHelper.getSelection();
+
+        // Mimicking band selection case -- BandController notifies item callback by itself.
+        mListener.onItemStateChanged(mItems.get(1), true);
+        mListener.onItemStateChanged(mItems.get(2), true);
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+
+        mListener.onItemStateChanged(mItems.get(1), false);
+        mListener.onItemStateChanged(mItems.get(2), false);
+        provisional.clear();
+
+        mListener.onItemStateChanged(mItems.get(3), true);
+        mListener.onItemStateChanged(mItems.get(4), true);
+        provisional.append(3, true);
+        provisional.append(4, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        mSelection.assertSelection(3, 4);
+    }
+
+    @Test
+    public void testProvisionalSelection_IntersectsExistingProvisionalSelection() {
+        Selection s = mHelper.getSelection();
+
+        // Mimicking band selection case -- BandController notifies item callback by itself.
+        mListener.onItemStateChanged(mItems.get(1), true);
+        mListener.onItemStateChanged(mItems.get(2), true);
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+
+        mListener.onItemStateChanged(mItems.get(1), false);
+        mListener.onItemStateChanged(mItems.get(2), false);
+        provisional.clear();
+
+        mListener.onItemStateChanged(mItems.get(1), true);
+        provisional.append(1, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        mSelection.assertSelection(1);
+    }
+
+    @Test
+    public void testProvisionalSelection_Apply() {
+        Selection s = mHelper.getSelection();
+
+        // Mimicking band selection case -- BandController notifies item callback by itself.
+        mListener.onItemStateChanged(mItems.get(1), true);
+        mListener.onItemStateChanged(mItems.get(2), true);
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        s.mergeProvisionalSelection();
+
+        mSelection.assertSelection(1, 2);
+    }
+
+    @Test
+    public void testProvisionalSelection_Cancel() {
+        mHelper.select(mItems.get(1));
+        mHelper.select(mItems.get(2));
+        Selection s = mHelper.getSelection();
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(3, true);
+        provisional.append(4, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        s.clearProvisionalSelection();
+
+        // Original selection should remain.
+        mSelection.assertSelection(1, 2);
+    }
+
+    @Test
+    public void testProvisionalSelection_IntersectsAppliedSelection() {
+        mHelper.select(mItems.get(1));
+        mHelper.select(mItems.get(2));
+        Selection s = mHelper.getSelection();
+
+        // Mimicking band selection case -- BandController notifies item callback by itself.
+        mListener.onItemStateChanged(mItems.get(3), true);
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(2, true);
+        provisional.append(3, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        mSelection.assertSelection(1, 2, 3);
+    }
+
+    @Test
+    public void testObserverOnChanged_NotifiesListenersOfChange() {
+        mAdapter.notifyDataSetChanged();
+
+        mListener.assertSelectionChanged();
+    }
+
+    private Set<String> getItemIds(SparseBooleanArray selection) {
+        Set<String> ids = new HashSet<>();
+
+        int count = selection.size();
+        for (int i = 0; i < count; ++i) {
+            ids.add(mItems.get(selection.keyAt(i)));
+        }
+
+        return ids;
+    }
+
+    private Iterable<String> getStringIds(int... ids) {
+        List<String> stringIds = new ArrayList<>(ids.length);
+        for (int id : ids) {
+            stringIds.add(mItems.get(id));
+        }
+        return stringIds;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/DefaultSelectionHelper_SingleSelectTest.java b/tests/unit/com/android/documentsui/selection/DefaultSelectionHelper_SingleSelectTest.java
new file mode 100644
index 0000000..563ce87
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/DefaultSelectionHelper_SingleSelectTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.selection.testing.SelectionPredicates;
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestAdapter;
+import com.android.documentsui.selection.testing.TestSelectionObserver;
+import com.android.documentsui.selection.testing.TestStableIdProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DefaultSelectionHelper_SingleSelectTest {
+
+    private List<String> mItems;
+    private SelectionHelper mHelper;
+    private TestSelectionObserver mListener;
+    private SelectionProbe mSelection;
+
+    @Before
+    public void setUp() throws Exception {
+        mItems = TestAdapter.createItemList(100);
+        mListener = new TestSelectionObserver();
+        TestAdapter adapter = new TestAdapter();
+        adapter.updateTestModelIds(mItems);
+
+        mHelper = new DefaultSelectionHelper(
+                DefaultSelectionHelper.MODE_SINGLE,
+                adapter,
+                new TestStableIdProvider(adapter),
+                SelectionPredicates.CAN_SET_ANYTHING);
+
+        mHelper.addObserver(mListener);
+
+        mSelection = new SelectionProbe(mHelper);
+    }
+
+    @Test
+    public void testSimpleSelect() {
+        mHelper.select(mItems.get(3));
+        mHelper.select(mItems.get(4));
+        mListener.assertSelectionChanged();
+        mSelection.assertSelection(4);
+    }
+
+    @Test
+    public void testRangeSelectionNotEstablished() {
+        mHelper.select(mItems.get(3));
+        mListener.reset();
+
+        try {
+            mHelper.extendRange(10);
+            fail("Should have thrown.");
+        } catch (Exception expected) {}
+
+        mListener.assertSelectionUnchanged();
+        mSelection.assertSelection(3);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/GestureRouterTest.java b/tests/unit/com/android/documentsui/selection/GestureRouterTest.java
new file mode 100644
index 0000000..e467f0f
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/GestureRouterTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyFloat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.GestureDetector.OnDoubleTapListener;
+import android.view.GestureDetector.OnGestureListener;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.testing.TestEvents.Mouse;
+import com.android.documentsui.selection.testing.TestEvents.Touch;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class GestureRouterTest {
+
+    private TestHandler mHandler;
+    private TestHandler mAlt;
+    private GestureRouter<TestHandler> mRouter;
+
+    @Before
+    public void setUp() {
+        mAlt = new TestHandler();
+        mHandler = new TestHandler();
+    }
+
+    @Test
+    public void testDelegates() {
+        mRouter = new GestureRouter<>();
+        mRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mHandler);
+        mRouter.register(MotionEvent.TOOL_TYPE_FINGER, mAlt);
+
+        mRouter.onDown(Mouse.CLICK);
+        mHandler.assertCalled_onDown(Mouse.CLICK);
+        mAlt.assertNotCalled_onDown();
+
+        mRouter.onShowPress(Mouse.CLICK);
+        mHandler.assertCalled_onShowPress(Mouse.CLICK);
+        mAlt.assertNotCalled_onShowPress();
+
+        mRouter.onSingleTapUp(Mouse.CLICK);
+        mHandler.assertCalled_onSingleTapUp(Mouse.CLICK);
+        mAlt.assertNotCalled_onSingleTapUp();
+
+        mRouter.onScroll(null, Mouse.CLICK, -1, -1);
+        mHandler.assertCalled_onScroll(null, Mouse.CLICK, -1, -1);
+        mAlt.assertNotCalled_onScroll();
+
+        mRouter.onLongPress(Mouse.CLICK);
+        mHandler.assertCalled_onLongPress(Mouse.CLICK);
+        mAlt.assertNotCalled_onLongPress();
+
+        mRouter.onFling(null, Mouse.CLICK, -1, -1);
+        mHandler.assertCalled_onFling(null, Mouse.CLICK, -1, -1);
+        mAlt.assertNotCalled_onFling();
+
+        mRouter.onSingleTapConfirmed(Mouse.CLICK);
+        mHandler.assertCalled_onSingleTapConfirmed(Mouse.CLICK);
+        mAlt.assertNotCalled_onSingleTapConfirmed();
+
+        mRouter.onDoubleTap(Mouse.CLICK);
+        mHandler.assertCalled_onDoubleTap(Mouse.CLICK);
+        mAlt.assertNotCalled_onDoubleTap();
+
+        mRouter.onDoubleTapEvent(Mouse.CLICK);
+        mHandler.assertCalled_onDoubleTapEvent(Mouse.CLICK);
+        mAlt.assertNotCalled_onDoubleTapEvent();
+    }
+
+    @Test
+    public void testFallsback() {
+        mRouter = new GestureRouter<>(mAlt);
+        mRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mHandler);
+
+        mRouter.onDown(Touch.TAP);
+        mAlt.assertCalled_onDown(Touch.TAP);
+
+        mRouter.onShowPress(Touch.TAP);
+        mAlt.assertCalled_onShowPress(Touch.TAP);
+
+        mRouter.onSingleTapUp(Touch.TAP);
+        mAlt.assertCalled_onSingleTapUp(Touch.TAP);
+
+        mRouter.onScroll(null, Touch.TAP, -1, -1);
+        mAlt.assertCalled_onScroll(null, Touch.TAP, -1, -1);
+
+        mRouter.onLongPress(Touch.TAP);
+        mAlt.assertCalled_onLongPress(Touch.TAP);
+
+        mRouter.onFling(null, Touch.TAP, -1, -1);
+        mAlt.assertCalled_onFling(null, Touch.TAP, -1, -1);
+
+        mRouter.onSingleTapConfirmed(Touch.TAP);
+        mAlt.assertCalled_onSingleTapConfirmed(Touch.TAP);
+
+        mRouter.onDoubleTap(Touch.TAP);
+        mAlt.assertCalled_onDoubleTap(Touch.TAP);
+
+        mRouter.onDoubleTapEvent(Touch.TAP);
+        mAlt.assertCalled_onDoubleTapEvent(Touch.TAP);
+    }
+
+    @Test
+    public void testEatsEventsWhenNoFallback() {
+        mRouter = new GestureRouter<>();
+        // Register the the delegate on mouse so touch events don't get handled.
+        mRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mHandler);
+
+        mRouter.onDown(Touch.TAP);
+        mAlt.assertNotCalled_onDown();
+
+        mRouter.onShowPress(Touch.TAP);
+        mAlt.assertNotCalled_onShowPress();
+
+        mRouter.onSingleTapUp(Touch.TAP);
+        mAlt.assertNotCalled_onSingleTapUp();
+
+        mRouter.onScroll(null, Touch.TAP, -1, -1);
+        mAlt.assertNotCalled_onScroll();
+
+        mRouter.onLongPress(Touch.TAP);
+        mAlt.assertNotCalled_onLongPress();
+
+        mRouter.onFling(null, Touch.TAP, -1, -1);
+        mAlt.assertNotCalled_onFling();
+
+        mRouter.onSingleTapConfirmed(Touch.TAP);
+        mAlt.assertNotCalled_onSingleTapConfirmed();
+
+        mRouter.onDoubleTap(Touch.TAP);
+        mAlt.assertNotCalled_onDoubleTap();
+
+        mRouter.onDoubleTapEvent(Touch.TAP);
+        mAlt.assertNotCalled_onDoubleTapEvent();
+    }
+
+    private static final class TestHandler implements OnGestureListener, OnDoubleTapListener {
+
+        private final Spy mSpy = Mockito.mock(Spy.class);
+
+        @Override
+        public boolean onDown(MotionEvent e) {
+            return mSpy.onDown(e);
+        }
+
+        @Override
+        public void onShowPress(MotionEvent e) {
+            mSpy.onShowPress(e);
+        }
+
+        @Override
+        public boolean onSingleTapUp(MotionEvent e) {
+            return mSpy.onSingleTapUp(e);
+        }
+
+        @Override
+        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+            return mSpy.onScroll(e1, e2, distanceX, distanceY);
+        }
+
+        @Override
+        public void onLongPress(MotionEvent e) {
+            mSpy.onLongPress(e);
+        }
+
+        @Override
+        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+            return mSpy.onFling(e1, e2, velocityX, velocityY);
+        }
+
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            return mSpy.onSingleTapConfirmed(e);
+        }
+
+        @Override
+        public boolean onDoubleTap(MotionEvent e) {
+            return mSpy.onDoubleTap(e);
+        }
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent e) {
+            return mSpy.onDoubleTapEvent(e);
+        }
+
+        void assertCalled_onDown(MotionEvent e) {
+            verify(mSpy).onDown(e);
+        }
+
+        void assertCalled_onShowPress(MotionEvent e) {
+            verify(mSpy).onShowPress(e);
+        }
+
+        void assertCalled_onSingleTapUp(MotionEvent e) {
+            verify(mSpy).onSingleTapUp(e);
+        }
+
+        void assertCalled_onScroll(MotionEvent e1, MotionEvent e2, float x, float y) {
+            verify(mSpy).onScroll(e1, e2, x, y);
+        }
+
+        void assertCalled_onLongPress(MotionEvent e) {
+            verify(mSpy).onLongPress(e);
+        }
+
+        void assertCalled_onFling(MotionEvent e1, MotionEvent e2, float x, float y) {
+            Mockito.verify(mSpy).onFling(e1, e2, x, y);
+        }
+
+        void assertCalled_onSingleTapConfirmed(MotionEvent e) {
+            Mockito.verify(mSpy).onSingleTapConfirmed(e);
+        }
+
+        void assertCalled_onDoubleTap(MotionEvent e) {
+            Mockito.verify(mSpy).onDoubleTap(e);
+        }
+
+        void assertCalled_onDoubleTapEvent(MotionEvent e) {
+            Mockito.verify(mSpy).onDoubleTapEvent(e);
+        }
+
+        void assertNotCalled_onDown() {
+            verify(mSpy, never()).onDown(any());
+        }
+
+        void assertNotCalled_onShowPress() {
+            verify(mSpy, never()).onShowPress(any());
+        }
+
+        void assertNotCalled_onSingleTapUp() {
+            verify(mSpy, never()).onSingleTapUp(any());
+        }
+
+        void assertNotCalled_onScroll() {
+            verify(mSpy, never()).onScroll(any(), any(), anyFloat(), anyFloat());
+        }
+
+        void assertNotCalled_onLongPress() {
+            verify(mSpy, never()).onLongPress(any());
+        }
+
+        void assertNotCalled_onFling() {
+            Mockito.verify(mSpy, never()).onFling(any(), any(), anyFloat(), anyFloat());
+        }
+
+        void assertNotCalled_onSingleTapConfirmed() {
+            Mockito.verify(mSpy, never()).onSingleTapConfirmed(any());
+        }
+
+        void assertNotCalled_onDoubleTap() {
+            Mockito.verify(mSpy, never()).onDoubleTap(any());
+        }
+
+        void assertNotCalled_onDoubleTapEvent() {
+            Mockito.verify(mSpy, never()).onDoubleTapEvent(any());
+        }
+    }
+
+    private static interface Spy extends OnGestureListener, OnDoubleTapListener {}
+}
diff --git a/tests/unit/com/android/documentsui/selection/GestureSelectionHelperTest.java b/tests/unit/com/android/documentsui/selection/GestureSelectionHelperTest.java
new file mode 100644
index 0000000..71b1c14
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/GestureSelectionHelperTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestData;
+import com.android.documentsui.testing.SelectionHelpers;
+import com.android.documentsui.testing.TestEvents;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GestureSelectionHelperTest {
+
+    private static final List<String> ITEMS = TestData.create(100);
+    private static final MotionEvent DOWN = TestEvents.builder()
+            .action(MotionEvent.ACTION_DOWN)
+            .location(1, 1)
+            .build();
+
+    private static final MotionEvent MOVE = TestEvents.builder()
+            .action(MotionEvent.ACTION_MOVE)
+            .location(1, 1)
+            .build();
+
+    private static final MotionEvent UP = TestEvents.builder()
+            .action(MotionEvent.ACTION_UP)
+            .location(1, 1)
+            .build();
+
+    private GestureSelectionHelper mHelper;
+    private SelectionHelper mSelectionHelper;
+    private SelectionProbe mSelection;
+    private ContentLock mLock;
+    private TestViewDelegate mView;
+
+    @Before
+    public void setUp() {
+        mSelectionHelper = SelectionHelpers.createTestInstance(ITEMS);
+        mSelection = new SelectionProbe(mSelectionHelper);
+        mLock = new ContentLock();
+        mView = new TestViewDelegate();
+        mHelper = new GestureSelectionHelper(mSelectionHelper, mView, mLock);
+    }
+
+    @Test
+    public void testIgnoresDownOnNoPosition() {
+        mView.mNextPosition = RecyclerView.NO_POSITION;
+        assertFalse(mHelper.onInterceptTouchEvent(null, DOWN));
+    }
+
+
+    @Test
+    public void testNoStartOnIllegalPosition() {
+        mHelper.onInterceptTouchEvent(null, DOWN);
+        try {
+            mHelper.start();
+            fail("Should have thrown.");
+        } catch (Exception expected) {}
+    }
+
+    @Test
+    public void testClaimsDownOnItem() {
+        mView.mNextPosition = 0;
+        assertTrue(mHelper.onInterceptTouchEvent(null, DOWN));
+    }
+
+    @Test
+    public void testClaimsMoveIfStarted() {
+        mView.mNextPosition = 0;
+        assertTrue(mHelper.onInterceptTouchEvent(null, DOWN));
+
+        // Normally, this is controller by the TouchSelectionHelper via a a long press gesture.
+        mSelectionHelper.select("1");
+        mSelectionHelper.anchorRange(1);
+        mHelper.start();
+        assertTrue(mHelper.onInterceptTouchEvent(null, MOVE));
+    }
+
+    @Test
+    public void testCreatesRangeSelection() {
+        mView.mNextPosition = 1;
+        mHelper.onInterceptTouchEvent(null, DOWN);
+        // Another way we are implicitly coupled to TouchInputHandler, is that we depend on
+        // long press to establish the initial anchor point. Without that we'll get an
+        // error when we try to extend the range.
+
+        mSelectionHelper.select("1");
+        mSelectionHelper.anchorRange(1);
+        mHelper.start();
+
+        mHelper.onTouchEvent(null, MOVE);
+
+        mView.mNextPosition = 9;
+        mHelper.onTouchEvent(null, MOVE);
+        mHelper.onTouchEvent(null, UP);
+
+        mSelection.assertRangeSelected(1,  9);
+    }
+
+    private static final class TestViewDelegate extends GestureSelectionHelper.ViewDelegate {
+
+        private int mNextPosition = RecyclerView.NO_POSITION;
+
+        @Override
+        int getHeight() {
+            return 1000;
+        }
+
+        @Override
+        int getItemUnder(MotionEvent e) {
+            return mNextPosition;
+        }
+
+        @Override
+        int getLastGlidedItemPosition(MotionEvent e) {
+            return mNextPosition;
+        }
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/GestureSelectionHelper_RecyclerViewDelegateTest.java b/tests/unit/com/android/documentsui/selection/GestureSelectionHelper_RecyclerViewDelegateTest.java
new file mode 100644
index 0000000..9e05d0c
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/GestureSelectionHelper_RecyclerViewDelegateTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.documentsui.selection.GestureSelectionHelper.RecyclerViewDelegate;
+import com.android.documentsui.testing.TestEvents;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GestureSelectionHelper_RecyclerViewDelegateTest {
+
+    // Simulate a (20, 20) box locating at (20, 20)
+    static final int LEFT_BORDER = 20;
+    static final int RIGHT_BORDER = 40;
+    static final int TOP_BORDER = 20;
+    static final int BOTTOM_BORDER = 40;
+
+    @Test
+    public void testLtrPastLastItem() {
+        MotionEvent event = createEvent(100, 100);
+        assertTrue(RecyclerViewDelegate.isPastLastItem(
+                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_LTR));
+    }
+
+    @Test
+    public void testLtrPastLastItem_Inverse() {
+        MotionEvent event = createEvent(10, 10);
+        assertFalse(RecyclerViewDelegate.isPastLastItem(
+                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_LTR));
+    }
+
+    @Test
+    public void testRtlPastLastItem() {
+        MotionEvent event = createEvent(10, 30);
+        assertTrue(RecyclerViewDelegate.isPastLastItem(
+                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_RTL));
+    }
+
+    @Test
+    public void testRtlPastLastItem_Inverse() {
+        MotionEvent event = createEvent(100, 100);
+        assertFalse(RecyclerViewDelegate.isPastLastItem(
+                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_RTL));
+    }
+
+    private static MotionEvent createEvent(int x, int y) {
+        return TestEvents.builder().action(MotionEvent.ACTION_MOVE).location(x, y).build();
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/GestureSelectorTest.java b/tests/unit/com/android/documentsui/selection/GestureSelectorTest.java
deleted file mode 100644
index 85a857a..0000000
--- a/tests/unit/com/android/documentsui/selection/GestureSelectorTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.View;
-
-import com.android.documentsui.selection.GestureSelector;
-import com.android.documentsui.testing.TestEvent;
-
-@SmallTest
-public class GestureSelectorTest extends AndroidTestCase {
-
-    TestEvent.Builder e;
-
-    // Simulate a (20, 20) box locating at (20, 20)
-    static final int LEFT_BORDER = 20;
-    static final int RIGHT_BORDER = 40;
-    static final int TOP_BORDER = 20;
-    static final int BOTTOM_BORDER = 40;
-
-    @Override
-    public void setUp() throws Exception {
-        e = TestEvent.builder()
-                .location(100, 100);
-    }
-
-    public void testLTRPastLastItem() {
-        assertTrue(GestureSelector.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e.build(), View.LAYOUT_DIRECTION_LTR));
-    }
-
-    public void testLTRPastLastItem_Inverse() {
-        e.location(10, 10);
-        assertFalse(GestureSelector.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e.build(), View.LAYOUT_DIRECTION_LTR));
-    }
-
-    public void testRTLPastLastItem() {
-        e.location(10, 30);
-        assertTrue(GestureSelector.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e.build(), View.LAYOUT_DIRECTION_RTL));
-    }
-
-    public void testRTLPastLastItem_Inverse() {
-        assertFalse(GestureSelector.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e.build(), View.LAYOUT_DIRECTION_RTL));
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/BandController_GridModelTest.java b/tests/unit/com/android/documentsui/selection/GridModelTest.java
similarity index 78%
rename from tests/unit/com/android/documentsui/selection/BandController_GridModelTest.java
rename to tests/unit/com/android/documentsui/selection/GridModelTest.java
index 4ce161d..1cb2900 100644
--- a/tests/unit/com/android/documentsui/selection/BandController_GridModelTest.java
+++ b/tests/unit/com/android/documentsui/selection/GridModelTest.java
@@ -16,33 +16,45 @@
 
 package com.android.documentsui.selection;
 
-import static com.android.documentsui.selection.BandController.GridModel.NOT_SET;
+import static com.android.documentsui.selection.GridModel.NOT_SET;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.v7.widget.RecyclerView.OnScrollListener;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.documentsui.dirlist.TestDocumentsAdapter;
-import com.android.documentsui.selection.BandController.GridModel;
+import com.android.documentsui.selection.BandSelectionHelper.BandHost;
+import com.android.documentsui.selection.testing.SelectionPredicates;
+import com.android.documentsui.selection.testing.TestAdapter;
+import com.android.documentsui.selection.testing.TestStableIdProvider;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
+import javax.annotation.Nullable;
+
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class BandController_GridModelTest extends AndroidTestCase {
+public class GridModelTest {
 
     private static final int VIEW_PADDING_PX = 5;
     private static final int CHILD_VIEW_EDGE_PX = 100;
     private static final int VIEWPORT_HEIGHT = 500;
 
-    private GridModel model;
-    private TestEnvironment env;
-    private TestDocumentsAdapter adapter;
-    private Set<String> lastSelection;
-    private int viewWidth;
+    private GridModel mModel;
+    private TestHost mHost;
+    private TestAdapter mAdapter;
+    private Set<String> mLastSelection;
+    private int mViewWidth;
 
     // TLDR: Don't call model.{start|resize}Selection; use the local #startSelection and
     // #resizeSelection methods instead.
@@ -55,91 +67,68 @@
     private Point mSelectionOrigin;
     private Point mSelectionPoint;
 
-    private void initData(final int numChildren, int numColumns) {
-        env = new TestEnvironment(numChildren, numColumns);
-        adapter = new TestDocumentsAdapter(new ArrayList<String>()) {
-            @Override
-            public String getModelId(int position) {
-                return Integer.toString(position);
-            }
-
-            @Override
-            public int getItemCount() {
-                return numChildren;
-            }
-        };
-
-        viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
-        model = new GridModel(env, (int pos) -> true, adapter);
-        model.addOnSelectionChangedListener(
-                new GridModel.OnSelectionChangedListener() {
-                    @Override
-                    public void onSelectionChanged(Set<String> updatedSelection) {
-                        lastSelection = updatedSelection;
-                    }
-
-                    @Override
-                    public boolean onBeforeItemStateChange(String id, boolean nextState) {
-                        return true;
-                    }
-                });
-    }
-
-    @Override
+    @After
     public void tearDown() {
-        model = null;
-        env = null;
-        lastSelection = null;
+        mModel = null;
+        mHost = null;
+        mLastSelection = null;
     }
 
+    @Test
     public void testSelectionLeftOfItems() {
         initData(20, 5);
         startSelection(new Point(0, 10));
         resizeSelection(new Point(1, 11));
         assertNoSelection();
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testSelectionRightOfItems() {
         initData(20, 4);
-        startSelection(new Point(viewWidth - 1, 10));
-        resizeSelection(new Point(viewWidth - 2, 11));
+        startSelection(new Point(mViewWidth - 1, 10));
+        resizeSelection(new Point(mViewWidth - 2, 11));
         assertNoSelection();
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testSelectionAboveItems() {
         initData(20, 4);
         startSelection(new Point(10, 0));
         resizeSelection(new Point(11, 1));
         assertNoSelection();
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testSelectionBelowItems() {
         initData(5, 4);
         startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
         resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
         assertNoSelection();
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testVerticalSelectionBetweenItems() {
         initData(20, 4);
         startSelection(new Point(106, 0));
         resizeSelection(new Point(107, 200));
         assertNoSelection();
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testHorizontalSelectionBetweenItems() {
         initData(20, 4);
         startSelection(new Point(0, 105));
         resizeSelection(new Point(200, 106));
         assertNoSelection();
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testGrowingAndShrinkingSelection() {
         initData(20, 4);
         startSelection(new Point(0, 0));
@@ -180,14 +169,15 @@
         resizeSelection(new Point(0, 0));
         verifySelection();
 
-        assertEquals(NOT_SET, model.getPositionNearestOrigin());
+        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testSelectionMovingAroundOrigin() {
         initData(16, 4);
 
         startSelection(new Point(210, 210));
-        resizeSelection(new Point(viewWidth - 1, 0));
+        resizeSelection(new Point(mViewWidth - 1, 0));
         verifySelection();
 
         resizeSelection(new Point(0, 0));
@@ -196,14 +186,15 @@
         resizeSelection(new Point(0, 420));
         verifySelection();
 
-        resizeSelection(new Point(viewWidth - 1, 420));
+        resizeSelection(new Point(mViewWidth - 1, 420));
         verifySelection();
 
         // This is manually figured and will need to be adjusted if the separator position is
         // changed.
-        assertEquals(7, model.getPositionNearestOrigin());
+        assertEquals(7, mModel.getPositionNearestOrigin());
     }
 
+    @Test
     public void testScrollingBandSelect() {
         initData(40, 4);
 
@@ -226,7 +217,37 @@
         resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
         verifySelection();
 
-        assertEquals(0, model.getPositionNearestOrigin());
+        assertEquals(0, mModel.getPositionNearestOrigin());
+    }
+
+    private void initData(final int numChildren, int numColumns) {
+        mHost = new TestHost(numChildren, numColumns);
+        mAdapter = new TestAdapter() {
+            @Override
+            public String getStableId(int position) {
+                return Integer.toString(position);
+            }
+
+            @Override
+            public int getItemCount() {
+                return numChildren;
+            }
+        };
+
+        mViewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
+
+        mModel = new GridModel(
+                mHost,
+                new TestStableIdProvider(mAdapter),
+                SelectionPredicates.CAN_SET_ANYTHING);
+
+        mModel.addOnSelectionChangedListener(
+                new GridModel.SelectionObserver() {
+                    @Override
+                    public void onSelectionChanged(Set<String> updatedSelection) {
+                        mLastSelection = updatedSelection;
+                    }
+                });
     }
 
     /** Returns the current selection area as a Rect. */
@@ -244,43 +265,43 @@
 
     /** Asserts that the selection is currently empty. */
     private void assertNoSelection() {
-        assertEquals("Unexpected items " + lastSelection + " in selection " + getSelectionArea(),
-                0, lastSelection.size());
+        assertEquals("Unexpected items " + mLastSelection + " in selection " + getSelectionArea(),
+                0, mLastSelection.size());
     }
 
     /** Verifies the selection using actual bbox checks. */
     private void verifySelection() {
         Rect selectionArea = getSelectionArea();
-        for (TestEnvironment.Item item: env.items) {
+        for (TestHost.Item item: mHost.items) {
             if (Rect.intersects(selectionArea, item.rect)) {
                 assertTrue("Expected item " + item + " was not in selection " + selectionArea,
-                        lastSelection.contains(item.name));
+                        mLastSelection.contains(item.name));
             } else {
                 assertFalse("Unexpected item " + item + " in selection" + selectionArea,
-                        lastSelection.contains(item.name));
+                        mLastSelection.contains(item.name));
             }
         }
     }
 
     private void startSelection(Point p) {
-        model.startSelection(p);
-        mSelectionOrigin = env.createAbsolutePoint(p);
+        mModel.startCapturing(p);
+        mSelectionOrigin = mHost.createAbsolutePoint(p);
     }
 
     private void resizeSelection(Point p) {
-        model.resizeSelection(p);
-        mSelectionPoint = env.createAbsolutePoint(p);
+        mModel.resizeSelection(p);
+        mSelectionPoint = mHost.createAbsolutePoint(p);
     }
 
     private void scroll(int dy) {
-        assertTrue(env.verticalOffset + VIEWPORT_HEIGHT + dy <= env.getTotalHeight());
-        env.verticalOffset += dy;
+        assertTrue(mHost.verticalOffset + VIEWPORT_HEIGHT + dy <= mHost.getTotalHeight());
+        mHost.verticalOffset += dy;
         // Correct the cached selection point as well.
         mSelectionPoint.y += dy;
-        model.onScrolled(null, 0, dy);
+        mHost.mScrollListener.onScrolled(null, 0, dy);
     }
 
-    private static final class TestEnvironment implements BandController.SelectionEnvironment {
+    private static final class TestHost extends BandHost {
 
         private final int mNumColumns;
         private final int mNumRows;
@@ -291,7 +312,10 @@
         public int verticalOffset = 0;
         private List<Item> items = new ArrayList<>();
 
-        public TestEnvironment(int numChildren, int numColumns) {
+        // Installed by GridModel on construction.
+        private @Nullable OnScrollListener mScrollListener;
+
+        public TestHost(int numChildren, int numColumns) {
             mNumChildren = numChildren;
             mNumColumns = numColumns;
             mSeparatorPosition = mNumColumns + 1;
@@ -363,7 +387,9 @@
         }
 
         @Override
-        public void addOnScrollListener(OnScrollListener listener) {}
+        public void addOnScrollListener(OnScrollListener listener) {
+            mScrollListener = listener;
+        }
 
         @Override
         public void removeOnScrollListener(OnScrollListener listener) {}
@@ -458,6 +484,7 @@
                 rect = r;
             }
 
+            @Override
             public String toString() {
                 return name + ": " + rect;
             }
diff --git a/tests/unit/com/android/documentsui/selection/MouseInputHandlerTest.java b/tests/unit/com/android/documentsui/selection/MouseInputHandlerTest.java
new file mode 100644
index 0000000..f1bf556
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/MouseInputHandlerTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static com.android.documentsui.testing.TestEvents.Mouse.ALT_CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.CTRL_CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.SECONDARY_CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.SHIFT_CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.TERTIARY_CLICK;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.testing.SelectionHelpers;
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestData;
+import com.android.documentsui.selection.testing.TestEvents;
+import com.android.documentsui.selection.testing.TestMouseCallbacks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class MouseInputHandlerTest {
+
+    private static final List<String> ITEMS = TestData.create(100);
+
+    private MouseInputHandler mInputDelegate;
+    private TestMouseCallbacks mCallbacks;
+    private TestItemDetailsLookup mDetailsLookup;
+    private SelectionProbe mSelection;
+    private SelectionHelper mSelectionMgr;
+
+    private TestEvents.Builder mEvent;
+
+    @Before
+    public void setUp() {
+
+        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
+        mDetailsLookup = new TestItemDetailsLookup();
+        mSelection = new SelectionProbe(mSelectionMgr);
+
+        mCallbacks = new TestMouseCallbacks();
+        mInputDelegate = new MouseInputHandler(mSelectionMgr, mDetailsLookup, mCallbacks);
+
+        mEvent = TestEvents.builder().mouse();
+        mDetailsLookup.initAt(RecyclerView.NO_POSITION);
+    }
+
+    @Test
+    public void testConfirmedClick_StartsSelection() {
+        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mSelection.assertSelection(11);
+    }
+
+    @Test
+    public void testClickOnSelectRegion_AddsToSelection() {
+        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(10).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapUp(CLICK);
+
+        mSelection.assertSelected(10, 11);
+    }
+
+    @Test
+    public void testClickOnIconOfSelectedItem_RemovesFromSelection() {
+        mDetailsLookup.initAt(8).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+        mSelection.assertSelected(8, 9, 10, 11);
+
+        mDetailsLookup.initAt(9);
+        mInputDelegate.onSingleTapUp(CLICK);
+        mSelection.assertSelected(8, 10, 11);
+    }
+
+    @Test
+    public void testRightClickDown_StartsContextMenu() {
+        mInputDelegate.onDown(SECONDARY_CLICK);
+
+        mCallbacks.assertLastEvent(SECONDARY_CLICK);
+    }
+
+    @Test
+    public void testAltClickDown_StartsContextMenu() {
+        mInputDelegate.onDown(ALT_CLICK);
+
+        mCallbacks.assertLastEvent(ALT_CLICK);
+    }
+
+    @Test
+    public void testScroll_shouldTrap() {
+        mDetailsLookup.initAt(0);
+        assertTrue(mInputDelegate.onScroll(
+                null,
+                mEvent.action(MotionEvent.ACTION_MOVE).primary().build(),
+                -1,
+                -1));
+    }
+
+    @Test
+    public void testScroll_NoTrapForTwoFinger() {
+        mDetailsLookup.initAt(0);
+        assertFalse(mInputDelegate.onScroll(
+                null,
+                mEvent.action(MotionEvent.ACTION_MOVE).build(),
+                -1,
+                -1));
+    }
+
+    @Test
+    public void testUnconfirmedCtrlClick_AddsToExistingSelection() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(CTRL_CLICK);
+
+        mSelection.assertSelection(7, 11);
+    }
+
+    @Test
+    public void testUnconfirmedShiftClick_ExtendsSelection() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertSelection(7, 8, 9, 10, 11);
+    }
+
+    @Test
+    public void testConfirmedShiftClick_ExtendsSelectionFromOriginFocus() {
+        TestItemDetails item = mDetailsLookup.initAt(7);
+        mCallbacks.focusItem(item);
+
+        // This is a hack-y test, since the real FocusManager would've set range begin itself.
+        mSelectionMgr.anchorRange(7);
+        mSelection.assertNoSelection();
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapConfirmed(SHIFT_CLICK);
+        mSelection.assertSelection(7, 8, 9, 10, 11);
+    }
+
+    @Test
+    public void testUnconfirmedShiftClick_RotatesAroundOrigin() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+        mSelection.assertSelection(7, 8, 9, 10, 11);
+
+        mDetailsLookup.initAt(5);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertSelection(5, 6, 7);
+        mSelection.assertNotSelected(8, 9, 10, 11);
+    }
+
+    @Test
+    public void testUnconfirmedShiftCtrlClick_Combination() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+        mSelection.assertSelection(7, 8, 9, 10, 11);
+
+        mDetailsLookup.initAt(5);
+        mInputDelegate.onSingleTapUp(CTRL_CLICK);
+
+        mSelection.assertSelection(5, 7, 8, 9, 10, 11);
+    }
+
+    @Test
+    public void testUnconfirmedShiftCtrlClick_ShiftTakesPriority() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(mEvent.ctrl().shift().build());
+
+        mSelection.assertSelection(7, 8, 9, 10, 11);
+    }
+
+    // TODO: Add testSpaceBar_Previews, but we need to set a system property
+    // to have a deterministic state.
+
+    @Test
+    public void testDoubleClick_Opens() {
+        TestItemDetails doc = mDetailsLookup.initAt(11);
+        mInputDelegate.onDoubleTap(CLICK);
+
+        mCallbacks.assertActivated(doc);
+    }
+
+    @Test
+    public void testMiddleClick_DoesNothing() {
+        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(TERTIARY_CLICK);
+
+        mSelection.assertNoSelection();
+    }
+
+    @Test
+    public void testClickOff_ClearsSelection() {
+        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(RecyclerView.NO_POSITION);
+        mInputDelegate.onSingleTapUp(CLICK);
+
+        mSelection.assertNoSelection();
+    }
+
+    @Test
+    public void testClick_Focuses() {
+        mDetailsLookup.initAt(11).setInItemSelectRegion(false);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mCallbacks.assertHasFocus(true);
+        mCallbacks.assertFocused("11");
+    }
+
+    @Test
+    public void testClickOff_ClearsFocus() {
+        mDetailsLookup.initAt(11).setInItemSelectRegion(false);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+        mCallbacks.assertHasFocus(true);
+
+        mDetailsLookup.initAt(RecyclerView.NO_POSITION);
+        mInputDelegate.onSingleTapUp(CLICK);
+        mCallbacks.assertHasFocus(false);
+    }
+
+    @Test
+    public void testClickOffSelection_RemovesSelectionAndFocuses() {
+        mDetailsLookup.initAt(1).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(5);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertSelection(1, 2, 3, 4, 5);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(CLICK);
+
+        mCallbacks.assertFocused("11");
+        mSelection.assertNoSelection();
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/MouseInputHandler_RangeTest.java b/tests/unit/com/android/documentsui/selection/MouseInputHandler_RangeTest.java
new file mode 100644
index 0000000..939e778
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/MouseInputHandler_RangeTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static com.android.documentsui.testing.TestEvents.Mouse.CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.SECONDARY_CLICK;
+import static com.android.documentsui.testing.TestEvents.Mouse.SHIFT_CLICK;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.testing.SelectionHelpers;
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestData;
+import com.android.documentsui.selection.testing.TestMouseCallbacks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * MouseInputDelegate / SelectHelper integration test covering the shared
+ * responsibility of range selection.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class MouseInputHandler_RangeTest {
+
+    private static final List<String> ITEMS = TestData.create(100);
+
+    private MouseInputHandler mInputDelegate;
+    private SelectionHelper mSelectionMgr;
+    private SelectionProbe mSelection;
+    private TestMouseCallbacks mCallbacks;
+    private TestItemDetailsLookup mDetailsLookup;
+
+    @Before
+    public void setUp() {
+        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
+        mDetailsLookup = new TestItemDetailsLookup();
+        mSelection = new SelectionProbe(mSelectionMgr);
+
+        mCallbacks = new TestMouseCallbacks();
+        mInputDelegate = new MouseInputHandler(mSelectionMgr, mDetailsLookup, mCallbacks);
+    }
+
+    @Test
+    public void testExtendRange() {
+        // uni-click just focuses.
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(7, 11);
+    }
+
+    @Test
+    public void testExtendRangeContinues() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mDetailsLookup.initAt(21);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(7, 21);
+    }
+
+    @Test
+    public void testMultipleContiguousRanges() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        // click without shift sets a new range start point.
+        TestItemDetails item = mDetailsLookup.initAt(20);
+        mInputDelegate.onSingleTapUp(CLICK);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mCallbacks.focusItem(item);
+
+        mDetailsLookup.initAt(25);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+        mInputDelegate.onSingleTapConfirmed(SHIFT_CLICK);
+
+        mSelection.assertRangeNotSelected(7, 11);
+        mSelection.assertRangeSelected(20, 25);
+        mSelection.assertSelectionSize(6);
+    }
+
+    @Test
+    public void testReducesSelectionRange() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(17);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mDetailsLookup.initAt(10);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(7, 10);
+    }
+
+    @Test
+    public void testReducesSelectionRange_Reverse() {
+        mDetailsLookup.initAt(17).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(7);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mDetailsLookup.initAt(14);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(14, 17);
+    }
+
+    @Test
+    public void testExtendsRange_Reverse() {
+        mDetailsLookup.initAt(12).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(5);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(5, 12);
+    }
+
+    @Test
+    public void testExtendsRange_ReversesAfterForwardClick() {
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapConfirmed(CLICK);
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mDetailsLookup.initAt(0);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(0, 7);
+    }
+
+    @Test
+    public void testRightClickEstablishesRange() {
+
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onDown(SECONDARY_CLICK);
+        // This next method call simulates the behavior of the system event dispatch code.
+        // UserInputHandler depends on a specific sequence of events for internal
+        // state to remain valid. It's not an awesome arrangement, but it is currently
+        // necessary.
+        //
+        // See: UserInputHandler.MouseDelegate#mHandledOnDown;
+        mInputDelegate.onSingleTapUp(SECONDARY_CLICK);
+
+        mDetailsLookup.initAt(11);
+        // Now we can send a subsequent event that should extend selection.
+        mInputDelegate.onDown(SHIFT_CLICK);
+        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
+
+        mSelection.assertRangeSelection(7, 11);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/SelectionManagerTest.java b/tests/unit/com/android/documentsui/selection/SelectionManagerTest.java
deleted file mode 100644
index 987780e..0000000
--- a/tests/unit/com/android/documentsui/selection/SelectionManagerTest.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.SparseBooleanArray;
-
-import com.android.documentsui.dirlist.TestDocumentsAdapter;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.dirlist.TestData;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.testing.SelectionManagers;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SelectionManagerTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private final Set<String> mIgnored = new HashSet<>();
-    private TestDocumentsAdapter mAdapter;
-    private SelectionManager mManager;
-    private TestSelectionListener mCallback;
-    private TestItemSelectionListener mItemCallback;
-    private SelectionProbe mSelection;
-
-    @Before
-    public void setUp() throws Exception {
-        mCallback = new TestSelectionListener();
-        mItemCallback = new TestItemSelectionListener();
-        mAdapter = new TestDocumentsAdapter(ITEMS);
-        mManager = SelectionManagers.createTestInstance(
-                mAdapter,
-                SelectionManager.MODE_MULTIPLE,
-                (String id, boolean nextState) -> (!nextState || !mIgnored.contains(id)));
-        mManager.addCallback(mCallback);
-        mManager.addItemCallback(mItemCallback);
-
-        mSelection = new SelectionProbe(mManager, mItemCallback);
-
-        mIgnored.clear();
-    }
-
-    @Test
-    public void testSelection() {
-        // Check selection.
-        mManager.toggleSelection(ITEMS.get(7));
-        mSelection.assertSelection(7);
-        // Check deselection.
-        mManager.toggleSelection(ITEMS.get(7));
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testSelection_DoNothingOnUnselectableItem() {
-        mIgnored.add(ITEMS.get(7));
-
-        mManager.toggleSelection(ITEMS.get(7));
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testSelection_NotifiesSelectionChanged() {
-        // Selection should notify.
-        mManager.toggleSelection(ITEMS.get(7));
-        mCallback.assertSelectionChanged();
-        // Deselection should notify.
-        mManager.toggleSelection(ITEMS.get(7));
-        mCallback.assertSelectionChanged();
-    }
-
-    @Test
-    public void testSelection_PersistsOnUpdate() {
-        mManager.toggleSelection(ITEMS.get(7));
-
-        mAdapter.updateTestModelIds(ITEMS);
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testSelection_IntersectsWithNewDataSet() {
-        mManager.toggleSelection(ITEMS.get(99));
-        mManager.toggleSelection(ITEMS.get(7));
-
-        mAdapter.updateTestModelIds(TestData.create(50));
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testSetItemsSelected() {
-        mManager.setItemsSelected(getStringIds(6, 7, 8), true);
-
-        mSelection.assertRangeSelected(6, 8);
-    }
-
-    @Test
-    public void testSetItemsSelected_SkipUnselectableItem() {
-        mIgnored.add(ITEMS.get(7));
-
-        mManager.setItemsSelected(getStringIds(6, 7, 8), true);
-
-        mSelection.assertSelected(6);
-        mSelection.assertNotSelected(7);
-        mSelection.assertSelected(8);
-    }
-
-    @Test
-    public void testRangeSelection() {
-        mManager.startRangeSelection(15);
-        mManager.snapRangeSelection(19);
-        mSelection.assertRangeSelection(15, 19);
-    }
-
-    @Test
-    public void testRangeSelection_SkipUnselectableItem() {
-        mIgnored.add(ITEMS.get(17));
-
-        mManager.startRangeSelection(15);
-        mManager.snapRangeSelection(19);
-
-        mSelection.assertRangeSelected(15, 16);
-        mSelection.assertNotSelected(17);
-        mSelection.assertRangeSelected(18, 19);
-    }
-
-    @Test
-    public void testRangeSelection_snapExpand() {
-        mManager.startRangeSelection(15);
-        mManager.snapRangeSelection(19);
-        mManager.snapRangeSelection(27);
-        mSelection.assertRangeSelection(15, 27);
-    }
-
-    @Test
-    public void testRangeSelection_snapContract() {
-        mManager.startRangeSelection(15);
-        mManager.snapRangeSelection(27);
-        mManager.snapRangeSelection(19);
-        mSelection.assertRangeSelection(15, 19);
-    }
-
-    @Test
-    public void testRangeSelection_snapInvert() {
-        mManager.startRangeSelection(15);
-        mManager.snapRangeSelection(27);
-        mManager.snapRangeSelection(3);
-        mSelection.assertRangeSelection(3, 15);
-    }
-
-    @Test
-    public void testRangeSelection_multiple() {
-        mManager.startRangeSelection(15);
-        mManager.snapRangeSelection(27);
-        mManager.endRangeSelection();
-        mManager.startRangeSelection(42);
-        mManager.snapRangeSelection(57);
-        mSelection.assertSelectionSize(29);
-        mSelection.assertRangeSelected(15, 27);
-        mSelection.assertRangeSelected(42, 57);
-    }
-
-    @Test
-    public void testProvisionalRangeSelection() {
-        mManager.startRangeSelection(13);
-        mManager.snapProvisionalRangeSelection(15);
-        mSelection.assertRangeSelection(13, 15);
-        mManager.getSelection().applyProvisionalSelection();
-        mManager.endRangeSelection();
-        mSelection.assertSelectionSize(3);
-    }
-
-    @Test
-    public void testProvisionalRangeSelection_endEarly() {
-        mManager.startRangeSelection(13);
-        mManager.snapProvisionalRangeSelection(15);
-        mSelection.assertRangeSelection(13, 15);
-
-        mManager.endRangeSelection();
-        // If we end range selection prematurely for provision selection, nothing should be selected
-        // except the first item
-        mSelection.assertSelectionSize(1);
-    }
-
-    @Test
-    public void testProvisionalRangeSelection_snapExpand() {
-        mManager.startRangeSelection(13);
-        mManager.snapProvisionalRangeSelection(15);
-        mSelection.assertRangeSelection(13, 15);
-        mManager.getSelection().applyProvisionalSelection();
-        mManager.snapRangeSelection(18);
-        mSelection.assertRangeSelection(13, 18);
-    }
-
-    @Test
-    public void testCombinationRangeSelection_IntersectsOldSelection() {
-        mManager.startRangeSelection(13);
-        mManager.snapRangeSelection(15);
-        mSelection.assertRangeSelection(13, 15);
-
-        mManager.startRangeSelection(11);
-        mManager.snapProvisionalRangeSelection(18);
-        mSelection.assertRangeSelected(11, 18);
-        mManager.endRangeSelection();
-        mSelection.assertRangeSelected(13, 15);
-        mSelection.assertRangeSelected(11, 11);
-        mSelection.assertSelectionSize(4);
-    }
-
-    @Test
-    public void testProvisionalSelection() {
-        Selection s = mManager.getSelection();
-        mSelection.assertNoSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mItemCallback.onItemStateChanged(ITEMS.get(1), true);
-        mItemCallback.onItemStateChanged(ITEMS.get(2), true);
-
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(1, 2);
-    }
-
-    @Test
-    public void testProvisionalSelection_Replace() {
-        Selection s = mManager.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mItemCallback.onItemStateChanged(ITEMS.get(1), true);
-        mItemCallback.onItemStateChanged(ITEMS.get(2), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-
-        mItemCallback.onItemStateChanged(ITEMS.get(1), false);
-        mItemCallback.onItemStateChanged(ITEMS.get(2), false);
-        provisional.clear();
-
-        mItemCallback.onItemStateChanged(ITEMS.get(3), true);
-        mItemCallback.onItemStateChanged(ITEMS.get(4), true);
-        provisional.append(3, true);
-        provisional.append(4, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(3, 4);
-    }
-
-    @Test
-    public void testProvisionalSelection_IntersectsExistingProvisionalSelection() {
-        Selection s = mManager.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mItemCallback.onItemStateChanged(ITEMS.get(1), true);
-        mItemCallback.onItemStateChanged(ITEMS.get(2), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-
-        mItemCallback.onItemStateChanged(ITEMS.get(1), false);
-        mItemCallback.onItemStateChanged(ITEMS.get(2), false);
-        provisional.clear();
-
-        mItemCallback.onItemStateChanged(ITEMS.get(1), true);
-        provisional.append(1, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(1);
-    }
-
-    @Test
-    public void testProvisionalSelection_Apply() {
-        Selection s = mManager.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mItemCallback.onItemStateChanged(ITEMS.get(1), true);
-        mItemCallback.onItemStateChanged(ITEMS.get(2), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        s.applyProvisionalSelection();
-
-        mSelection.assertSelection(1, 2);
-    }
-
-    @Test
-    public void testProvisionalSelection_Cancel() {
-        mManager.toggleSelection(ITEMS.get(1));
-        mManager.toggleSelection(ITEMS.get(2));
-        Selection s = mManager.getSelection();
-
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(3, true);
-        provisional.append(4, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        s.cancelProvisionalSelection();
-
-        // Original selection should remain.
-        mSelection.assertSelection(1, 2);
-    }
-
-    @Test
-    public void testProvisionalSelection_IntersectsAppliedSelection() {
-        mManager.toggleSelection(ITEMS.get(1));
-        mManager.toggleSelection(ITEMS.get(2));
-        Selection s = mManager.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mItemCallback.onItemStateChanged(ITEMS.get(3), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(2, true);
-        provisional.append(3, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(1, 2, 3);
-    }
-
-    private static Set<String> getItemIds(SparseBooleanArray selection) {
-        Set<String> ids = new HashSet<>();
-
-        int count = selection.size();
-        for (int i = 0; i < count; ++i) {
-            ids.add(ITEMS.get(selection.keyAt(i)));
-        }
-
-        return ids;
-    }
-
-    private static Iterable<String> getStringIds(int... ids) {
-        List<String> stringIds = new ArrayList<>(ids.length);
-        for (int id : ids) {
-            stringIds.add(ITEMS.get(id));
-        }
-        return stringIds;
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/SelectionManager_SingleSelectTest.java b/tests/unit/com/android/documentsui/selection/SelectionManager_SingleSelectTest.java
deleted file mode 100644
index b25c1c0..0000000
--- a/tests/unit/com/android/documentsui/selection/SelectionManager_SingleSelectTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.documentsui.selection;
-
-import static junit.framework.Assert.fail;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.documentsui.dirlist.TestData;
-import com.android.documentsui.dirlist.TestDocumentsAdapter;
-import com.android.documentsui.selection.SelectionManager;
-import com.android.documentsui.testing.SelectionManagers;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SelectionManager_SingleSelectTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private SelectionManager mManager;
-    private TestSelectionListener mCallback;
-    private TestDocumentsAdapter mAdapter;
-    private SelectionProbe mSelection;
-
-    @Before
-    public void setUp() throws Exception {
-        mCallback = new TestSelectionListener();
-        mManager = SelectionManagers.createTestInstance(ITEMS, SelectionManager.MODE_SINGLE);
-        mManager.addCallback(mCallback);
-
-        mSelection = new SelectionProbe(mManager);
-    }
-
-    @Test
-    public void testSimpleSelect() {
-        mManager.toggleSelection(ITEMS.get(3));
-        mManager.toggleSelection(ITEMS.get(4));
-        mCallback.assertSelectionChanged();
-        mSelection.assertSelection(4);
-    }
-
-    @Test
-    public void testRangeSelectionNotEstablished() {
-        mManager.toggleSelection(ITEMS.get(3));
-        mCallback.reset();
-
-        try {
-            mManager.snapRangeSelection(10);
-            fail("Should have thrown.");
-        } catch (Exception expected) {}
-
-        mCallback.assertSelectionUnchanged();
-        mSelection.assertSelection(3);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/SelectionTest.java b/tests/unit/com/android/documentsui/selection/SelectionTest.java
index ad1422a..fcf525b 100644
--- a/tests/unit/com/android/documentsui/selection/SelectionTest.java
+++ b/tests/unit/com/android/documentsui/selection/SelectionTest.java
@@ -23,8 +23,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.documentsui.selection.Selection;
-
 import com.google.common.collect.Sets;
 
 import org.junit.Before;
diff --git a/tests/unit/com/android/documentsui/selection/TestItemDetails.java b/tests/unit/com/android/documentsui/selection/TestItemDetails.java
new file mode 100644
index 0000000..b943247
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/TestItemDetails.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.internal.widget.RecyclerView;
+
+public final class TestItemDetails extends ItemDetails {
+
+    // DocumentsAdapter.ITEM_TYPE_DOCUMENT
+    private int mViewType = -1;
+    private int mPosition;
+    private String mStableId;
+    private boolean mInDragRegion;
+    private boolean mInSelectionHotspot;
+
+    public TestItemDetails() {
+       mPosition = RecyclerView.NO_POSITION;
+    }
+
+    public TestItemDetails(TestItemDetails source) {
+        mPosition = source.mPosition;
+        mStableId = source.mStableId;
+        mViewType = source.mViewType;
+        mInDragRegion = source.mInDragRegion;
+        mInSelectionHotspot = source.mInSelectionHotspot;
+    }
+
+    public void setViewType(int viewType) {
+        mViewType = viewType;
+    }
+
+    public void at(int position) {
+        mPosition = position;  // this is both "adapter position" and "item position".
+        mStableId = (position == RecyclerView.NO_POSITION)
+                ? null
+                : String.valueOf(position);
+    }
+
+    public void setInItemDragRegion(boolean inHotspot) {
+        mInDragRegion = inHotspot;
+    }
+
+    public void setInItemSelectRegion(boolean over) {
+        mInSelectionHotspot = over;
+    }
+
+    @Override
+    public int getItemViewType() {
+        return mViewType;
+    }
+
+    @Override
+    public boolean inDragRegion(MotionEvent event) {
+        return mInDragRegion;
+    }
+
+    @Override
+    public int hashCode() {
+        return mPosition;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) {
+          return true;
+      }
+
+      if (!(o instanceof TestItemDetails)) {
+          return false;
+      }
+
+      TestItemDetails other = (TestItemDetails) o;
+      return mPosition == other.mPosition
+              && mStableId == other.mStableId
+              && mViewType == other.mViewType;
+    }
+
+    @Override
+    public int getPosition() {
+        return mPosition;
+    }
+
+    @Override
+    public String getStableId() {
+        return mStableId;
+    }
+
+    @Override
+    public boolean inSelectionHotspot(MotionEvent e) {
+        return mInSelectionHotspot;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/TestItemDetailsLookup.java b/tests/unit/com/android/documentsui/selection/TestItemDetailsLookup.java
new file mode 100644
index 0000000..982575c
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/TestItemDetailsLookup.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import javax.annotation.Nullable;
+
+/**
+ * Test impl of ItemDetailsLookup.
+ */
+public class TestItemDetailsLookup extends ItemDetailsLookup {
+
+    private @Nullable TestItemDetails mDoc;
+
+    @Override
+    public boolean overItem(MotionEvent e) {
+        return getItemPosition(e) != RecyclerView.NO_POSITION;
+    }
+
+    @Override
+    public boolean overStableItem(MotionEvent e) {
+        return mDoc.getStableId() != null;
+    }
+
+    @Override
+    public boolean inItemDragRegion(MotionEvent e) {
+        return mDoc.inDragRegion(e);
+    }
+
+    @Override
+    public int getItemPosition(MotionEvent e) {
+        return mDoc.getPosition();
+    }
+
+    @Override
+    public boolean inItemSelectRegion(MotionEvent e) {
+        return mDoc.inSelectionHotspot(e);
+    }
+
+    @Override
+    public @Nullable ItemDetails getItemDetails(MotionEvent e) {
+        return mDoc;
+    }
+
+    /**
+     * Creates/installs/returns a new test document. Subsequent calls to
+     * any EventDocLookup methods will consult the newly created doc.
+     */
+    public TestItemDetails initAt(int position) {
+        TestItemDetails doc = new TestItemDetails();
+        doc.at(position);
+        mDoc = doc;
+        return doc;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/TouchInputHandlerTest.java b/tests/unit/com/android/documentsui/selection/TouchInputHandlerTest.java
new file mode 100644
index 0000000..c39bfee
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/TouchInputHandlerTest.java
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection;
+
+import static com.android.documentsui.testing.TestEvents.Touch.TAP;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.annotation.Nullable;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.selection.TouchInputHandler.Callbacks;
+import com.android.documentsui.selection.testing.SelectionHelpers;
+import com.android.documentsui.selection.testing.SelectionProbe;
+import com.android.documentsui.selection.testing.TestData;
+import com.android.documentsui.selection.testing.TestSelectionPredicate;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class TouchInputHandlerTest {
+
+    private static final List<String> ITEMS = TestData.create(100);
+
+    private TouchInputHandler mInputDelegate;
+    private SelectionHelper mSelectionMgr;
+    private TestSelectionPredicate mSelectionPredicate;
+    private TestRunnable mGestureStarted;
+    private TestCallbacks mCallbacks;
+    private TestItemDetailsLookup mDetailsLookup;
+    private SelectionProbe mSelection;
+
+    @Before
+    public void setUp() {
+        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
+        mDetailsLookup = new TestItemDetailsLookup();
+        mSelectionPredicate = new TestSelectionPredicate();
+        mSelection = new SelectionProbe(mSelectionMgr);
+        mGestureStarted = new TestRunnable();
+        mCallbacks = new TestCallbacks();
+
+        mInputDelegate = new TouchInputHandler(
+                mSelectionMgr,
+                mDetailsLookup,
+                mSelectionPredicate,
+                mGestureStarted,
+                mCallbacks);
+    }
+
+    @Test
+    public void testTap_ActivatesWhenNoExistingSelection() {
+        ItemDetails doc = mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(TAP);
+
+        mCallbacks.assertActivated(doc);
+    }
+
+    @Test
+    public void testScroll_shouldNotBeTrapped() {
+        assertFalse(mInputDelegate.onScroll(null, TAP, -1, -1));
+    }
+
+    @Test
+    public void testLongPress_SelectsItem() {
+        mSelectionPredicate.setReturnValue(true);
+
+        mDetailsLookup.initAt(7);
+        mInputDelegate.onLongPress(TAP);
+
+        mSelection.assertSelection(7);
+    }
+
+    @Test
+    public void testLongPress_StartsGestureSelection() {
+        mSelectionPredicate.setReturnValue(true);
+
+        mDetailsLookup.initAt(7);
+        mInputDelegate.onLongPress(TAP);
+        mGestureStarted.assertRan();
+    }
+
+    @Test
+    public void testSelectHotspot_StartsSelectionMode() {
+        mSelectionPredicate.setReturnValue(true);
+
+        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapUp(TAP);
+
+        mSelection.assertSelection(7);
+    }
+
+    @Test
+    public void testSelectionHotspot_UnselectsSelectedItem() {
+        mSelectionMgr.select("11");
+
+        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
+        mInputDelegate.onSingleTapUp(TAP);
+
+        mSelection.assertNoSelection();
+    }
+
+    @Test
+    public void testStartsSelection_PerformsHapticFeedback() {
+        mSelectionPredicate.setReturnValue(true);
+
+        mDetailsLookup.initAt(7);
+        mInputDelegate.onLongPress(TAP);
+
+        mCallbacks.assertVibrated();
+    }
+
+    @Test
+    public void testLongPress_AddsToSelection() {
+        mSelectionPredicate.setReturnValue(true);
+
+        mDetailsLookup.initAt(7);
+        mInputDelegate.onLongPress(TAP);
+
+        mDetailsLookup.initAt(99);
+        mInputDelegate.onLongPress(TAP);
+
+        mDetailsLookup.initAt(13);
+        mInputDelegate.onLongPress(TAP);
+
+        mSelection.assertSelection(7, 13, 99);
+    }
+
+    @Test
+    public void testTap_UnselectsSelectedItem() {
+        mSelectionMgr.select("11");
+
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(TAP);
+
+        mSelection.assertNoSelection();
+    }
+
+    @Test
+    public void testTapOff_ClearsSelection() {
+        mSelectionMgr.select("7");
+        mDetailsLookup.initAt(7);
+
+        mInputDelegate.onLongPress(TAP);
+
+        mSelectionMgr.select("11");
+        mDetailsLookup.initAt(11);
+        mInputDelegate.onSingleTapUp(TAP);
+
+        mDetailsLookup.initAt(RecyclerView.NO_POSITION).setInItemSelectRegion(false);
+        mInputDelegate.onSingleTapUp(TAP);
+
+        mSelection.assertNoSelection();
+    }
+
+    private static final class TestCallbacks extends TouchInputHandler.Callbacks {
+
+        private @Nullable ItemDetails mActivated;
+        private boolean mVibrated;
+
+        @Override
+        public boolean onItemActivated(ItemDetails item, MotionEvent e) {
+            mActivated = item;
+            return false;
+        }
+
+        @Override
+        public boolean onDragInitiated(MotionEvent e) {
+            return false;
+        }
+
+        @Override
+        public void onPerformHapticFeedback() {
+            mVibrated = true;
+        }
+
+        private void assertActivated(ItemDetails expected) {
+            assertEquals(expected, mActivated);
+        }
+
+        private void assertVibrated() {
+            assertTrue(mVibrated);
+        }
+    }
+
+    private static final class TestRunnable implements Runnable {
+
+        private boolean mWasRun;
+
+        @Override
+        public void run() {
+            mWasRun = true;
+        }
+
+        void assertRan() {
+            assertTrue(mWasRun);
+        }
+    }
+}
diff --git a/tests/unit/com/android/documentsui/ui/ViewAutoScrollerTest.java b/tests/unit/com/android/documentsui/selection/ViewAutoScrollerTest.java
similarity index 88%
rename from tests/unit/com/android/documentsui/ui/ViewAutoScrollerTest.java
rename to tests/unit/com/android/documentsui/selection/ViewAutoScrollerTest.java
index 5ad5e3c..b75c3da 100644
--- a/tests/unit/com/android/documentsui/ui/ViewAutoScrollerTest.java
+++ b/tests/unit/com/android/documentsui/selection/ViewAutoScrollerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.ui;
+package com.android.documentsui.selection;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -23,7 +23,8 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.documentsui.ui.ViewAutoScroller;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
+import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,15 +47,16 @@
     private ViewAutoScroller mAutoScroller;
     private Point mPoint;
     private boolean mActive;
-    private ViewAutoScroller.ScrollDistanceDelegate mDistanceDelegate;
-    private ViewAutoScroller.ScrollActionDelegate mActionDelegate;
+    private ScrollHost mHost;
+    private ScrollerCallbacks mCallbacks;
     private IntConsumer mScrollAssert;
 
     @Before
     public void setUp() {
         mActive = false;
         mPoint = new Point();
-        mDistanceDelegate = new ViewAutoScroller.ScrollDistanceDelegate() {
+
+        mHost = new ScrollHost() {
             @Override
             public boolean isActive() {
                 return mActive;
@@ -70,7 +72,8 @@
                 return mPoint;
             }
         };
-        mActionDelegate = new ViewAutoScroller.ScrollActionDelegate() {
+
+        mCallbacks = new ScrollerCallbacks() {
             @Override
             public void scrollBy(int dy) {
                 mScrollAssert.accept(dy);
@@ -84,7 +87,8 @@
             public void removeCallback(Runnable r) {
             }
         };
-        mAutoScroller = new ViewAutoScroller(mDistanceDelegate, mActionDelegate);
+
+        mAutoScroller = new ViewAutoScroller(mHost, mCallbacks);
     }
 
     @Test
diff --git a/tests/unit/com/android/documentsui/selection/testing/SelectionHelpers.java b/tests/unit/com/android/documentsui/selection/testing/SelectionHelpers.java
new file mode 100644
index 0000000..6bdd18a
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/SelectionHelpers.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection.testing;
+
+import com.android.documentsui.selection.DefaultSelectionHelper;
+import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode;
+import com.android.documentsui.selection.SelectionHelper;
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SelectionHelpers {
+
+    public static final SelectionPredicate CAN_SET_ANYTHING = new SelectionPredicate() {
+        @Override
+        public boolean canSetStateForId(String id, boolean nextState) {
+            return true;
+        }
+
+        @Override
+        public boolean canSetStateAtPosition(int position, boolean nextState) {
+            return true;
+        }
+    };
+
+    private SelectionHelpers() {}
+
+    public static SelectionHelper createTestInstance() {
+        return createTestInstance(Collections.emptyList());
+    }
+
+    public static SelectionHelper createTestInstance(List<String> docs) {
+        return createTestInstance(docs, DefaultSelectionHelper.MODE_MULTIPLE);
+    }
+
+    public static SelectionHelper createTestInstance(
+            List<String> items, @SelectionMode int mode) {
+        return createTestInstance(new TestAdapter(items), mode, CAN_SET_ANYTHING);
+    }
+
+    public static SelectionHelper createTestInstance(
+            TestAdapter adapter, @SelectionMode int mode, SelectionPredicate selPredicate) {
+        return new DefaultSelectionHelper(
+                mode, adapter, new TestStableIdProvider(adapter), selPredicate);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/SelectionPredicates.java b/tests/unit/com/android/documentsui/selection/testing/SelectionPredicates.java
new file mode 100644
index 0000000..0200919
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/SelectionPredicates.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+/**
+ * Test friendly {@link SelectionPredicate} instances.
+ */
+public final class SelectionPredicates {
+
+    private SelectionPredicates() {}
+
+    public static final SelectionPredicate CAN_SET_ANYTHING = new SelectionPredicate() {
+        @Override
+        public boolean canSetStateForId(String id, boolean nextState) {
+            return true;
+        }
+
+        @Override
+        public boolean canSetStateAtPosition(int position, boolean nextState) {
+            return true;
+        }
+    };
+}
diff --git a/tests/common/com/android/documentsui/selection/SelectionProbe.java b/tests/unit/com/android/documentsui/selection/testing/SelectionProbe.java
similarity index 69%
rename from tests/common/com/android/documentsui/selection/SelectionProbe.java
rename to tests/unit/com/android/documentsui/selection/testing/SelectionProbe.java
index d7a3632..4d5790b 100644
--- a/tests/common/com/android/documentsui/selection/SelectionProbe.java
+++ b/tests/unit/com/android/documentsui/selection/testing/SelectionProbe.java
@@ -14,35 +14,35 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.selection;
+package com.android.documentsui.selection.testing;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import com.android.documentsui.selection.SelectionManager;
+import com.android.documentsui.selection.DefaultSelectionHelper;
 import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.SelectionHelper;
 
 /**
- * Helper class for making assertions against the state of a {@link SelectionManager} instance and
- * the consistency of states between {@link SelectionManager} and
- * {@link SelectionManager.ItemCallback}.
+ * Helper class for making assertions against the state of a {@link DefaultSelectionHelper} instance
+ * and the consistency of states between {@link DefaultSelectionHelper} and
+ * {@link DefaultSelectionHelper.ItemEventCallback}.
  */
 public final class SelectionProbe {
 
-    private final SelectionManager mMgr;
-    private final TestItemSelectionListener mTestCallback;
+    private final SelectionHelper mMgr;
+    private final TestSelectionObserver mSelectionListener;
 
-    public SelectionProbe(SelectionManager mgr) {
+    public SelectionProbe(SelectionHelper mgr) {
         mMgr = mgr;
-        mTestCallback = new TestItemSelectionListener();
-
-        mMgr.addItemCallback(mTestCallback);
+        mSelectionListener = new TestSelectionObserver();
+        mMgr.addObserver(mSelectionListener);
     }
 
-    public SelectionProbe(SelectionManager mgr, TestItemSelectionListener testCallback) {
+    public SelectionProbe(SelectionHelper mgr, TestSelectionObserver selectionListener) {
         mMgr = mgr;
-        mTestCallback = testCallback;
+        mSelectionListener = selectionListener;
     }
 
     public void assertRangeSelected(int begin, int end) {
@@ -66,20 +66,20 @@
         Selection selection = mMgr.getSelection();
         assertEquals(selection.toString(), expected, selection.size());
 
-        mTestCallback.assertSelectionSize(expected);
+        mSelectionListener.assertSelectionSize(expected);
     }
 
     public void assertNoSelection() {
         assertSelectionSize(0);
 
-        mTestCallback.assertNoSelection();
+        mSelectionListener.assertNoSelection();
     }
 
     public void assertSelection(int... ids) {
         assertSelected(ids);
         assertEquals(ids.length, mMgr.getSelection().size());
 
-        mTestCallback.assertSelectionSize(ids.length);
+        mSelectionListener.assertSelectionSize(ids.length);
     }
 
     public void assertSelected(int... ids) {
@@ -88,7 +88,7 @@
             String sid = String.valueOf(id);
             assertTrue(sid + " is not in selection " + sel, sel.contains(sid));
 
-            mTestCallback.assertSelected(sid);
+            mSelectionListener.assertSelected(sid);
         }
     }
 
@@ -98,13 +98,13 @@
             String sid = String.valueOf(id);
             assertFalse(sid + " is in selection " + sel, sel.contains(sid));
 
-            mTestCallback.assertNotSelected(sid);
+            mSelectionListener.assertNotSelected(sid);
         }
     }
 
     public void select(int...positions) {
         for (int position : positions) {
-            mMgr.toggleSelection(String.valueOf(position));
+            mMgr.select(String.valueOf(position));
         }
     }
 }
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestAdapter.java b/tests/unit/com/android/documentsui/selection/testing/TestAdapter.java
new file mode 100644
index 0000000..f4c6d17
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestAdapter.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import static org.junit.Assert.assertTrue;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.Adapter;
+import android.support.v7.widget.RecyclerView.AdapterDataObserver;
+import android.view.ViewGroup;
+
+import com.android.documentsui.selection.SelectionHelper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class TestAdapter extends Adapter<TestHolder> {
+
+    private final List<String> mItems = new ArrayList<>();
+    private final List<Integer> mNotifiedOfSelection = new ArrayList<>();
+    private final AdapterDataObserver mAdapterObserver;
+
+    public TestAdapter() {
+        this(Collections.EMPTY_LIST);
+    }
+
+    public TestAdapter(List<String> items) {
+        mItems.addAll(items);
+        mAdapterObserver = new RecyclerView.AdapterDataObserver() {
+
+            @Override
+            public void onChanged() {
+            }
+
+            @Override
+            public void onItemRangeChanged(int startPosition, int itemCount, Object payload) {
+                if (SelectionHelper.SELECTION_CHANGED_MARKER.equals(payload)) {
+                    int last = startPosition + itemCount;
+                    for (int i = startPosition; i < last; i++) {
+                        mNotifiedOfSelection.add(i);
+                    }
+                }
+            }
+
+            @Override
+            public void onItemRangeInserted(int startPosition, int itemCount) {
+            }
+
+            @Override
+            public void onItemRangeRemoved(int startPosition, int itemCount) {
+            }
+
+            @Override
+            public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+                throw new UnsupportedOperationException();
+            }
+        };
+
+        registerAdapterDataObserver(mAdapterObserver);
+    }
+
+    @Override
+    public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        return new TestHolder(parent);
+    }
+
+    @Override
+    public void onBindViewHolder(TestHolder holder, int position) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getItemCount() {
+        return mItems.size();
+    }
+
+    public void updateTestModelIds(List<String> items) {
+        mItems.clear();
+        mItems.addAll(items);
+
+        notifyDataSetChanged();
+    }
+
+    public List<String> getStableIds() {
+        return mItems;
+    }
+
+    public int getPosition(String id) {
+        return mItems.indexOf(id);
+    }
+
+    public String getStableId(int position) {
+        return mItems.get(position);
+    }
+
+
+    public void resetSelectionNotifications() {
+        mNotifiedOfSelection.clear();
+    }
+
+    public void assertNotifiedOfSelectionChange(int position) {
+        assertTrue(mNotifiedOfSelection.contains(position));
+    }
+
+    public static List<String> createItemList(int num) {
+        List<String> items = new ArrayList<>(num);
+        for (int i = 0; i < num; ++i) {
+            items.add(Integer.toString(i));
+        }
+        return items;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestBandPredicate.java b/tests/unit/com/android/documentsui/selection/testing/TestBandPredicate.java
new file mode 100644
index 0000000..2e901a0
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestBandPredicate.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.BandPredicate;
+
+public class TestBandPredicate extends BandPredicate {
+
+    private boolean mCanInitiate = true;
+
+    public void setCanInitiate(boolean canInitiate) {
+        mCanInitiate = canInitiate;
+    }
+
+    @Override
+    public boolean canInitiate(MotionEvent e) {
+        return mCanInitiate;
+    }
+
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestData.java b/tests/unit/com/android/documentsui/selection/testing/TestData.java
new file mode 100644
index 0000000..1a05990
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestData.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection.testing;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestData {
+    public static List<String> create(int num) {
+        List<String> items = new ArrayList<String>(num);
+        for (int i = 0; i < num; ++i) {
+            items.add(Integer.toString(i));
+        }
+        return items;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestEvents.java b/tests/unit/com/android/documentsui/selection/testing/TestEvents.java
new file mode 100644
index 0000000..c472adb
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestEvents.java
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+
+package com.android.documentsui.selection.testing;
+
+import android.annotation.IntDef;
+import android.graphics.Point;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Handy-dandy wrapper class to facilitate the creation of MotionEvents.
+ */
+public final class TestEvents {
+
+    /**
+     * Common mouse event types...for your convenience.
+     */
+    public static final class Mouse {
+        public static final MotionEvent CLICK =
+                TestEvents.builder().mouse().primary().build();
+        public static final MotionEvent CTRL_CLICK =
+                TestEvents.builder().mouse().primary().ctrl().build();
+        public static final MotionEvent ALT_CLICK =
+                TestEvents.builder().mouse().primary().alt().build();
+        public static final MotionEvent SHIFT_CLICK =
+                TestEvents.builder().mouse().primary().shift().build();
+        public static final MotionEvent SECONDARY_CLICK =
+                TestEvents.builder().mouse().secondary().build();
+        public static final MotionEvent TERTIARY_CLICK =
+                TestEvents.builder().mouse().tertiary().build();
+    }
+
+    /**
+     * Common touch event types...for your convenience.
+     */
+    public static final class Touch {
+        public static final MotionEvent TAP =
+                TestEvents.builder().touch().build();
+    }
+
+    static final int ACTION_UNSET = -1;
+
+    // Add other actions from MotionEvent.ACTION_ as needed.
+    @IntDef(flag = true, value = {
+            MotionEvent.ACTION_DOWN,
+            MotionEvent.ACTION_MOVE,
+            MotionEvent.ACTION_UP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Action {}
+
+    // Add other types from MotionEvent.TOOL_TYPE_ as needed.
+    @IntDef(flag = true, value = {
+            MotionEvent.TOOL_TYPE_FINGER,
+            MotionEvent.TOOL_TYPE_MOUSE,
+            MotionEvent.TOOL_TYPE_STYLUS,
+            MotionEvent.TOOL_TYPE_UNKNOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ToolType {}
+
+    @IntDef(flag = true, value = {
+            MotionEvent.BUTTON_PRIMARY,
+            MotionEvent.BUTTON_SECONDARY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Button {}
+
+    @IntDef(flag = true, value = {
+            KeyEvent.META_SHIFT_ON,
+            KeyEvent.META_CTRL_ON
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Key {}
+
+    private static final class State {
+        private @Action int mAction = ACTION_UNSET;
+        private @ToolType int mToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
+        private int mPointerCount = 1;
+        private Set<Integer> mButtons = new HashSet<>();
+        private Set<Integer> mKeys = new HashSet<>();
+        private Point mLocation = new Point(0, 0);
+        private Point mRawLocation = new Point(0, 0);
+    }
+
+    public static final Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Test event builder with convenience methods for common event attrs.
+     */
+    public static final class Builder {
+
+        private State mState = new State();
+
+        /**
+         * @param action Any action specified in {@link MotionEvent}.
+         * @return
+         */
+        public Builder action(int action) {
+            mState.mAction = action;
+            return this;
+        }
+
+        public Builder type(@ToolType int type) {
+            mState.mToolType = type;
+            return this;
+        }
+
+        public Builder location(int x, int y) {
+            mState.mLocation = new Point(x, y);
+            return this;
+        }
+
+        public Builder rawLocation(int x, int y) {
+            mState.mRawLocation = new Point(x, y);
+            return this;
+        }
+
+        public Builder pointerCount(int count) {
+            mState.mPointerCount = count;
+            return this;
+        }
+
+        /**
+         * Adds one or more button press attributes.
+         */
+        public Builder pressButton(@Button int... buttons) {
+            for (int button : buttons) {
+                mState.mButtons.add(button);
+            }
+            return this;
+        }
+
+        /**
+         * Removes one or more button press attributes.
+         */
+        public Builder releaseButton(@Button int... buttons) {
+            for (int button : buttons) {
+                mState.mButtons.remove(button);
+            }
+            return this;
+        }
+
+        /**
+         * Adds one or more key press attributes.
+         */
+        public Builder pressKey(@Key int... keys) {
+            for (int key : keys) {
+                mState.mKeys.add(key);
+            }
+            return this;
+        }
+
+        /**
+         * Removes one or more key press attributes.
+         */
+        public Builder releaseKey(@Button int... keys) {
+            for (int key : keys) {
+                mState.mKeys.remove(key);
+            }
+            return this;
+        }
+
+        public Builder touch() {
+            type(MotionEvent.TOOL_TYPE_FINGER);
+            return this;
+        }
+
+        public Builder mouse() {
+            type(MotionEvent.TOOL_TYPE_MOUSE);
+            return this;
+        }
+
+        public Builder shift() {
+            pressKey(KeyEvent.META_SHIFT_ON);
+            return this;
+        }
+
+        /**
+         * Use {@link #remove(@Attribute int...)}
+         */
+        public Builder unshift() {
+            releaseKey(KeyEvent.META_SHIFT_ON);
+            return this;
+        }
+
+        public Builder ctrl() {
+            pressKey(KeyEvent.META_CTRL_ON);
+            return this;
+        }
+
+        public Builder alt() {
+            pressKey(KeyEvent.META_ALT_ON);
+            return this;
+        }
+
+        public Builder primary() {
+            pressButton(MotionEvent.BUTTON_PRIMARY);
+            releaseButton(MotionEvent.BUTTON_SECONDARY);
+            releaseButton(MotionEvent.BUTTON_TERTIARY);
+            return this;
+        }
+
+        public Builder secondary() {
+            pressButton(MotionEvent.BUTTON_SECONDARY);
+            releaseButton(MotionEvent.BUTTON_PRIMARY);
+            releaseButton(MotionEvent.BUTTON_TERTIARY);
+            return this;
+        }
+
+        public Builder tertiary() {
+            pressButton(MotionEvent.BUTTON_TERTIARY);
+            releaseButton(MotionEvent.BUTTON_PRIMARY);
+            releaseButton(MotionEvent.BUTTON_SECONDARY);
+            return this;
+        }
+
+        public MotionEvent build() {
+
+            PointerProperties[] pointers = new PointerProperties[1];
+            pointers[0] = new PointerProperties();
+            pointers[0].id = 0;
+            pointers[0].toolType = mState.mToolType;
+
+            PointerCoords[] coords = new PointerCoords[1];
+            coords[0] = new PointerCoords();
+            coords[0].x = mState.mLocation.x;
+            coords[0].y = mState.mLocation.y;
+
+            int buttons = 0;
+            for (Integer button : mState.mButtons) {
+                buttons |= button;
+            }
+
+            int keys = 0;
+            for (Integer key : mState.mKeys) {
+                keys |= key;
+            }
+
+            return MotionEvent.obtain(
+                    0,     // down time
+                    1,     // event time
+                    mState.mAction,
+                    1,  // pointerCount,
+                    pointers,
+                    coords,
+                    keys,
+                    buttons,
+                    1.0f,  // x precision
+                    1.0f,  // y precision
+                    0,     // device id
+                    0,     // edge flags
+                    0,     // int source,
+                    0      // int flags
+                    );
+        }
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestHolder.java b/tests/unit/com/android/documentsui/selection/testing/TestHolder.java
new file mode 100644
index 0000000..a0728fe
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestHolder.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.View;
+
+public class TestHolder extends ViewHolder {
+    public TestHolder(View itemView) {
+        super(itemView);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestMouseCallbacks.java b/tests/unit/com/android/documentsui/selection/testing/TestMouseCallbacks.java
new file mode 100644
index 0000000..06edc1e
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestMouseCallbacks.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import com.android.documentsui.selection.MouseInputHandler;
+import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+
+public final class TestMouseCallbacks extends MouseInputHandler.Callbacks {
+
+    private String mFocusItemId;
+    private int mFocusPosition;
+    private MotionEvent mLastContextEvent;
+    private ItemDetails mActivated;
+
+    @Override
+    public boolean onItemActivated(ItemDetails item, MotionEvent e) {
+        mActivated = item;
+        return true;
+    }
+
+    @Override
+    public boolean onContextClick(MotionEvent e) {
+        mLastContextEvent = e;
+        return false;
+    }
+
+    @Override
+    public void onPerformHapticFeedback() {
+    }
+
+    @Override
+    public void clearFocus() {
+        mFocusPosition = RecyclerView.NO_POSITION;
+        mFocusItemId = null;
+    }
+
+    @Override
+    public void focusItem(ItemDetails item) {
+        mFocusItemId = item.getStableId();
+        mFocusPosition = item.getPosition();
+    }
+
+    @Override
+    public int getFocusedPosition() {
+        return mFocusPosition;
+    }
+
+    @Override
+    public boolean hasFocusedItem() {
+        return mFocusItemId != null;
+    }
+
+    public void assertLastEvent(MotionEvent expected) {
+        // sadly, MotionEvent doesn't implement equals, so we compare references.
+        assertTrue(expected == mLastContextEvent);
+    }
+
+    public void assertActivated(ItemDetails expected) {
+        assertEquals(expected, mActivated);
+    }
+
+    public void assertHasFocus(boolean focused) {
+        assertEquals(focused, hasFocusedItem());
+    }
+
+    public void assertFocused(String expectedId) {
+        assertEquals(expectedId, mFocusItemId);
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestSelectionObserver.java b/tests/unit/com/android/documentsui/selection/testing/TestSelectionObserver.java
new file mode 100644
index 0000000..e75bde3
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestSelectionObserver.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestSelectionObserver extends SelectionObserver {
+
+    private final Set<String> mSelected = new HashSet<>();
+    private boolean mSelectionChanged = false;
+    private boolean mSelectionReset = false;
+    private boolean mSelectionRestored = false;
+
+    public void reset() {
+        mSelected.clear();
+        mSelectionChanged = false;
+        mSelectionReset = false;
+    }
+
+    @Override
+    public void onItemStateChanged(String id, boolean selected) {
+        if (selected) {
+            assertNotSelected(id);
+            mSelected.add(id);
+        } else {
+            assertSelected(id);
+            mSelected.remove(id);
+        }
+    }
+
+    @Override
+    public void onSelectionReset() {
+        mSelectionReset = true;
+        mSelected.clear();
+    }
+
+    @Override
+    public void onSelectionChanged() {
+        mSelectionChanged = true;
+    }
+
+    @Override
+    public void onSelectionRestored() {
+        mSelectionRestored = true;
+    }
+
+    void assertNoSelection() {
+        assertTrue(mSelected.isEmpty());
+    }
+
+    void assertSelectionSize(int expected) {
+        assertEquals(expected, mSelected.size());
+    }
+
+    void assertSelected(String id) {
+        assertTrue(id + " is not selected.", mSelected.contains(id));
+    }
+
+    void assertNotSelected(String id) {
+        assertFalse(id + " is already selected", mSelected.contains(id));
+    }
+
+    public void assertSelectionChanged() {
+        assertTrue(mSelectionChanged);
+    }
+
+    public void assertSelectionUnchanged() {
+        assertFalse(mSelectionChanged);
+    }
+
+    public void assertSelectionReset() {
+        assertTrue(mSelectionReset);
+    }
+
+    public void assertSelectionRestored() {
+        assertTrue(mSelectionRestored);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestSelectionPredicate.java b/tests/unit/com/android/documentsui/selection/testing/TestSelectionPredicate.java
new file mode 100644
index 0000000..578be3d
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestSelectionPredicate.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
+
+public final class TestSelectionPredicate extends SelectionPredicate {
+    private boolean mValue;
+
+    public void setReturnValue(boolean value) {
+        mValue = value;
+    }
+
+    @Override
+    public boolean canSetStateForId(String id, boolean nextState) {
+        return mValue;
+    }
+
+    @Override
+    public boolean canSetStateAtPosition(int position, boolean nextState) {
+        return mValue;
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestStableIdProvider.java b/tests/unit/com/android/documentsui/selection/testing/TestStableIdProvider.java
new file mode 100644
index 0000000..1d50737
--- /dev/null
+++ b/tests/unit/com/android/documentsui/selection/testing/TestStableIdProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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 com.android.documentsui.selection.testing;
+
+import static android.support.v4.util.Preconditions.checkArgument;
+
+import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
+
+import java.util.List;
+
+/**
+ * Provides RecyclerView selection code access to stable ids backed
+ * by TestAdapter.
+ */
+public final class TestStableIdProvider extends StableIdProvider {
+
+    private final TestAdapter mAdapter;
+
+    public TestStableIdProvider(TestAdapter adapter) {
+        checkArgument(adapter != null);
+        mAdapter = adapter;
+    }
+
+    @Override
+    public String getStableId(int position) {
+        return mAdapter.getStableId(position);
+    }
+
+    @Override
+    public int getPosition(String id) {
+        return mAdapter.getPosition(id);
+    }
+
+    @Override
+    public List<String> getStableIds() {
+        return mAdapter.getStableIds();
+    }
+}
diff --git a/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java b/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java
index 7f75aa5..a210c0e 100644
--- a/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java
+++ b/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java
@@ -21,8 +21,8 @@
 import static com.android.documentsui.services.FileOperations.createBaseIntent;
 import static com.android.documentsui.services.FileOperations.createJobId;
 import static com.google.android.collect.Lists.newArrayList;
+import static org.junit.Assert.fail;
 
-import android.app.Notification;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -131,8 +131,9 @@
     public void testRunsCopyJobs_AfterExceptionInJobCreation() throws Exception {
         try {
             startService(createCopyIntent(new ArrayList<>(), BETA_DOC));
-        } catch(AssertionError e) {
-            // Expected AssertionError
+            fail("Should have throw exception.");
+        } catch(IllegalArgumentException expected) {
+            // We're sending a naughty empty list that should result in an IllegalArgumentException.
         }
         startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));