Merge "Mark AVRCP devices as internal."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e95e5ec..bf50017 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,12 +40,28 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.document/root" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.provider.action.BROWSE_DOCUMENT_ROOT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.document/root" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name=".StandaloneActivity"
+            android:theme="@style/StandaloneTheme"
+            android:icon="@drawable/ic_doc_text"
+            android:enabled="false">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
         </activity>
 
         <provider
             android:name=".RecentsProvider"
             android:authorities="com.android.documentsui.recents"
-            android:exported="false" />
+            android:exported="false"/>
 
         <receiver android:name=".PackageReceiver">
             <intent-filter>
@@ -54,5 +70,10 @@
                 <data android:scheme="package" />
             </intent-filter>
         </receiver>
+
+        <service
+            android:name=".CopyService"
+            android:exported="false">
+        </service>
     </application>
 </manifest>
diff --git a/res/layout/fragment_pick.xml b/res/layout/fragment_pick.xml
index 5735871..87dc4f8 100644
--- a/res/layout/fragment_pick.xml
+++ b/res/layout/fragment_pick.xml
@@ -21,12 +21,19 @@
     android:baselineAligned="false"
     android:gravity="center_vertical"
     android:minHeight="?android:attr/listPreferredItemHeightSmall">
-
+    <Button
+        android:id="@android:id/button2"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:text="@android:string/cancel"
+        android:visibility="gone"
+        style="?android:attr/buttonBarNegativeButtonStyle" />
     <Button
         android:id="@android:id/button1"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="match_parent"
+        android:layout_weight="1"
         android:textAllCaps="false"
         style="?android:attr/buttonBarPositiveButtonStyle" />
-
 </LinearLayout>
diff --git a/res/menu/activity.xml b/res/menu/activity.xml
index b9b8054..5b944ab 100644
--- a/res/menu/activity.xml
+++ b/res/menu/activity.xml
@@ -60,4 +60,8 @@
     <item
         android:id="@+id/menu_file_size"
         android:showAsAction="never" />
+    <item
+        android:id="@+id/menu_settings"
+        android:title="@string/menu_settings"
+        android:showAsAction="never" />
 </menu>
diff --git a/res/menu/mode_directory.xml b/res/menu/mode_directory.xml
index 0a3645f..4b89823 100644
--- a/res/menu/mode_directory.xml
+++ b/res/menu/mode_directory.xml
@@ -29,4 +29,12 @@
         android:icon="@drawable/ic_menu_delete"
         android:title="@string/menu_delete"
         android:showAsAction="always" />
+    <item
+        android:id="@+id/menu_select_all"
+        android:title="@string/menu_select_all"
+        android:showAsAction="never" />
+    <item
+        android:id="@+id/menu_copy"
+        android:title="@string/menu_copy"
+        android:showAsAction="never" />
 </menu>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 19fe7a7..6fa7a4e 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Deel"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Vee uit"</string>
     <string name="menu_select" msgid="8711270657353563424">"Kies \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Kies almal"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopieer na …"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Wys interne berging"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Wys SD-kaart"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Versteek interne berging"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Kan lêer nie oopmaak nie"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Kan sommige dokumente nie uitvee nie"</string>
     <string name="share_via" msgid="8966594246261344259">"Deel via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Kanselleer"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopieer tans lêers"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> oor"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Kopieer tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers.</item>
+      <item quantity="one">Kopieer tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 419d162..52cc50e 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"አጋራ"</string>
     <string name="menu_delete" msgid="8138799623850614177">"ሰርዝ"</string>
     <string name="menu_select" msgid="8711270657353563424">"«<xliff:g id="DIRECTORY">^1</xliff:g>»ን ይምረጡ"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"ሁሉንም ምረጥ"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"ቅዳ ወደ…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ውስጣዊ ማከማቻ አሳይ"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ካርድ አሳይ"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ውስጣዊ ማከማቻ ደብቅ"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ፋይል መክፈት አይቻልም"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
     <string name="share_via" msgid="8966594246261344259">"በሚከተለው በኩል ያጋሩ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ፋይሎች በመገልበጥ ላይ"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ቀርቷል"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 5bccdae..4e1065f 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"مشاركة"</string>
     <string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
     <string name="menu_select" msgid="8711270657353563424">"تحديد \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"تحديد الكل"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"نسخ إلى…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"إظهار وحدة التخزين الداخلية"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"‏إظهار بطاقة SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"إخفاء وحدة التخزين الداخلية"</string>
@@ -55,4 +57,17 @@
     <string name="toast_no_application" msgid="1339885974067891667">"لا يمكن فتح الملف"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"تعذر حذف بعض المستندات"</string>
     <string name="share_via" msgid="8966594246261344259">"مشاركة عبر"</string>
+    <string name="cancel" msgid="6442560571259935130">"إلغاء"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"جارٍ نسخ الملفات"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"المدة المتبقية: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="zero">جارٍ نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
+      <item quantity="two">جارٍ نسخ ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>).</item>
+      <item quantity="few">جارٍ نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
+      <item quantity="many">جارٍ نسخ <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 77f6855..8e98cd2 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Споделяне"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Изтриване"</string>
     <string name="menu_select" msgid="8711270657353563424">"Избиране на „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Избиране на всички"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Копиране във…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Вътр. хранилище: Показв."</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD карта: Показване"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Вътр. хранилище: Скрив."</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Файлът не може да се отвори"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Някои документи не могат да бъдат изтрити"</string>
     <string name="share_via" msgid="8966594246261344259">"Споделяне чрез"</string>
+    <string name="cancel" msgid="6442560571259935130">"Отказ"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Файловете се копират"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Оставащо време: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 603cb96..ad2a860 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"ভাগ করুন"</string>
     <string name="menu_delete" msgid="8138799623850614177">"মুছুন"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" নির্বাচন করুন"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"সমস্ত নির্বাচন করুন"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"এতে অনুলিপি করুন…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"অভ্যন্তরীণ সঞ্চয়স্থান দেখান"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD কার্ড দেখান"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"অভ্যন্তরীণ সঞ্চয়স্থান লুকান"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ফাইল খোলা যাবে না"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"কিছু দস্তাবেজ মুছতে অসমর্থ"</string>
     <string name="share_via" msgid="8966594246261344259">"এর মাধ্যমে ভাগ করুন"</string>
+    <string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ফাইলগুলি অনুলিপি করা হচ্ছে"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> বাকি"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index d973650..4ee3832 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Comparteix"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Suprimeix"</string>
     <string name="menu_select" msgid="8711270657353563424">"Selecciona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Selecciona\'ls tots"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copia a…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostra emmagatz. intern"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostra la targeta SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Amaga emmagatz. intern"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"No es pot obrir el fitxer."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es poden suprimir alguns documents."</string>
     <string name="share_via" msgid="8966594246261344259">"Comparteix mitjançant"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancel·la"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"S\'estan copiant fitxers"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Temps restant: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">S\'estan copiant <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
+      <item quantity="one">S\'està copiant <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 36bb72f..0da696f 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Sdílet"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Smazat"</string>
     <string name="menu_select" msgid="8711270657353563424">"Vyberte adresář <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Vybrat vše"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopírovat do…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Zobrazit inter. úložiště"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Zobrazit SD kartu"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skrýt interní úložiště"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Soubor nelze otevřít"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Některé dokumenty nelze smazat"</string>
     <string name="share_via" msgid="8966594246261344259">"Sdílet pomocí"</string>
+    <string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopírování souborů"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Zbývající čas: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="few">Kopírování <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
+      <item quantity="many">Kopírování <xliff:g id="COUNT_1">%1$d</xliff:g> souboru</item>
+      <item quantity="other">Kopírování <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
+      <item quantity="one">Kopírování <xliff:g id="COUNT_0">%1$d</xliff:g> souboru</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 5feb517..c674ed2 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Del"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Slet"</string>
     <string name="menu_select" msgid="8711270657353563424">"Vælg \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Vælg alle"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiér til…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Vis intern lagerplads"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Vis SD-kort"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skjul intern lagerplads"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Filen kan ikke åbnes"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nogle dokumenter kan ikke slettes"</string>
     <string name="share_via" msgid="8966594246261344259">"Del via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Annuller"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> tilbage"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+      <item quantity="other">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 598862b..73f08e1 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Teilen"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Löschen"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" auswählen"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Alle auswählen"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopieren nach..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Int. Speicher anzeigen"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-Karte anzeigen"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Int. Speicher ausblenden"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Datei kann nicht geöffnet werden."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Einige Dokumente konnten nicht gelöscht werden."</string>
     <string name="share_via" msgid="8966594246261344259">"Teilen über"</string>
+    <string name="cancel" msgid="6442560571259935130">"Abbrechen"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Dateien werden kopiert"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Noch <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden kopiert.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird kopiert.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 37f99cf..c41a831 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Κοινή χρήση"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Διαγραφή"</string>
     <string name="menu_select" msgid="8711270657353563424">"Επιλογή \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Επιλογή όλων"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Αντιγραφή σε…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Εμφ.εσωτ.χώρου αποθήκ."</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Εμφάνιση κάρτας SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Απόκρ.εσωτ.χώρου αποθήκ."</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
     <string name="share_via" msgid="8966594246261344259">"Κοινή χρήση μέσω"</string>
+    <string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Αντιγραφή αρχείων"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Απομένουν <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
 </resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..74eaaa7
--- /dev/null
+++ b/res/values-en-rAU/strings.xml
@@ -0,0 +1,68 @@
+<?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="app_label" msgid="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Open from"</string>
+    <string name="title_save" msgid="2433679664882857999">"Save to"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
+    <string name="menu_list" msgid="7279285939892417279">"List view"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Search"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Settings"</string>
+    <string name="menu_open" msgid="432922957274920903">"Open"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Save"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Share"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
+    <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Select All"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
+    <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
+    <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
+    <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
+    <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Hide SD card"</string>
+    <string name="menu_file_size_show" msgid="3240323619260823076">"Show file size"</string>
+    <string name="menu_file_size_hide" msgid="8881975928502581042">"Hide file size"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+    <string name="sort_name" msgid="9183560467917256779">"By name"</string>
+    <string name="sort_date" msgid="586080032956151448">"By date modified"</string>
+    <string name="sort_size" msgid="3350681319735474741">"By size"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Show roots"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
+    <string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
+    <string name="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Shortcuts"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
+    <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
+    <string name="share_via" msgid="8966594246261344259">"Share via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
+</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 2bd5615..74eaaa7 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Share"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
     <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Select All"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Share via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
 </resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 2bd5615..74eaaa7 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Share"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
     <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Select All"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Share via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
 </resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 4a47b73..bd3088e 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
     <string name="menu_select" msgid="8711270657353563424">"Seleccionar \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Seleccionar todos"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copiar a…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar almacen. interno"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar tarjeta SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar almacen. interno"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"No se puede abrir el archivo."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos."</string>
     <string name="share_via" msgid="8966594246261344259">"Compartir mediante"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Faltan <xliff:g id="DURATION">%s</xliff:g>."</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+      <item quantity="one">Copiando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 95cc812..ff70644 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
     <string name="menu_select" msgid="8711270657353563424">"Selecciona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Seleccionar todo"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copiar en…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar almac. interno"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar tarjeta SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar almac. interno"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Error al abrir el archivo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Tiempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+      <item quantity="one">Copiando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index c98f0b9..b67f798 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Jaga"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Kustuta"</string>
     <string name="menu_select" msgid="8711270657353563424">"Kataloogi „<xliff:g id="DIRECTORY">^1</xliff:g>” valimine"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Vali kõik"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopeeri asukohta ..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Kuva sis. salvestusruum"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Kuva SD-kaart"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Peida sis. salvestusruum"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Faili ei saa avada"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Mõnda dokumenti ei õnnestu kustutada"</string>
     <string name="share_via" msgid="8966594246261344259">"Jagage teenusega"</string>
+    <string name="cancel" msgid="6442560571259935130">"Tühista"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Failide kopeerimine"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Jäänud on <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili kopeerimine.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili kopeerimine.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 1fd7b1d..268a75c 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Partekatu"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Ezabatu"</string>
     <string name="menu_select" msgid="8711270657353563424">"Hautatu \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Hautatu guztiak"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiatu hemen…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Erakutsi barneko memoria"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Erakutsi SD txartela"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ezkutatu barneko memoria"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Ezin da fitxategia ireki"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ezin izan dira dokumentu batzuk ezabatu"</string>
     <string name="share_via" msgid="8966594246261344259">"Partekatu honen bidez:"</string>
+    <string name="cancel" msgid="6442560571259935130">"Utzi"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Fitxategiak kopiatzen"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Falta den denbora: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi kopiatzen.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi kopiatzen.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 6c57211..0388409 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"اشتراک‌گذاری"</string>
     <string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
     <string name="menu_select" msgid="8711270657353563424">"انتخاب «<xliff:g id="DIRECTORY">^1</xliff:g>»"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"انتخاب همه"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"کپی در..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"نمایش فضای ذخیره‌سازی داخلی"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"‏نمایش کارت SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"پنهان کردن فضای ذخیره‌سازی داخلی"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"فایل باز نمی‌شود"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"برخی از اسناد حذف نمی‌شوند"</string>
     <string name="share_via" msgid="8966594246261344259">"اشتراک‌گذاری از طریق"</string>
+    <string name="cancel" msgid="6442560571259935130">"لغو"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"در حال کپی کردن فایل‌ها"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> باقی‌مانده"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 185be47..34b704c 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Jaa"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Poista"</string>
     <string name="menu_select" msgid="8711270657353563424">"Valitse <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Valitse kaikki"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopioi kohteeseen…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Näytä sis. tallennustila"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Näytä SD-kortti"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Piilota sis. tallennust."</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Tiedostoa ei voi avata"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
     <string name="share_via" msgid="8966594246261344259">"Jaa sovelluksessa"</string>
+    <string name="cancel" msgid="6442560571259935130">"Peruuta"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopioidaan tiedostoja"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> jäljellä"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Kopioidaan <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
+      <item quantity="one">Kopioidaan <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 4e4c0ed..7ee5449 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Partager"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
     <string name="menu_select" msgid="8711270657353563424">"Sélectionner « <xliff:g id="DIRECTORY">^1</xliff:g> »"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Tout sélectionner"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copier vers..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Aff. mém. stock. interne"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Afficher la carte SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Masquer mém. stock. int."</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Impossible d\'ouvrir le fichier"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Partager par"</string>
+    <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers..."</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Durée restante : <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Copier de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours.</item>
+      <item quantity="other">Copier de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index b760caa..2875f6c 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Partager"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
     <string name="menu_select" msgid="8711270657353563424">"Sélectionner \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Tout sélectionner"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copier vers…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Aff. mém. stock. interne"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Afficher la carte SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Masquer mém. stock. int."</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Impossible d\'ouvrir le fichier."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents."</string>
     <string name="share_via" msgid="8966594246261344259">"Partager via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers en cours"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Temps restant : <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Copie de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
+      <item quantity="other">Copie de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index bc6ee9e..5f316f2 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
     <string name="menu_select" msgid="8711270657353563424">"Selecciona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Seleccionar todos"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copiar en…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar almacen. interno"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar tarxeta SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar almacen. interno"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Non se pode abrir o ficheiro"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Non se poden eliminar algúns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copiando ficheiros"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Tempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+      <item quantity="one">Copianto <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 88f26ed..9d6727c 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"साझा करें"</string>
     <string name="menu_delete" msgid="8138799623850614177">"हटाएं"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" चुनें"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"सभी चुनें"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"इनकी कॉपी बनाएं..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"आंतरिक मेमोरी दिखाएं"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड दिखाएं"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"आंतरिक मेमोरी छिपाएं"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"फ़ाइल नहीं खोली जा सकती"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"कुछ दस्तावेज़ों को हटाने में अक्षम"</string>
     <string name="share_via" msgid="8966594246261344259">"इसके द्वारा साझा करें"</string>
+    <string name="cancel" msgid="6442560571259935130">"अभी नहीं"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"फ़ाइलें कॉपी हो रही हैं"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> शेष"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 60343d2..1635ada 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Dijeli"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
     <string name="menu_select" msgid="8711270657353563424">"Odaberi \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Odaberi sve"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiraj u…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Pokaži internu pohranu"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Pokaži SD karticu"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Sakrij internu pohranu"</string>
@@ -55,4 +57,14 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Datoteku nije moguće otvoriti"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
     <string name="share_via" msgid="8966594246261344259">"Dijeli putem"</string>
+    <string name="cancel" msgid="6442560571259935130">"Odustani"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datoteka"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+      <item quantity="few">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+      <item quantity="other">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index a9b5a7c..223ed89 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Megosztás"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Törlés"</string>
     <string name="menu_select" msgid="8711270657353563424">"A(z) „<xliff:g id="DIRECTORY">^1</xliff:g>” mappa kiválasztása"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Az összes kijelölése"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Másolás ide…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Belső tárhely"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-kártya megjelenítése"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Belső tárhely elrejtése"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"A fájlt nem lehet megnyitni"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Néhány dokumentumot nem lehet törölni"</string>
     <string name="share_via" msgid="8966594246261344259">"Megosztás itt:"</string>
+    <string name="cancel" msgid="6442560571259935130">"Mégse"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Fájlok másolása"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> van hátra"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl másolása.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl másolása.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index cabc956..35de1e1 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -19,8 +19,8 @@
     <string name="app_label" msgid="2783841764617238354">"Փաստաթղթեր"</string>
     <string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
     <string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
-    <string name="menu_create_dir" msgid="5947289605844398389">"Ստեղծել թղթապանակ"</string>
-    <string name="menu_grid" msgid="6878021334497835259">"Ցանցային տեսք"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Ստեղծել պանակ"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Ցանցի տեսք"</string>
     <string name="menu_list" msgid="7279285939892417279">"Ցուցակի տեսք"</string>
     <string name="menu_sort" msgid="7677740407158414452">"Դասավորել ըստ"</string>
     <string name="menu_search" msgid="3816712084502856974">"Որոնել"</string>
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Համօգտագործել"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Ջնջել"</string>
     <string name="menu_select" msgid="8711270657353563424">"Ընտրել «<xliff:g id="DIRECTORY">^1</xliff:g>»"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Ընտրել բոլորը"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Պատճենել…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ցույց տալ ներքին պահոցը"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Ցույց տալ SD քարտը"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Թաքցնել ներքին պահոցը"</string>
@@ -43,7 +45,7 @@
     <string name="drawer_open" msgid="4545466532430226949">"Ցույց տալ արմատները"</string>
     <string name="drawer_close" msgid="7602734368552123318">"Թաքցնել արմատները"</string>
     <string name="save_error" msgid="6167009778003223664">"Չհաջողվեց պահել փաստաթուղթը"</string>
-    <string name="create_error" msgid="3735649141335444215">"Չհաջողվեց ստեղծել թղթապանակը"</string>
+    <string name="create_error" msgid="3735649141335444215">"Չհաջողվեց ստեղծել պանակը"</string>
     <string name="query_error" msgid="1222448261663503501">"Փաստաթղթերին հարցում կատարելիս սխալ տեղի ունեցավ"</string>
     <string name="root_recent" msgid="4470053704320518133">"Վերջին"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ազատ է"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Հնարավոր չէ բացել ֆայլը"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
     <string name="share_via" msgid="8966594246261344259">"Տարածել"</string>
+    <string name="cancel" msgid="6442560571259935130">"Չեղարկել"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Ֆայլերի պատճենում"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Մնացել է <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 1514fc6..4d28802 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Bagikan"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Hapus"</string>
     <string name="menu_select" msgid="8711270657353563424">"Pilih \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Pilih Semua"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Salin ke…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Tampilkan simpanan internal"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Tampilkan kartu SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Sembunyikan simpanan internal"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat menghapus beberapa dokumen"</string>
     <string name="share_via" msgid="8966594246261344259">"Bagikan melalui"</string>
+    <string name="cancel" msgid="6442560571259935130">"Batal"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Menyalin file"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+      <item quantity="one">Menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Menyiapkan salinan..."</string>
 </resources>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index f324dad..83ac621 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Deila"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Eyða"</string>
     <string name="menu_select" msgid="8711270657353563424">"Velja „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Velja allt"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Afrita í ..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Sýna innbyggða geymslu"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Sýna SD-kort"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Fela innbyggða geymslu"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Ekki er hægt að opna skrána"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ekki er hægt að eyða einhverjum skjölum"</string>
     <string name="share_via" msgid="8966594246261344259">"Deila í gegnum"</string>
+    <string name="cancel" msgid="6442560571259935130">"Hætta við"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Afritar skrár"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> eftir"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Afritar <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
+      <item quantity="other">Afritar <xliff:g id="COUNT_1">%1$d</xliff:g> skrár.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index a073c44..d85ae95 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Condividi"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Elimina"</string>
     <string name="menu_select" msgid="8711270657353563424">"Seleziona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Seleziona tutti"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copia in…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostra memoria interna"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostra scheda SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Nascondi memoria interna"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Impossibile aprire il file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossibile eliminare alcuni documenti"</string>
     <string name="share_via" msgid="8966594246261344259">"Condividi via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Annulla"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copia di file in corso"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> rimanenti"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Copia di <xliff:g id="COUNT_1">%1$d</xliff:g> file in corso.</item>
+      <item quantity="one">Copia di <xliff:g id="COUNT_0">%1$d</xliff:g> file in corso.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 6ab2880..12c7240 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"שתף"</string>
     <string name="menu_delete" msgid="8138799623850614177">"מחק"</string>
     <string name="menu_select" msgid="8711270657353563424">"בחר ב-\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"בחר הכל"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"העתק אל…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"הצג אחסון פנימי"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"‏הצג כרטיס SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"הסתר אחסון פנימי"</string>
@@ -55,4 +57,14 @@
     <string name="toast_no_application" msgid="1339885974067891667">"לא ניתן לפתוח את הקובץ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
     <string name="share_via" msgid="8966594246261344259">"שתף באמצעות"</string>
+    <string name="cancel" msgid="6442560571259935130">"ביטול"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"מעתיק קבצים"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"זמן נותר: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="two">מעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+      <item quantity="many">מעתיק <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="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index f57a21c..29be902 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"共有"</string>
     <string name="menu_delete" msgid="8138799623850614177">"削除"</string>
     <string name="menu_select" msgid="8711270657353563424">"「<xliff:g id="DIRECTORY">^1</xliff:g>」を選択"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"すべて選択"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"コピー…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"内部ストレージを表示"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SDカードを表示"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"内部ストレージを非表示"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ファイルを開けません"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
     <string name="share_via" msgid="8966594246261344259">"共有ツール"</string>
+    <string name="cancel" msgid="6442560571259935130">"キャンセル"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ファイルのコピー中"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"残り<xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index b1e39b8..03bc0a4 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"გაზიარება"</string>
     <string name="menu_delete" msgid="8138799623850614177">"წაშლა"</string>
     <string name="menu_select" msgid="8711270657353563424">"„<xliff:g id="DIRECTORY">^1</xliff:g>“-ის არჩევა"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"ყველას არჩევა"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"კოპირება…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"შიდა საცავის ჩვენება"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ბარათის ჩვენება"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"შიდა მეხსიერების დამალვა"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ფაილის გახსნა ვერ ხერხდება"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
     <string name="share_via" msgid="8966594246261344259">"გაზიარება:"</string>
+    <string name="cancel" msgid="6442560571259935130">"გაუქმება"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"მიმდ. ფაილების კოპირება"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"დარჩა <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index c7e207c..4f43ca8 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Бөлісу"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Жою"</string>
     <string name="menu_select" msgid="8711270657353563424">"«<xliff:g id="DIRECTORY">^1</xliff:g>» таңдау"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Барлығын таңдау"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Көшіру орны…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ішкі жадты көрсету"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD картасын көрсету"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ішкі жадты жасыру"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Файлды аша алмады"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Кейбір құжаттарды жою мүмкін болмады"</string>
     <string name="share_via" msgid="8966594246261344259">"арқылы бөлісу"</string>
+    <string name="cancel" msgid="6442560571259935130">"Бас тарту"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Файлдарды көшіру"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> қалды"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 3055001..82400ff 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"ចែករំលែក​"</string>
     <string name="menu_delete" msgid="8138799623850614177">"លុប"</string>
     <string name="menu_select" msgid="8711270657353563424">"ជ្រើស \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"ជ្រើសរើសទាំងអស់"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"ថតចម្លងទៅ…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"បង្ហាញឧបករណ៍ផ្ទុកខាងក្នុង"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"បង្ហាញកាតអេសឌី"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"លាក់​ឧបករណ៍​​ផ្ទុក​ខាងក្នុង"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"មិន​អាច​បើក​ឯកសារ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"មិន​អាច​លុប​ឯកសារ​មួយ​ចំនួន"</string>
     <string name="share_via" msgid="8966594246261344259">"ចែករំលែក​តាម"</string>
+    <string name="cancel" msgid="6442560571259935130">"បោះ​បង់​"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"កំពុងថតចម្លងឯកសារ"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"នៅសល់ <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 508f0e5..03c42a4 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"ಹಂಚು"</string>
     <string name="menu_delete" msgid="8138799623850614177">"ಅಳಿಸು"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"ಎಲ್ಲವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"ಇದಕ್ಕೆ ನಕಲಿಸಿ…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆಯನ್ನು ತೋರಿಸು"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ಕಾಡ್‌ ಅನ್ನು ತೋರಿಸು"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆಯನ್ನು ಮರೆಮಾಡಿ"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ಕೆಲವು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="share_via" msgid="8966594246261344259">"ಈ ಮೂಲಕ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡು"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ಉಳಿದಿದೆ"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d6f0cbd..6080cf2 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"공유"</string>
     <string name="menu_delete" msgid="8138799623850614177">"삭제"</string>
     <string name="menu_select" msgid="8711270657353563424">"\'<xliff:g id="DIRECTORY">^1</xliff:g>\' 선택"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"모두 선택"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"복사…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"내부 저장소 표시"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD 카드 표시"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"내부 저장소 숨기기"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"파일을 열 수 없음"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"일부 문서를 삭제할 수 없음"</string>
     <string name="share_via" msgid="8966594246261344259">"공유 방법"</string>
+    <string name="cancel" msgid="6442560571259935130">"취소"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"파일 복사 중"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> 남음"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index a4f718b..2e62a47 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Бөлүшүү"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Өчүрүү"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" тандоо"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Бардыгын тандоо"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Төмөнкүгө көчүрүү…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ички сактагычты көрсөтүү"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD картаны көрсөтүү"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ички эстутумду жашыруу"</string>
@@ -55,4 +57,14 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Файл ачылбады"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Кээ бир документтерди өчүрүү кыйрады"</string>
     <string name="share_via" msgid="8966594246261344259">"Кийинки аркылуу бөлүшүү:"</string>
+    <!-- no translation found for cancel (6442560571259935130) -->
+    <skip />
+    <string name="copy_notification_title" msgid="6374299806748219777">"Файлдар көчүрүлүүдө"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> калды"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 8db69c7..5b7364f 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"ແບ່ງປັນ"</string>
     <string name="menu_delete" msgid="8138799623850614177">"ລຶບ"</string>
     <string name="menu_select" msgid="8711270657353563424">"ເລືອກ​ \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"ເລືອກທັງຫມົດ"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"ອັດ​ສຳ​ເນົາ​ໃສ່…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ສະແດງ​ໂຕເກັບ​ຂໍ້ມູນພາຍໃນ"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"ສະແດງ SD Card"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ເຊື່ອງ​ໂຕ​ເກັບຂໍ້ມູນ​ພາຍໃນ"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ບໍ່ສາມດາເປີດໄຟລ໌ໄດ້"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
     <string name="share_via" msgid="8966594246261344259">"ແບ່ງປັນຜ່ານ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ຍົກເລີກ"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ກຳ​ລັງ​ອັດ​ສຳ​ເນົາ​ໄຟ​ລ໌"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ຍັງ​ເຫຼືອ​ຢູ່"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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="copy_preparing" msgid="3896202461003039386">"ກຳ​ລັງ​ກຽມ​ອັດ​ສຳ​ເນົາ…"</string>
 </resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 81412c5..9a650c1 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Bendrinti"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Ištrinti"</string>
     <string name="menu_select" msgid="8711270657353563424">"Pasirinkti katalogą „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Pasirinkti viską"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopijuoti į..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Rodyti vidinę atmintį"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Rodyti SD kortelę"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Slėpti vidinę atmintį"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Nepavyksta atidaryti failo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nepavyko ištrinti kai kurių dokumentų"</string>
     <string name="share_via" msgid="8966594246261344259">"Bendrinti naudojant"</string>
+    <string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopijuojami failai"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Liko: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Kopijuojamas <xliff:g id="COUNT_1">%1$d</xliff:g> failas.</item>
+      <item quantity="few">Kopijuojami <xliff:g id="COUNT_1">%1$d</xliff:g> failai.</item>
+      <item quantity="many">Kopijuojama <xliff:g id="COUNT_1">%1$d</xliff:g> failo.</item>
+      <item quantity="other">Kopijuojama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 0cd5812..4130d4f 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Kopīgot"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Dzēst"</string>
     <string name="menu_select" msgid="8711270657353563424">"Atlasīt “<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Atlasīt visus"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopēt…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Rādīt iekšējo atmiņu"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Rādīt SD karti"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Paslēpt iekšējo atmiņu"</string>
@@ -55,4 +57,14 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Nevar atvērt failu."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nevar dzēst dažus dokumentus."</string>
     <string name="share_via" msgid="8966594246261344259">"Kopīgot, izmantojot"</string>
+    <string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Notiek failu kopēšana"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Atlikušais laiks: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="zero">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu kopēšana.</item>
+      <item quantity="one">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> faila kopēšana.</item>
+      <item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu kopēšana.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index d909741..927487d 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Сподели"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Избриши"</string>
     <string name="menu_select" msgid="8711270657353563424">"Одберете „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Избери ги сите"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Копирај во…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Прикажи внатрешна мемор."</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Прикажи СД-картичка"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Скриј внатрешна меморија"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Датотеката не се отвора"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Некои документи не може да се избришат"</string>
     <string name="share_via" msgid="8966594246261344259">"Сподели преку"</string>
+    <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Се копираат датотеки"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Уште <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 24f4815..3b9b0d9 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"പങ്കിടുക"</string>
     <string name="menu_delete" msgid="8138799623850614177">"ഇല്ലാതാക്കുക"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" തിരഞ്ഞെടുക്കുക"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"എല്ലാം തിരഞ്ഞെടുക്കുക"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"ഇതിൽ പകർത്തുക…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ആന്തരിക സംഭരണം കാണിക്കുക"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD കാർഡ് കാണിക്കുക"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ആന്തരിക സംഭരണം മറയ്‌ക്കുക"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ഫയൽ തുറക്കാനായില്ല"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ചില പ്രമാണങ്ങൾ ഇല്ലാതാക്കാനായില്ല"</string>
     <string name="share_via" msgid="8966594246261344259">"ഇതുവഴി പങ്കിടുക"</string>
+    <string name="cancel" msgid="6442560571259935130">"റദ്ദാക്കുക"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ഫയലുകൾ പകർത്തുന്നു"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 141032d..00b52db 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Хуваалцах"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Устгах"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\"-г сонгох"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Бүгдийг сонгох"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"...руу хуулах"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Дотоод санг харуулах"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD картыг харуулах"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Дотоод санг нуух"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Файлыг нээх боломжгүй"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
     <string name="share_via" msgid="8966594246261344259">"Дараахаар дамжуулан хуваалцах"</string>
+    <string name="cancel" msgid="6442560571259935130">"Цуцлах"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Файлуудыг хуулж байна"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> үлдсэн"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index b59ded5..c100970 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"सामायिक करा"</string>
     <string name="menu_delete" msgid="8138799623850614177">"हटवा"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" निवडा"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"सर्व निवडा"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"यावर कॉपी करा…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"अंतर्गत संचयन दर्शवा"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड दर्शवा"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"अंतर्गत संचयन लपवा"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"फाईल उघडू शकत नाही"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"काही दस्‍तऐवज हटविण्‍यात अक्षम"</string>
     <string name="share_via" msgid="8966594246261344259">"द्वारे सामायिक करा"</string>
+    <string name="cancel" msgid="6442560571259935130">"रद्द करा"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"फायली कॉपी करीत आहे"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> शिल्लक"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 5330d92..f50aa78 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Kongsi"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Padam"</string>
     <string name="menu_select" msgid="8711270657353563424">"Pilih \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Pilih Semua"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Salin ke..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Papar storan dalaman"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Papar kad SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Sembunyikan storan dlmn"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka fail"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat memadam beberapa dokumen"</string>
     <string name="share_via" msgid="8966594246261344259">"Kongsi melalui"</string>
+    <string name="cancel" msgid="6442560571259935130">"Batal"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Menyalin fail"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
+      <item quantity="one">Menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index 50f8363..3a860a4 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"မျှဝေခြင်း"</string>
     <string name="menu_delete" msgid="8138799623850614177">"ဖျက်ပစ်ရန်"</string>
     <string name="menu_select" msgid="8711270657353563424">"ရွေးရန်\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"အားလုံးရွေးရန်"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"သို့ကူးယူရန်…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"စက်ရှိစတိုရုံ ပြပါ"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ကဒ် ပြပါ"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"စက်ရှိစတိုရုံ ဖျောက်ထားပါ"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ဖိုင်အား ဖွင့်မရပါ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"တချို့ စာရွက်စာတန်းများ မဖျက်စီးနိုင်ပါ"</string>
     <string name="share_via" msgid="8966594246261344259">"မှ ဝေမျှပါ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ထားတော့"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ဖိုင်များကူယူနေသည်"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ကျန်ရှိသည်"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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="copy_preparing" msgid="3896202461003039386">"မိတ္တူကူးရန်ပြင်ဆင်နေ..."</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index beee44f..e1254a3 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Del"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Slett"</string>
     <string name="menu_select" msgid="8711270657353563424">"Velg «<xliff:g id="DIRECTORY">^1</xliff:g>»"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Velg alle"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiér til …"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Vis den interne lagringen"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Vis SD-kortet"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skjul den interne lagringen"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Kan ikke åpne filen"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Enkelte dokumenter kunne ikke slettes"</string>
     <string name="share_via" msgid="8966594246261344259">"Del via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> gjenstår"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+      <item quantity="one">Kopierer <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index 4251a7c..7c300e3 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"साझेदारी गर्नुहोस्"</string>
     <string name="menu_delete" msgid="8138799623850614177">"मेटाउनुहोस्"</string>
     <string name="menu_select" msgid="8711270657353563424">"चयनगर्नुहोस् \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"सबै चयन गर्नुहोस्"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"यसमा प्रतिलिपि गर्नुहोस् ..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"आन्तरिक भण्डारण देखाउनुहोस्"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड देखाउनुहोस्"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"आन्तरिक भण्डारण लुकाउनुहोस्"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"फाइल खोल्न सक्दैन"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
     <string name="share_via" msgid="8966594246261344259">"माध्यमबाट साझेदारी गर्नुहोस्"</string>
+    <string name="cancel" msgid="6442560571259935130">"रद्द गर्नुहोस्"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"फाइलहरू प्रतिलिपि गर्दै:"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g>बाँकी"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 1fc7dc1..593451a 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Delen"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Verwijderen"</string>
     <string name="menu_select" msgid="8711270657353563424">"<xliff:g id="DIRECTORY">^1</xliff:g> selecteren"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Alles selecteren"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiëren naar…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Interne opslag weergeven"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-kaart weergeven"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Interne opslag verbergen"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Kan bestand niet openen"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Kan bepaalde documenten niet verwijderen"</string>
     <string name="share_via" msgid="8966594246261344259">"Delen via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Bestanden kopiëren"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> resterend"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden kopiëren.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand kopiëren.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 5bb7f75..94a78c2 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Udostępnij"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Usuń"</string>
     <string name="menu_select" msgid="8711270657353563424">"Zaznacz „<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Wybierz wszystko"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiuj do…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Pokaż pamięć wewnętrzną"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Pokaż kartę SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ukryj pamięć wewnętrzną"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Nie można otworzyć pliku"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
     <string name="share_via" msgid="8966594246261344259">"Udostępnij przez"</string>
+    <string name="cancel" msgid="6442560571259935130">"Anuluj"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopiowanie plików"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Pozostało: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="few">Kopiowanie <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
+      <item quantity="many">Kopiowanie <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
+      <item quantity="other">Kopiowanie <xliff:g id="COUNT_1">%1$d</xliff:g> pliku.</item>
+      <item quantity="one">Kopiowanie <xliff:g id="COUNT_0">%1$d</xliff:g> pliku.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index e32dfc9..50e59d6 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Partilhar"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
     <string name="menu_select" msgid="8711270657353563424">"Selecionar \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Selecionar tudo"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copiar para…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar mem. armaz. int."</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar cartão SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar mem. armaz. int."</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o ficheiro"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não é possível eliminar alguns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Partilhar através de"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"A copiar ficheiros"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Faltam <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">A copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+      <item quantity="one">A copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 2aaa4d2..a0a5821 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Excluir"</string>
     <string name="menu_select" msgid="8711270657353563424">"Selecionar \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Selecionar tudo"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copiar para..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar armaz. interno"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar cartão SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar armaz. interno"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+      <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index c5de856..679b43e 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Distribuiți"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Ștergeți"</string>
     <string name="menu_select" msgid="8711270657353563424">"Selectați „<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Selectați-le pe toate"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Copiați în…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Afișați stocarea internă"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Afișați cardul SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ascundeți stocarea internă"</string>
@@ -55,4 +57,14 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Fișierul nu poate fi deschis"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unele documente nu au putut fi șterse"</string>
     <string name="share_via" msgid="8966594246261344259">"Distribuiți prin"</string>
+    <string name="cancel" msgid="6442560571259935130">"Anulați"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Se copiază fișierele"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Timp rămas: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="few">Se copiază <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere.</item>
+      <item quantity="other">Se copiază <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere.</item>
+      <item quantity="one">Se copiază <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 10de6f0..651aa60 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Поделиться"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Удалить"</string>
     <string name="menu_select" msgid="8711270657353563424">"Выбрать папку \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Выбрать все"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Копировать в…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Внутренняя память"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-карта"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Скрыть внутреннюю память"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Не удалось открыть файл"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
     <string name="share_via" msgid="8966594246261344259">"Поделиться"</string>
+    <string name="cancel" msgid="6442560571259935130">"Отмена"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Копирование файлов"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Осталось <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файл...</item>
+      <item quantity="few">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
+      <item quantity="many">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файлов...</item>
+      <item quantity="other">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 26e2b1d..e388195 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"බෙදාගන්න"</string>
     <string name="menu_delete" msgid="8138799623850614177">"මකන්න"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" තෝරන්න"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"සියල්ල තෝරන්න"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"වෙත පිටපත් කරන්න..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"අභ්‍යන්තර ආචයනය පෙන්වන්න"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD කාඩ් පත පෙන්වන්න"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"අභ්‍යන්තර ආචයනය සඟවන්න"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ගොනුව විවෘත කළ නොහැක"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"සමහර ලේඛන මැකීමට නොහැකි විය"</string>
     <string name="share_via" msgid="8966594246261344259">"හරහා බෙදාගන්න"</string>
+    <string name="cancel" msgid="6442560571259935130">"අවලංගු කරන්න"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ගොනු පිටපත් කරමින්"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ඉතිරියි"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index facaf4a..5c5451b 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Zdieľať"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Odstrániť"</string>
     <string name="menu_select" msgid="8711270657353563424">"Vyberte adresár <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Vybrať všetko"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopírovať do…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Zobraziť interné úložisko"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Zobraziť kartu SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skryť interné úložisko"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Súbor sa nepodarilo otvoriť"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
     <string name="share_via" msgid="8966594246261344259">"Zdieľať pomocou"</string>
+    <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopírovanie súborov"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Zostáva: <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="few">Kopírujú sa <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
+      <item quantity="many">Kopíruje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súboru.</item>
+      <item quantity="other">Kopíruje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
+      <item quantity="one">Kopíruje sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 865df8b..76a9107 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Skupna raba"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
     <string name="menu_select" msgid="8711270657353563424">"Izbira mape »<xliff:g id="DIRECTORY">^1</xliff:g>«"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Izberi vse"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiranje v …"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Pokaži notranjo shrambo"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Pokaži kartico SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skrij notranjo shrambo"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Datoteke ni mogoče odpreti"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nekaterih dokumentov ni mogoče izbrisati"</string>
     <string name="share_via" msgid="8966594246261344259">"Deli z drugimi prek"</string>
+    <string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datotek"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Še <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+      <item quantity="two">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+      <item quantity="few">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+      <item quantity="other">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index fd20722..a2f9eb7 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Дели"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Избриши"</string>
     <string name="menu_select" msgid="8711270657353563424">"Изабери „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Изабери све"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Копирај на..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Прикажи интерну меморију"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Прикажи SD картицу"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Сакриј интерну меморију"</string>
@@ -55,4 +57,14 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Није могуће отворити датотеку"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
     <string name="share_via" msgid="8966594246261344259">"Делите преко"</string>
+    <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Копирање датотека"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Још <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
+      <item quantity="few">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
+      <item quantity="other">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index a77b75d..fe852b0 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Dela"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Ta bort"</string>
     <string name="menu_select" msgid="8711270657353563424">"Välj <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Markera alla"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiera till …"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Visa internminne"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Visa SD-kort"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Dölj internminne"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Det går inte att öppna filen"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Det gick inte att ta bort vissa dokument"</string>
     <string name="share_via" msgid="8966594246261344259">"Dela via"</string>
+    <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopierar filer"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> återstår"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Kopierar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+      <item quantity="one">Kopierar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index b46d97f..a9d0ad6 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Shiriki"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Futa"</string>
     <string name="menu_select" msgid="8711270657353563424">"Chagua \" <xliff:g id="DIRECTORY">^1</xliff:g> \""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Chagua Zote"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Nakili kwenda..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Onyesha hifadhi ya ndani"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Onyesha kadi ya SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ficha hifadhi ya ndani"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Haiwezi kufungua faili"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Imeshindwa kufuta baadhi ya hati"</string>
     <string name="share_via" msgid="8966594246261344259">"Shiriki kupitia"</string>
+    <string name="cancel" msgid="6442560571259935130">"Ghairi"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Inanakili faili"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Zimesalia <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Inanakili faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+      <item quantity="one">Inanakili faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index 5b09b97..b597486 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"பகிர்"</string>
     <string name="menu_delete" msgid="8138799623850614177">"நீக்கு"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" ஐத் தேர்ந்தெடு"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"எல்லாவற்றையும் தேர்ந்தெடு"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"இங்கு நகலெடு…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"அகச் சேமிப்பகத்தைக் காட்டு"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD கார்டைக் காட்டு"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"அகச் சேமிப்பகத்தை மறை"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"கோப்பைத் திறக்க முடியவில்லை"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
     <string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
+    <string name="cancel" msgid="6442560571259935130">"ரத்துசெய்"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"கோப்புகளை நகலெடுத்தல்"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> மீதமுள்ளது"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index e04724a..512d365 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"భాగస్వామ్యం చేయి"</string>
     <string name="menu_delete" msgid="8138799623850614177">"తొలగించు"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\"ని ఎంచుకోండి"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"అన్నీ ఎంచుకోండి"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"ఇక్కడికి కాపీ చేయి…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"అంతర్గత నిల్వను చూపు"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD కార్డ్‌ను చూపు"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"అంతర్గత నిల్వను దాచు"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ఫైల్‌ను తెరవడం సాధ్యపడదు"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"కొన్ని పత్రాలను తొలగించడం సాధ్యపడలేదు"</string>
     <string name="share_via" msgid="8966594246261344259">"దీని ద్వారా భాగస్వామ్యం చేయండి"</string>
+    <string name="cancel" msgid="6442560571259935130">"రద్దు చేయండి"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"ఫైల్‌లు కాపీ అవుతున్నాయి"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> మిగిలి ఉంది"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 5410d37..378103b 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"แชร์"</string>
     <string name="menu_delete" msgid="8138799623850614177">"ลบ"</string>
     <string name="menu_select" msgid="8711270657353563424">"เลือก \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"เลือกทั้งหมด"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"คัดลอกไปยัง…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"แสดงที่จัดเก็บภายใน"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"แสดงการ์ด SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ซ่อนที่จัดเก็บภายใน"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"ไม่สามารถเปิดไฟล์ได้"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
     <string name="share_via" msgid="8966594246261344259">"แชร์ผ่าน"</string>
+    <string name="cancel" msgid="6442560571259935130">"ยกเลิก"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"กำลังคัดลอกไฟล์"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"เหลือ <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 3defd6a..b0bf5eb 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Ibahagi"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Tanggalin"</string>
     <string name="menu_select" msgid="8711270657353563424">"Piliin ang \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Piliin Lahat"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopyahin sa..."</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ipakita internal storage"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Ipakita ang SD card"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Itago internal storage"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Hindi mabuksan ang file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Hindi matanggal ang ilang dokumento"</string>
     <string name="share_via" msgid="8966594246261344259">"Ibahagi sa pamamagitan ng"</string>
+    <string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kinokopya ang mga file"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> na lang ang natitira"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+      <item quantity="other">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Naghahanda para sa pagkopya…"</string>
 </resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 9f0f846..f4f9363 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Paylaş"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" dizinini seç"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Tümünü Seç"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopyala…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Dahili depolamayı göster"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD kartı göster"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Dahili depolamayı gizle"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Dosya açılamıyor"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Bazı dokümanlar silinemiyor"</string>
     <string name="share_via" msgid="8966594246261344259">"Şunu kullanarak paylaş:"</string>
+    <string name="cancel" msgid="6442560571259935130">"İptal"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Dosyalar kopyalanıyor"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> kaldı"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanıyor.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanıyor.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 5be1947..9781d11 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Поділитися"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Видалити"</string>
     <string name="menu_select" msgid="8711270657353563424">"Вибрати каталог \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Вибрати все"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Копіювати в…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Показати внутр. пам’ять"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Показати карту SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Сховати внутр. пам’ять"</string>
@@ -55,4 +57,15 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Не вдалося відкрити файл"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не вдалося видалити деякі документи"</string>
     <string name="share_via" msgid="8966594246261344259">"Надіслати через"</string>
+    <string name="cancel" msgid="6442560571259935130">"Скасувати"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Копіювання файлів"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Залишилося <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
+      <item quantity="few">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+      <item quantity="many">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+      <item quantity="other">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 729fc7f..c07d607 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"اشتراک کریں"</string>
     <string name="menu_delete" msgid="8138799623850614177">"حذف کریں"</string>
     <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" منتخب کریں"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"سبھی منتخب کریں"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"اس پر کاپی ہو رہی ہے…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"داخلی اسٹوریج دکھائیں"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"‏SD کارڈ دکھائیں"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"داخلی اسٹوریج چھپائیں"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"فائل نہيں کھول سکتے ہیں"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"کچھ دستاویزات کو حذف کرنے سے قاصر"</string>
     <string name="share_via" msgid="8966594246261344259">"اشتراک کریں بذریعہ"</string>
+    <string name="cancel" msgid="6442560571259935130">"منسوخ کریں"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"فائلیں کاپی ہو رہی ہیں"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> باقی ہے"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index db35356..c3eaded 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Ulashish"</string>
     <string name="menu_delete" msgid="8138799623850614177">"O‘chirish"</string>
     <string name="menu_select" msgid="8711270657353563424">"“<xliff:g id="DIRECTORY">^1</xliff:g>” jildini tanlash"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Barchasini tanlash"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"...ga nusxalash"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ichki xotirani ko‘rsatish"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD kartani ko‘rsatish"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ichki xotirani berkitish"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Fayl ochilmadi"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ba’zi hujjatlar o‘chirilmadi"</string>
     <string name="share_via" msgid="8966594246261344259">"Quyidagi orqali ulashish"</string>
+    <string name="cancel" msgid="6442560571259935130">"Bekor qilish"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Fayllar nusxalanmoqda"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> qoldi"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
+      <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
 </resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index e4bbfda..78bccec 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Chia sẻ"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Xóa"</string>
     <string name="menu_select" msgid="8711270657353563424">"Chọn \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Chọn tất cả"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Sao chép vào…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Hiển thị bộ nhớ trong"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Hiển thị thẻ SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ẩn bộ nhớ trong"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Không thể mở tệp"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Không thể xóa một số tài liệu"</string>
     <string name="share_via" msgid="8966594246261344259">"Chia sẻ qua"</string>
+    <string name="cancel" msgid="6442560571259935130">"Hủy"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Đang sao chép tệp"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Còn <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="other">Đang sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
+      <item quantity="one">Đang sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
+    </plurals>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 4a44250..78fe5e3 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"分享"</string>
     <string name="menu_delete" msgid="8138799623850614177">"删除"</string>
     <string name="menu_select" msgid="8711270657353563424">"选择“<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"全选"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"复制到…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"显示内部存储设备"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"显示SD卡"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"隐藏内部存储设备"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"无法打开文件"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式"</string>
+    <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"正在复制文件"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"剩余时间:<xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index e245c12..f8ed983 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"分享"</string>
     <string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
     <string name="menu_select" msgid="8711270657353563424">"選取「<xliff:g id="DIRECTORY">^1</xliff:g>」"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"全部選取"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"複製到…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"顯示內部儲存空間"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"顯示 SD 卡"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"隱藏內部儲存空間"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"無法開啟檔案"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
+    <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"正在複製檔案"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 464a13e..8372133 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"共用"</string>
     <string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
     <string name="menu_select" msgid="8711270657353563424">"選取「<xliff:g id="DIRECTORY">^1</xliff:g>」"</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"全選"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"複製到…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"顯示內部儲存空間"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"顯示 SD 卡"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"隱藏內部儲存空間"</string>
@@ -55,4 +57,13 @@
     <string name="toast_no_application" msgid="1339885974067891667">"無法開啟檔案"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
+    <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"複製檔案"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <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>
+    <!-- no translation found for copy_preparing (3896202461003039386) -->
+    <skip />
 </resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index b35da3c..3178117 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -30,6 +30,8 @@
     <string name="menu_share" msgid="3075149983979628146">"Yabelana"</string>
     <string name="menu_delete" msgid="8138799623850614177">"Susa"</string>
     <string name="menu_select" msgid="8711270657353563424">"Khetha i-\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_select_all" msgid="4320518282375109902">"Khetha konke"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopishela ku…"</string>
     <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Bonisa isitoreji sangaphakathi"</string>
     <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Bonisa ikhadi le-SD"</string>
     <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Fihla isitoreji sangaphakathi"</string>
@@ -55,4 +57,12 @@
     <string name="toast_no_application" msgid="1339885974067891667">"Ayikwazi ukuvula ifayela"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
     <string name="share_via" msgid="8966594246261344259">"Yabelana nge-"</string>
+    <string name="cancel" msgid="6442560571259935130">"Khansela"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Ikopisha amafayela"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> okusele"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+      <item quantity="other">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+    </plurals>
+    <string name="copy_preparing" msgid="3896202461003039386">"Ilungiselela ukukopisha..."</string>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 268ce18..062d433 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -46,6 +46,10 @@
     <string name="menu_delete">Delete</string>
     <!-- Menu item title that selects the current directory [CHAR LIMIT=48] -->
     <string name="menu_select">Select \"<xliff:g id="directory" example="My Directory">^1</xliff:g>\"</string>
+    <!-- Menu item title that selects all documents in the current directory [CHAR LIMIT=24] -->
+    <string name="menu_select_all">Select All</string>
+    <!-- Menu item title that copies the selected documents [CHAR LIMIT=24] -->
+    <string name="menu_copy">Copy to\u2026</string>
 
     <!-- Menu item that reveals internal storage built into the device [CHAR LIMIT=24] -->
     <string name="menu_advanced_show" product="nosdcard">Show internal storage</string>
@@ -61,6 +65,9 @@
     <!-- Menu item that hides the sizes of displayed files [CHAR LIMIT=24] -->
     <string name="menu_file_size_hide">Hide file size</string>
 
+    <!-- Button label that copies files to the current directory [CHAR LIMIT=48] -->
+    <string name="button_copy">Copy</string>
+
     <!-- Action mode title summarizing the number of documents selected [CHAR LIMIT=32] -->
     <string name="mode_selected_count"><xliff:g id="count" example="3">%1$d</xliff:g> selected</string>
 
@@ -108,4 +115,28 @@
     <!-- Title of dialog when prompting user to select an app to share documents with [CHAR LIMIT=32] -->
     <string name="share_via">Share via</string>
 
+    <!-- Title of the copy notification [CHAR LIMIT=24] -->
+    <string name="copy_notification_title">Copying files</string>
+    <!-- Text shown on the copy notification to indicate remaining time, in minutes [CHAR LIMIT=24] -->
+    <string name="copy_remaining"><xliff:g id="duration" example="3 minutes">%s</xliff:g> left</string>
+    <!-- Toast shown when a file copy is kicked off -->
+    <plurals name="copy_begin">
+      <item quantity="one">Copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
+      <item quantity="other">Copying <xliff:g id="count" example="3">%1$d</xliff:g> files.</item>
+    </plurals>
+    <!-- Text shown on the copy notification while DocumentsUI performs setup in preparation for copying files [CHAR LIMIT=32] -->
+    <string name="copy_preparing">Preparing for copy\u2026</string>
+    <!-- Title of the copy error notification [CHAR LIMIT=48] -->
+    <plurals name="copy_error_notification_title">
+      <item quantity="one">Error copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
+      <item quantity="other">Error copying <xliff:g id="count" example="1">%1$d</xliff:g> files.</item>
+    </plurals>
+    <!-- Second line for notifications saying that more information will be shown after touching [CHAR LIMIT=48] -->
+    <string name="notification_touch_for_details">Touch to view details</string>
+    <!-- Label of a dialog button for retrying a failed operation [CHAR LIMIT=24] -->
+    <string name="retry">Retry</string>
+    <!-- Title of the copying failure alert dialog. [CHAR LIMIT=48] -->
+    <string name="copy_failure_alert_title">Error copying files</string>
+    <!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] -->
+    <string name="copy_failure_alert_content">Following files are not copied: <xliff:g id="list">%1$s</xliff:g></string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 04692f6..39c958e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -43,4 +43,22 @@
         <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
     </style>
 
+    <style name="StandaloneTheme" parent="android:Theme.DeviceDefault.Light">
+        <item name="android:actionBarWidgetTheme">@null</item>
+        <item name="android:actionBarTheme">@*android:style/ThemeOverlay.Material.Dark.ActionBar</item>
+        <item name="android:actionBarPopupTheme">@*android:style/ThemeOverlay.Material.Light</item>
+
+        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_900</item>
+        <item name="android:colorPrimary">@*android:color/material_blue_grey_800</item>
+        <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
+
+        <item name="android:listDivider">@*android:drawable/list_divider_material</item>
+
+        <item name="android:windowActionBar">false</item>
+        <item name="android:windowActionModeOverlay">true</item>
+        <item name="android:windowNoTitle">true</item>
+
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+    </style>
+
 </resources>
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
new file mode 100644
index 0000000..66792da
--- /dev/null
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -0,0 +1,166 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.pm.ResolveInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.DurableUtils;
+import com.android.documentsui.model.RootInfo;
+import com.google.common.collect.Maps;
+
+abstract class BaseActivity extends Activity {
+    public abstract State getDisplayState();
+    public abstract RootInfo getCurrentRoot();
+    public abstract void onStateChanged();
+    public abstract void setRootsDrawerOpen(boolean open);
+    public abstract void onDocumentPicked(DocumentInfo doc);
+    public abstract void onDocumentsPicked(List<DocumentInfo> docs);
+    public abstract DocumentInfo getCurrentDirectory();
+    public abstract void setPending(boolean pending);
+    public abstract void onStackPicked(DocumentStack stack);
+    public abstract void onPickRequested(DocumentInfo pickTarget);
+    public abstract void onAppPicked(ResolveInfo info);
+    public abstract void onRootPicked(RootInfo root, boolean closeDrawer);
+    public abstract void onSaveRequested(DocumentInfo replaceTarget);
+    public abstract void onSaveRequested(String mimeType, String displayName);
+
+    public static BaseActivity get(Fragment fragment) {
+        return (BaseActivity) fragment.getActivity();
+    }
+
+    public static abstract class DocumentsIntent {
+        /** Intent action name to open copy destination. */
+        public static String ACTION_OPEN_COPY_DESTINATION =
+                "com.android.documentsui.OPEN_COPY_DESTINATION";
+
+        /**
+         * Extra boolean flag for ACTION_OPEN_COPY_DESTINATION_STRING, which
+         * specifies if the destination directory needs to create new directory or not.
+         */
+        public static String EXTRA_DIRECTORY_COPY = "com.android.documentsui.DIRECTORY_COPY";
+    }
+
+    public static class State implements android.os.Parcelable {
+        public int action;
+        public String[] acceptMimes;
+
+        /** Explicit user choice */
+        public int userMode = MODE_UNKNOWN;
+        /** Derived after loader */
+        public int derivedMode = MODE_LIST;
+
+        /** Explicit user choice */
+        public int userSortOrder = SORT_ORDER_UNKNOWN;
+        /** Derived after loader */
+        public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
+
+        public boolean allowMultiple = false;
+        public boolean showSize = false;
+        public boolean localOnly = false;
+        public boolean forceAdvanced = false;
+        public boolean showAdvanced = false;
+        public boolean stackTouched = false;
+        public boolean restored = false;
+        public boolean directoryCopy = false;
+
+        /** Current user navigation stack; empty implies recents. */
+        public DocumentStack stack = new DocumentStack();
+        /** Currently active search, overriding any stack. */
+        public String currentSearch;
+
+        /** Instance state for every shown directory */
+        public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
+
+        public static final int ACTION_OPEN = 1;
+        public static final int ACTION_CREATE = 2;
+        public static final int ACTION_GET_CONTENT = 3;
+        public static final int ACTION_OPEN_TREE = 4;
+        public static final int ACTION_MANAGE = 5;
+        public static final int ACTION_BROWSE = 6;
+        public static final int ACTION_BROWSE_ALL = 7;
+        public static final int ACTION_OPEN_COPY_DESTINATION = 8;
+
+        public static final int MODE_UNKNOWN = 0;
+        public static final int MODE_LIST = 1;
+        public static final int MODE_GRID = 2;
+
+        public static final int SORT_ORDER_UNKNOWN = 0;
+        public static final int SORT_ORDER_DISPLAY_NAME = 1;
+        public static final int SORT_ORDER_LAST_MODIFIED = 2;
+        public static final int SORT_ORDER_SIZE = 3;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(action);
+            out.writeInt(userMode);
+            out.writeStringArray(acceptMimes);
+            out.writeInt(userSortOrder);
+            out.writeInt(allowMultiple ? 1 : 0);
+            out.writeInt(showSize ? 1 : 0);
+            out.writeInt(localOnly ? 1 : 0);
+            out.writeInt(forceAdvanced ? 1 : 0);
+            out.writeInt(showAdvanced ? 1 : 0);
+            out.writeInt(stackTouched ? 1 : 0);
+            out.writeInt(restored ? 1 : 0);
+            DurableUtils.writeToParcel(out, stack);
+            out.writeString(currentSearch);
+            out.writeMap(dirState);
+        }
+
+        public static final Creator<State> CREATOR = new Creator<State>() {
+            @Override
+            public State createFromParcel(Parcel in) {
+                final State state = new State();
+                state.action = in.readInt();
+                state.userMode = in.readInt();
+                state.acceptMimes = in.readStringArray();
+                state.userSortOrder = in.readInt();
+                state.allowMultiple = in.readInt() != 0;
+                state.showSize = in.readInt() != 0;
+                state.localOnly = in.readInt() != 0;
+                state.forceAdvanced = in.readInt() != 0;
+                state.showAdvanced = in.readInt() != 0;
+                state.stackTouched = in.readInt() != 0;
+                state.restored = in.readInt() != 0;
+                DurableUtils.readFromParcel(in, state.stack);
+                state.currentSearch = in.readString();
+                in.readMap(state.dirState, null);
+                return state;
+            }
+
+            @Override
+            public State[] newArray(int size) {
+                return new State[size];
+            }
+        };
+    }
+}
diff --git a/src/com/android/documentsui/CopyService.java b/src/com/android/documentsui/CopyService.java
new file mode 100644
index 0000000..d2ef3d7
--- /dev/null
+++ b/src/com/android/documentsui/CopyService.java
@@ -0,0 +1,466 @@
+/*
+ * 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 static com.android.documentsui.model.DocumentInfo.getCursorLong;
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import libcore.io.IoUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class CopyService extends IntentService {
+    public static final String TAG = "CopyService";
+
+    private static final String EXTRA_CANCEL = "com.android.documentsui.CANCEL";
+    public static final String EXTRA_SRC_LIST = "com.android.documentsui.SRC_LIST";
+    public static final String EXTRA_STACK = "com.android.documentsui.STACK";
+    public static final String EXTRA_FAILURE = "com.android.documentsui.FAILURE";
+
+    // TODO: Move it to a shared file when more operations are implemented.
+    public static final int FAILURE_COPY = 1;
+
+    private NotificationManager mNotificationManager;
+    private Notification.Builder mProgressBuilder;
+
+    // Jobs are serialized but a job ID is used, to avoid mixing up cancellation requests.
+    private String mJobId;
+    private volatile boolean mIsCancelled;
+    // Parameters of the copy job. Requests to an IntentService are serialized so this code only
+    // needs to deal with one job at a time.
+    private final ArrayList<Uri> mFailedFiles;
+    private long mBatchSize;
+    private long mBytesCopied;
+    private long mStartTime;
+    private long mLastNotificationTime;
+    // Speed estimation
+    private long mBytesCopiedSample;
+    private long mSampleTime;
+    private long mSpeed;
+    private long mRemainingTime;
+    // Provider clients are acquired for the duration of each copy job. Note that there is an
+    // implicit assumption that all srcs come from the same authority.
+    private ContentProviderClient mSrcClient;
+    private ContentProviderClient mDstClient;
+
+    public CopyService() {
+        super("CopyService");
+
+        mFailedFiles = new ArrayList<Uri>();
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (intent.hasExtra(EXTRA_CANCEL)) {
+            handleCancel(intent);
+        }
+        return super.onStartCommand(intent, flags, startId);
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        if (intent.hasExtra(EXTRA_CANCEL)) {
+            handleCancel(intent);
+            return;
+        }
+
+        final ArrayList<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
+        final DocumentStack stack = intent.getParcelableExtra(EXTRA_STACK);
+
+        try {
+            // Acquire content providers.
+            mSrcClient = DocumentsApplication.acquireUnstableProviderOrThrow(getContentResolver(),
+                    srcs.get(0).authority);
+            mDstClient = DocumentsApplication.acquireUnstableProviderOrThrow(getContentResolver(),
+                    stack.peek().authority);
+
+            setupCopyJob(srcs, stack);
+
+            for (int i = 0; i < srcs.size() && !mIsCancelled; ++i) {
+                copy(srcs.get(i), stack.peek());
+            }
+        } catch (Exception e) {
+            // Catch-all to prevent any copy errors from wedging the app.
+            Log.e(TAG, "Exceptions occurred during copying", e);
+        } finally {
+            ContentProviderClient.releaseQuietly(mSrcClient);
+            ContentProviderClient.releaseQuietly(mDstClient);
+
+            // Dismiss the ongoing copy notification when the copy is done.
+            mNotificationManager.cancel(mJobId, 0);
+
+            if (mFailedFiles.size() > 0) {
+                final Context context = getApplicationContext();
+                final Intent navigateIntent = new Intent(context, StandaloneActivity.class);
+                navigateIntent.putExtra(EXTRA_STACK, (Parcelable) stack);
+                navigateIntent.putExtra(EXTRA_FAILURE, FAILURE_COPY);
+                navigateIntent.putParcelableArrayListExtra(EXTRA_SRC_LIST, mFailedFiles);
+
+                final Notification.Builder errorBuilder = new Notification.Builder(this)
+                        .setContentTitle(context.getResources().
+                                getQuantityString(R.plurals.copy_error_notification_title,
+                                        mFailedFiles.size(), mFailedFiles.size()))
+                        .setContentText(getString(R.string.notification_touch_for_details))
+                        .setContentIntent(PendingIntent.getActivity(context, 0, navigateIntent,
+                                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT))
+                        .setCategory(Notification.CATEGORY_ERROR)
+                        .setSmallIcon(R.drawable.ic_menu_copy)
+                        .setAutoCancel(true);
+                mNotificationManager.notify(mJobId, 0, errorBuilder.build());
+            }
+
+            // TODO: Display a toast if the copy was cancelled.
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+    }
+
+    /**
+     * Sets up the CopyService to start tracking and sending notifications for the given batch of
+     * files.
+     *
+     * @param srcs A list of src files to copy.
+     * @param stack The copy destination stack.
+     * @throws RemoteException
+     */
+    private void setupCopyJob(ArrayList<DocumentInfo> srcs, DocumentStack stack)
+            throws RemoteException {
+        // Create an ID for this copy job. Use the timestamp.
+        mJobId = String.valueOf(SystemClock.elapsedRealtime());
+        // Reset the cancellation flag.
+        mIsCancelled = false;
+
+        final Context context = getApplicationContext();
+        final Intent navigateIntent = new Intent(context, StandaloneActivity.class);
+        navigateIntent.putExtra(EXTRA_STACK, (Parcelable) stack);
+
+        mProgressBuilder = new Notification.Builder(this)
+                .setContentTitle(getString(R.string.copy_notification_title))
+                .setContentIntent(PendingIntent.getActivity(context, 0, navigateIntent, 0))
+                .setCategory(Notification.CATEGORY_PROGRESS)
+                .setSmallIcon(R.drawable.ic_menu_copy)
+                .setOngoing(true);
+
+        final Intent cancelIntent = new Intent(this, CopyService.class);
+        cancelIntent.putExtra(EXTRA_CANCEL, mJobId);
+        mProgressBuilder.addAction(R.drawable.ic_cab_cancel,
+                getString(android.R.string.cancel), PendingIntent.getService(this, 0,
+                        cancelIntent, PendingIntent.FLAG_ONE_SHOT));
+
+        // Send an initial progress notification.
+        mProgressBuilder.setProgress(0, 0, true); // Indeterminate progress while setting up.
+        mProgressBuilder.setContentText(getString(R.string.copy_preparing));
+        mNotificationManager.notify(mJobId, 0, mProgressBuilder.build());
+
+        // Reset batch parameters.
+        mFailedFiles.clear();
+        mBatchSize = calculateFileSizes(srcs);
+        mBytesCopied = 0;
+        mStartTime = SystemClock.elapsedRealtime();
+        mLastNotificationTime = 0;
+        mBytesCopiedSample = 0;
+        mSampleTime = 0;
+        mSpeed = 0;
+        mRemainingTime = 0;
+
+        // TODO: Check preconditions for copy.
+        // - check that the destination has enough space and is writeable?
+        // - check MIME types?
+    }
+
+    /**
+     * Calculates the cumulative size of all the documents in the list. Directories are recursed
+     * into and totaled up.
+     *
+     * @param srcs
+     * @return Size in bytes.
+     * @throws RemoteException
+     */
+    private long calculateFileSizes(List<DocumentInfo> srcs) throws RemoteException {
+        long result = 0;
+        for (DocumentInfo src : srcs) {
+            if (Document.MIME_TYPE_DIR.equals(src.mimeType)) {
+                // Directories need to be recursed into.
+                result += calculateFileSizesHelper(src.derivedUri);
+            } else {
+                result += src.size;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Calculates (recursively) the cumulative size of all the files under the given directory.
+     *
+     * @throws RemoteException
+     */
+    private long calculateFileSizesHelper(Uri uri) throws RemoteException {
+        final String authority = uri.getAuthority();
+        final Uri queryUri = DocumentsContract.buildChildDocumentsUri(authority,
+                DocumentsContract.getDocumentId(uri));
+        final String queryColumns[] = new String[] {
+                Document.COLUMN_DOCUMENT_ID,
+                Document.COLUMN_MIME_TYPE,
+                Document.COLUMN_SIZE
+        };
+
+        long result = 0;
+        Cursor cursor = null;
+        try {
+            cursor = mSrcClient.query(queryUri, queryColumns, null, null, null);
+            while (cursor.moveToNext()) {
+                if (Document.MIME_TYPE_DIR.equals(
+                        getCursorString(cursor, Document.COLUMN_MIME_TYPE))) {
+                    // Recurse into directories.
+                    final Uri subdirUri = DocumentsContract.buildDocumentUri(authority,
+                            getCursorString(cursor, Document.COLUMN_DOCUMENT_ID));
+                    result += calculateFileSizesHelper(subdirUri);
+                } else {
+                    // This may return -1 if the size isn't defined. Ignore those cases.
+                    long size = getCursorLong(cursor, Document.COLUMN_SIZE);
+                    result += size > 0 ? size : 0;
+                }
+            }
+        } finally {
+            IoUtils.closeQuietly(cursor);
+        }
+
+        return result;
+    }
+
+    /**
+     * Cancels the current copy job, if its ID matches the given ID.
+     *
+     * @param intent The cancellation intent.
+     */
+    private void handleCancel(Intent intent) {
+        final String cancelledId = intent.getStringExtra(EXTRA_CANCEL);
+        // Do nothing if the cancelled ID doesn't match the current job ID. This prevents racey
+        // cancellation requests from affecting unrelated copy jobs.
+        if (Objects.equals(mJobId, cancelledId)) {
+            // Set the cancel flag. This causes the copy loops to exit.
+            mIsCancelled = true;
+            // Dismiss the progress notification here rather than in the copy loop. This preserves
+            // interactivity for the user in case the copy loop is stalled.
+            mNotificationManager.cancel(mJobId, 0);
+        }
+    }
+
+    /**
+     * Logs progress on the current copy operation. Displays/Updates the progress notification.
+     *
+     * @param bytesCopied
+     */
+    private void makeProgress(long bytesCopied) {
+        mBytesCopied += bytesCopied;
+        double done = (double) mBytesCopied / mBatchSize;
+        String percent = NumberFormat.getPercentInstance().format(done);
+
+        // Update time estimate
+        long currentTime = SystemClock.elapsedRealtime();
+        long elapsedTime = currentTime - mStartTime;
+
+        // Send out progress notifications once a second.
+        if (currentTime - mLastNotificationTime > 1000) {
+            updateRemainingTimeEstimate(elapsedTime);
+            mProgressBuilder.setProgress(100, (int) (done * 100), false);
+            mProgressBuilder.setContentInfo(percent);
+            if (mRemainingTime > 0) {
+                mProgressBuilder.setContentText(getString(R.string.copy_remaining,
+                        DateUtils.formatDuration(mRemainingTime)));
+            } else {
+                mProgressBuilder.setContentText(null);
+            }
+            mNotificationManager.notify(mJobId, 0, mProgressBuilder.build());
+            mLastNotificationTime = currentTime;
+        }
+    }
+
+    /**
+     * Generates an estimate of the remaining time in the copy.
+     *
+     * @param elapsedTime The time elapsed so far.
+     */
+    private void updateRemainingTimeEstimate(long elapsedTime) {
+        final long sampleDuration = elapsedTime - mSampleTime;
+        final long sampleSpeed = ((mBytesCopied - mBytesCopiedSample) * 1000) / sampleDuration;
+        if (mSpeed == 0) {
+            mSpeed = sampleSpeed;
+        } else {
+            mSpeed = ((3 * mSpeed) + sampleSpeed) / 4;
+        }
+
+        if (mSampleTime > 0 && mSpeed > 0) {
+            mRemainingTime = ((mBatchSize - mBytesCopied) * 1000) / mSpeed;
+        } else {
+            mRemainingTime = 0;
+        }
+
+        mSampleTime = elapsedTime;
+        mBytesCopiedSample = mBytesCopied;
+    }
+
+    /**
+     * Copies a the given documents to the given location.
+     *
+     * @param srcInfo DocumentInfos for the documents to copy.
+     * @param dstDirInfo The destination directory.
+     * @throws RemoteException
+     */
+    private void copy(DocumentInfo srcInfo, DocumentInfo dstDirInfo) throws RemoteException {
+        final Uri dstUri = DocumentsContract.createDocument(mDstClient, dstDirInfo.derivedUri,
+                srcInfo.mimeType, srcInfo.displayName);
+        if (dstUri == null) {
+            // If this is a directory, the entire subdir will not be copied over.
+            Log.e(TAG, "Error while copying " + srcInfo.displayName);
+            mFailedFiles.add(srcInfo.derivedUri);
+            return;
+        }
+
+        if (Document.MIME_TYPE_DIR.equals(srcInfo.mimeType)) {
+            copyDirectoryHelper(srcInfo.derivedUri, dstUri);
+        } else {
+            copyFileHelper(srcInfo.derivedUri, dstUri);
+        }
+    }
+
+    /**
+     * Handles recursion into a directory and copying its contents. Note that in linux terms, this
+     * does the equivalent of "cp src/* dst", not "cp -r src dst".
+     *
+     * @param srcDirUri URI of the directory to copy from. The routine will copy the directory's
+     *            contents, not the directory itself.
+     * @param dstDirUri URI of the directory to copy to. Must be created beforehand.
+     * @throws RemoteException
+     */
+    private void copyDirectoryHelper(Uri srcDirUri, Uri dstDirUri) throws RemoteException {
+        // Recurse into directories. Copy children into the new subdirectory.
+        final String queryColumns[] = new String[] {
+                Document.COLUMN_DISPLAY_NAME,
+                Document.COLUMN_DOCUMENT_ID,
+                Document.COLUMN_MIME_TYPE,
+                Document.COLUMN_SIZE
+        };
+        final Uri queryUri = DocumentsContract.buildChildDocumentsUri(srcDirUri.getAuthority(),
+                DocumentsContract.getDocumentId(srcDirUri));
+        Cursor cursor = null;
+        try {
+            // Iterate over srcs in the directory; copy to the destination directory.
+            cursor = mSrcClient.query(queryUri, queryColumns, null, null, null);
+            while (cursor.moveToNext()) {
+                final String childMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+                final Uri dstUri = DocumentsContract.createDocument(mDstClient, dstDirUri,
+                        childMimeType, getCursorString(cursor, Document.COLUMN_DISPLAY_NAME));
+                final Uri childUri = DocumentsContract.buildDocumentUri(srcDirUri.getAuthority(),
+                        getCursorString(cursor, Document.COLUMN_DOCUMENT_ID));
+                if (Document.MIME_TYPE_DIR.equals(childMimeType)) {
+                    copyDirectoryHelper(childUri, dstUri);
+                } else {
+                    copyFileHelper(childUri, dstUri);
+                }
+            }
+        } finally {
+            IoUtils.closeQuietly(cursor);
+        }
+    }
+
+    /**
+     * Handles copying a single file.
+     *
+     * @param srcUri URI of the file to copy from.
+     * @param dstUri URI of the *file* to copy to. Must be created beforehand.
+     * @throws RemoteException
+     */
+    private void copyFileHelper(Uri srcUri, Uri dstUri) throws RemoteException {
+        // Copy an individual file.
+        CancellationSignal canceller = new CancellationSignal();
+        ParcelFileDescriptor srcFile = null;
+        ParcelFileDescriptor dstFile = null;
+        InputStream src = null;
+        OutputStream dst = null;
+
+        boolean errorOccurred = false;
+        try {
+            srcFile = mSrcClient.openFile(srcUri, "r", canceller);
+            dstFile = mDstClient.openFile(dstUri, "w", canceller);
+            src = new ParcelFileDescriptor.AutoCloseInputStream(srcFile);
+            dst = new ParcelFileDescriptor.AutoCloseOutputStream(dstFile);
+
+            byte[] buffer = new byte[8192];
+            int len;
+            while (!mIsCancelled && ((len = src.read(buffer)) != -1)) {
+                dst.write(buffer, 0, len);
+                makeProgress(len);
+            }
+            srcFile.checkError();
+            dstFile.checkError();
+        } catch (IOException e) {
+            errorOccurred = true;
+            Log.e(TAG, "Error while copying " + srcUri.toString(), e);
+            mFailedFiles.add(srcUri);
+        } finally {
+            // This also ensures the file descriptors are closed.
+            IoUtils.closeQuietly(src);
+            IoUtils.closeQuietly(dst);
+        }
+
+        if (errorOccurred || mIsCancelled) {
+            // Clean up half-copied files.
+            canceller.cancel();
+            try {
+                DocumentsContract.deleteDocument(mDstClient, dstUri);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to clean up: " + srcUri, e);
+                // RemoteExceptions usually signal that the connection is dead, so there's no point
+                // attempting to continue. Propagate the exception up so the copy job is cancelled.
+                throw e;
+            }
+        }
+    }
+}
diff --git a/src/com/android/documentsui/CreateDirectoryFragment.java b/src/com/android/documentsui/CreateDirectoryFragment.java
index ba8c35f..1a17ee0 100644
--- a/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -70,7 +70,7 @@
             public void onClick(DialogInterface dialog, int which) {
                 final String displayName = text1.getText().toString();
 
-                final DocumentsActivity activity = (DocumentsActivity) getActivity();
+                final BaseActivity activity = (BaseActivity) getActivity();
                 final DocumentInfo cwd = activity.getCurrentDirectory();
 
                 new CreateDirectoryTask(activity, cwd, displayName).executeOnExecutor(
@@ -83,12 +83,12 @@
     }
 
     private class CreateDirectoryTask extends AsyncTask<Void, Void, DocumentInfo> {
-        private final DocumentsActivity mActivity;
+        private final BaseActivity mActivity;
         private final DocumentInfo mCwd;
         private final String mDisplayName;
 
         public CreateDirectoryTask(
-                DocumentsActivity activity, DocumentInfo cwd, String displayName) {
+                BaseActivity activity, DocumentInfo cwd, String displayName) {
             mActivity = activity;
             mCwd = cwd;
             mDisplayName = displayName;
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
index 39c2252..e2e9807 100644
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ b/src/com/android/documentsui/DirectoryFragment.java
@@ -16,17 +16,20 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE;
+import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE_ALL;
+import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
+import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
+import static com.android.documentsui.BaseActivity.State.MODE_GRID;
+import static com.android.documentsui.BaseActivity.State.MODE_LIST;
+import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
 import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
-import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
-import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
-import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN;
 import static com.android.documentsui.model.DocumentInfo.getCursorInt;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -50,6 +53,7 @@
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.Parcelable;
+import android.os.SystemProperties;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.text.format.DateUtils;
@@ -76,7 +80,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.ProviderExecutor.Preemptable;
 import com.android.documentsui.RecentsProvider.StateColumns;
 import com.android.documentsui.model.DocumentInfo;
@@ -97,6 +101,8 @@
 
     private AbsListView mCurrentView;
 
+    private List<DocumentInfo> mSelectedDocumentsForCopy;
+
     public static final int TYPE_NORMAL = 1;
     public static final int TYPE_SEARCH = 2;
     public static final int TYPE_RECENT_OPEN = 3;
@@ -106,6 +112,8 @@
     public static final int ANIM_DOWN = 3;
     public static final int ANIM_UP = 4;
 
+    public static final int REQUEST_COPY_DESTINATION = 1;
+
     private int mType = TYPE_NORMAL;
     private String mStateKey;
 
@@ -301,13 +309,13 @@
                     state.derivedMode = result.mode;
                 }
                 state.derivedSortOrder = result.sortOrder;
-                ((DocumentsActivity) context).onStateChanged();
+                ((BaseActivity) context).onStateChanged();
 
                 updateDisplayState();
 
                 // When launched into empty recents, show drawer
                 if (mType == TYPE_RECENT_OPEN && mAdapter.isEmpty() && !state.stackTouched) {
-                    ((DocumentsActivity) context).setRootsDrawerOpen(true);
+                    ((BaseActivity) context).setRootsDrawerOpen(true);
                 }
 
                 // Restore any previous instance state
@@ -335,6 +343,33 @@
     }
 
     @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        final Context context = getActivity();
+        final Resources res = context.getResources();
+
+        // There's only one request code right now. Replace this with a switch statement or
+        // something more scalable when more codes are added.
+        if (requestCode != REQUEST_COPY_DESTINATION) {
+            return;
+        }
+        if (resultCode == Activity.RESULT_CANCELED || data == null) {
+            // User pressed the back button or otherwise cancelled the destination pick. Don't
+            // proceed with the copy.
+            return;
+        }
+
+        final List<DocumentInfo> docs = mSelectedDocumentsForCopy;
+        final Intent copyIntent = new Intent(context, CopyService.class);
+        copyIntent.putParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST, new ArrayList<DocumentInfo>(docs));
+        copyIntent.putExtra(CopyService.EXTRA_STACK, data.getParcelableExtra(CopyService.EXTRA_STACK));
+
+        Toast.makeText(context,
+                res.getQuantityString(R.plurals.copy_begin, docs.size(), docs.size()),
+                Toast.LENGTH_SHORT).show();
+        context.startService(copyIntent);
+    }
+
+    @Override
     public void onStop() {
         super.onStop();
 
@@ -386,7 +421,7 @@
         // Mode change is just visual change; no need to kick loader, and
         // deliver change event immediately.
         state.derivedMode = state.userMode;
-        ((DocumentsActivity) getActivity()).onStateChanged();
+        ((BaseActivity) getActivity()).onStateChanged();
 
         updateDisplayState();
     }
@@ -441,7 +476,7 @@
                 final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
                 if (isDocumentEnabled(docMimeType, docFlags)) {
                     final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
-                    ((DocumentsActivity) getActivity()).onDocumentPicked(doc);
+                    ((BaseActivity) getActivity()).onDocumentPicked(doc);
                 }
             }
         }
@@ -463,11 +498,18 @@
             final MenuItem open = menu.findItem(R.id.menu_open);
             final MenuItem share = menu.findItem(R.id.menu_share);
             final MenuItem delete = menu.findItem(R.id.menu_delete);
+            final MenuItem copy = menu.findItem(R.id.menu_copy);
 
-            final boolean manageMode = state.action == ACTION_MANAGE;
-            open.setVisible(!manageMode);
-            share.setVisible(manageMode);
-            delete.setVisible(manageMode);
+            final boolean manageOrBrowse = (state.action == ACTION_MANAGE
+                    || state.action == ACTION_BROWSE || state.action == ACTION_BROWSE_ALL);
+
+            open.setVisible(!manageOrBrowse);
+            share.setVisible(manageOrBrowse);
+            delete.setVisible(manageOrBrowse);
+
+            // TODO: unhide copying when ready
+            copy.setVisible(manageOrBrowse &&
+                    SystemProperties.getBoolean("debug.documentsui.enable_copy", false));
 
             return true;
         }
@@ -487,7 +529,7 @@
 
             final int id = item.getItemId();
             if (id == R.id.menu_open) {
-                DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
+                BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
                 mode.finish();
                 return true;
 
@@ -501,6 +543,19 @@
                 mode.finish();
                 return true;
 
+            } else if (id == R.id.menu_copy) {
+                onCopyDocuments(docs);
+                mode.finish();
+                return true;
+
+            } else if (id == R.id.menu_select_all) {
+                int count = mCurrentView.getCount();
+                for (int i = 0; i < count; i++) {
+                    mCurrentView.setItemChecked(i, true);
+                }
+                updateDisplayState();
+                return true;
+
             } else {
                 return false;
             }
@@ -522,9 +577,7 @@
                 if (cursor != null) {
                     final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
                     final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
-                    if (!Document.MIME_TYPE_DIR.equals(docMimeType)) {
-                        valid = isDocumentEnabled(docMimeType, docFlags);
-                    }
+                    valid = isDocumentEnabled(docMimeType, docFlags);
                 }
 
                 if (!valid) {
@@ -553,8 +606,17 @@
 
     private void onShareDocuments(List<DocumentInfo> docs) {
         Intent intent;
-        if (docs.size() == 1) {
-            final DocumentInfo doc = docs.get(0);
+
+        // Filter out directories - those can't be shared.
+        List<DocumentInfo> docsForSend = Lists.newArrayList();
+        for (DocumentInfo doc: docs) {
+            if (!Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
+                docsForSend.add(doc);
+            }
+        }
+
+        if (docsForSend.size() == 1) {
+            final DocumentInfo doc = docsForSend.get(0);
 
             intent = new Intent(Intent.ACTION_SEND);
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -562,14 +624,14 @@
             intent.setType(doc.mimeType);
             intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);
 
-        } else if (docs.size() > 1) {
+        } else if (docsForSend.size() > 1) {
             intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             intent.addCategory(Intent.CATEGORY_DEFAULT);
 
             final ArrayList<String> mimeTypes = Lists.newArrayList();
             final ArrayList<Uri> uris = Lists.newArrayList();
-            for (DocumentInfo doc : docs) {
+            for (DocumentInfo doc : docsForSend) {
                 mimeTypes.add(doc.mimeType);
                 uris.add(doc.derivedUri);
             }
@@ -615,8 +677,29 @@
         }
     }
 
+    private void onCopyDocuments(List<DocumentInfo> docs) {
+        mSelectedDocumentsForCopy = docs;
+
+        // Pop up a dialog to pick a destination.  This is inadequate but works for now.
+        // TODO: Implement a picker that is to spec.
+        final Intent intent = new Intent(
+                BaseActivity.DocumentsIntent.ACTION_OPEN_COPY_DESTINATION,
+                Uri.EMPTY,
+                getActivity(),
+                DocumentsActivity.class);
+        boolean directoryCopy = false;
+        for (DocumentInfo info : docs) {
+            if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
+                directoryCopy = true;
+                break;
+            }
+        }
+        intent.putExtra(BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, directoryCopy);
+        startActivityForResult(intent, REQUEST_COPY_DESTINATION);
+    }
+
     private static State getDisplayState(Fragment fragment) {
-        return ((DocumentsActivity) fragment.getActivity()).getDisplayState();
+        return ((BaseActivity) fragment.getActivity()).getDisplayState();
     }
 
     private static abstract class Footer {
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 163615d..8e4ec8c 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -17,11 +17,11 @@
 package com.android.documentsui;
 
 import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_DISPLAY_NAME;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_DISPLAY_NAME;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_SIZE;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
 import static com.android.documentsui.model.DocumentInfo.getCursorInt;
 
 import android.content.AsyncTaskLoader;
@@ -36,7 +36,7 @@
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.RecentsProvider.StateColumns;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
diff --git a/src/com/android/documentsui/DirectoryView.java b/src/com/android/documentsui/DirectoryView.java
index 4f52a03..4893652 100644
--- a/src/com/android/documentsui/DirectoryView.java
+++ b/src/com/android/documentsui/DirectoryView.java
@@ -17,9 +17,6 @@
 package com.android.documentsui;
 
 import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.InsetDrawable;
 import android.util.AttributeSet;
 import android.widget.FrameLayout;
 
diff --git a/src/com/android/documentsui/DocumentsActivity.java b/src/com/android/documentsui/DocumentsActivity.java
index 8778f11..a2a789f 100644
--- a/src/com/android/documentsui/DocumentsActivity.java
+++ b/src/com/android/documentsui/DocumentsActivity.java
@@ -16,20 +16,21 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE;
+import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
+import static com.android.documentsui.BaseActivity.State.ACTION_GET_CONTENT;
+import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
+import static com.android.documentsui.BaseActivity.State.ACTION_OPEN;
+import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
+import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_COPY_DESTINATION;
+import static com.android.documentsui.BaseActivity.State.MODE_GRID;
+import static com.android.documentsui.BaseActivity.State.MODE_LIST;
 import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
 import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
 import static com.android.documentsui.DirectoryFragment.ANIM_SIDE;
 import static com.android.documentsui.DirectoryFragment.ANIM_UP;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN;
-import static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN_TREE;
-import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
-import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
 
 import android.app.Activity;
-import android.app.Fragment;
 import android.app.FragmentManager;
 import android.content.ActivityNotFoundException;
 import android.content.ClipData;
@@ -46,7 +47,6 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Root;
@@ -54,7 +54,6 @@
 import android.support.v4.widget.DrawerLayout;
 import android.support.v4.widget.DrawerLayout.DrawerListener;
 import android.util.Log;
-import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -73,25 +72,23 @@
 import android.widget.Toast;
 import android.widget.Toolbar;
 
+import libcore.io.IoUtils;
+
 import com.android.documentsui.RecentsProvider.RecentColumns;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.DurableUtils;
 import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Maps;
-
-import libcore.io.IoUtils;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.Executor;
 
-public class DocumentsActivity extends Activity {
+public class DocumentsActivity extends BaseActivity {
     public static final String TAG = "Documents";
 
     private static final String EXTRA_STATE = "state";
@@ -182,7 +179,7 @@
         setActionBar(mToolbar);
 
         // Hide roots when we're managing a specific root
-        if (mState.action == ACTION_MANAGE) {
+        if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
             if (mShowAsDialog) {
                 findViewById(R.id.container_roots).setVisibility(View.GONE);
             } else {
@@ -194,7 +191,8 @@
             final String mimeType = getIntent().getType();
             final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
             SaveFragment.show(getFragmentManager(), mimeType, title);
-        } else if (mState.action == ACTION_OPEN_TREE) {
+        } else if (mState.action == ACTION_OPEN_TREE ||
+                   mState.action == ACTION_OPEN_COPY_DESTINATION) {
             PickFragment.show(getFragmentManager());
         }
 
@@ -203,13 +201,15 @@
             moreApps.setComponent(null);
             moreApps.setPackage(null);
             RootsFragment.show(getFragmentManager(), moreApps);
-        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_CREATE
-                || mState.action == ACTION_OPEN_TREE) {
+        } else if (mState.action == ACTION_OPEN ||
+                   mState.action == ACTION_CREATE ||
+                   mState.action == ACTION_OPEN_TREE ||
+                   mState.action == ACTION_OPEN_COPY_DESTINATION) {
             RootsFragment.show(getFragmentManager(), null);
         }
 
         if (!mState.restored) {
-            if (mState.action == ACTION_MANAGE) {
+            if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
                 final Uri rootUri = getIntent().getData();
                 new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor());
             } else {
@@ -235,6 +235,10 @@
             mState.action = ACTION_OPEN_TREE;
         } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
             mState.action = ACTION_MANAGE;
+        } else if (DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT.equals(action)) {
+            mState.action = ACTION_BROWSE;
+        } else if (DocumentsIntent.ACTION_OPEN_COPY_DESTINATION.equals(action)) {
+            mState.action = ACTION_OPEN_COPY_DESTINATION;
         }
 
         if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
@@ -242,7 +246,7 @@
                     Intent.EXTRA_ALLOW_MULTIPLE, false);
         }
 
-        if (mState.action == ACTION_MANAGE) {
+        if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
             mState.acceptMimes = new String[] { "*/*" };
             mState.allowMultiple = true;
         } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
@@ -256,11 +260,15 @@
         mState.showAdvanced = mState.forceAdvanced
                 | LocalPreferences.getDisplayAdvancedDevices(this);
 
-        if (mState.action == ACTION_MANAGE) {
+        if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
             mState.showSize = true;
         } else {
             mState.showSize = LocalPreferences.getDisplayFileSize(this);
         }
+        if (mState.action == ACTION_OPEN_COPY_DESTINATION) {
+            mState.directoryCopy = intent.getBooleanExtra(
+                    BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false);
+        }
     }
 
     private class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> {
@@ -389,6 +397,7 @@
         updateActionBar();
     }
 
+    @Override
     public void setRootsDrawerOpen(boolean open) {
         if (!mShowAsDialog) {
             if (open) {
@@ -409,16 +418,19 @@
 
     public void updateActionBar() {
         if (mRootsToolbar != null) {
-            if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT
-                    || mState.action == ACTION_OPEN_TREE) {
+            if (mState.action == ACTION_OPEN ||
+                mState.action == ACTION_GET_CONTENT ||
+                mState.action == ACTION_OPEN_TREE) {
                 mRootsToolbar.setTitle(R.string.title_open);
-            } else if (mState.action == ACTION_CREATE) {
+            } else if (mState.action == ACTION_CREATE ||
+                       mState.action == ACTION_OPEN_COPY_DESTINATION) {
                 mRootsToolbar.setTitle(R.string.title_save);
             }
         }
 
         final RootInfo root = getCurrentRoot();
-        final boolean showRootIcon = mShowAsDialog || (mState.action == ACTION_MANAGE);
+        final boolean showRootIcon = mShowAsDialog
+                || (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE);
         if (showRootIcon) {
             mToolbar.setNavigationIcon(
                     root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
@@ -549,6 +561,7 @@
         final MenuItem list = menu.findItem(R.id.menu_list);
         final MenuItem advanced = menu.findItem(R.id.menu_advanced);
         final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
+        final MenuItem settings = menu.findItem(R.id.menu_settings);
 
         sort.setVisible(cwd != null);
         grid.setVisible(mState.derivedMode != MODE_GRID);
@@ -576,7 +589,8 @@
         sortSize.setVisible(mState.showSize);
 
         boolean searchVisible;
-        boolean fileSizeVisible = mState.action != ACTION_MANAGE;
+        boolean fileSizeVisible = !(mState.action == ACTION_MANAGE
+                || mState.action == ACTION_BROWSE);
         if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE) {
             createDir.setVisible(cwd != null && cwd.isCreateSupported());
             searchVisible = false;
@@ -606,9 +620,12 @@
         fileSize.setTitle(LocalPreferences.getDisplayFileSize(this)
                 ? R.string.menu_file_size_hide : R.string.menu_file_size_show);
 
-        advanced.setVisible(mState.action != ACTION_MANAGE);
+        advanced.setVisible(!(mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE));
         fileSize.setVisible(fileSizeVisible);
 
+        settings.setVisible((mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE)
+                && (root.flags & Root.FLAG_HAS_SETTINGS) != 0);
+
         return true;
     }
 
@@ -648,6 +665,13 @@
         } else if (id == R.id.menu_file_size) {
             setDisplayFileSize(!LocalPreferences.getDisplayFileSize(this));
             return true;
+        } else if (id == R.id.menu_settings) {
+            final RootInfo root = getCurrentRoot();
+            final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
+            intent.setDataAndType(DocumentsContract.buildRootUri(root.authority, root.rootId),
+                    DocumentsContract.Root.MIME_TYPE_ITEM);
+            startActivity(intent);
+            return true;
         } else {
             return super.onOptionsItemSelected(item);
         }
@@ -667,9 +691,7 @@
         invalidateOptionsMenu();
     }
 
-    /**
-     * Update UI to reflect internal state changes not from user.
-     */
+    @Override
     public void onStateChanged() {
         invalidateOptionsMenu();
     }
@@ -690,6 +712,7 @@
         DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
     }
 
+    @Override
     public void setPending(boolean pending) {
         final SaveFragment save = SaveFragment.get(getFragmentManager());
         if (save != null) {
@@ -808,6 +831,7 @@
         }
     };
 
+    @Override
     public RootInfo getCurrentRoot() {
         if (mState.stack.root != null) {
             return mState.stack.root;
@@ -816,6 +840,7 @@
         }
     }
 
+    @Override
     public DocumentInfo getCurrentDirectory() {
         return mState.stack.peek();
     }
@@ -834,6 +859,7 @@
         }
     }
 
+    @Override
     public State getDisplayState() {
         return mState;
     }
@@ -847,7 +873,9 @@
 
         if (cwd == null) {
             // No directory means recents
-            if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE) {
+            if (mState.action == ACTION_CREATE ||
+                mState.action == ACTION_OPEN_TREE ||
+                mState.action == ACTION_OPEN_COPY_DESTINATION) {
                 RecentsCreateFragment.show(fm);
             } else {
                 DirectoryFragment.showRecentsOpen(fm, anim);
@@ -876,12 +904,13 @@
             }
         }
 
-        if (mState.action == ACTION_OPEN_TREE) {
+        if (mState.action == ACTION_OPEN_TREE ||
+            mState.action == ACTION_OPEN_COPY_DESTINATION) {
             final PickFragment pick = PickFragment.get(fm);
             if (pick != null) {
                 final CharSequence displayName = (mState.stack.size() <= 1) ? root.title
                         : cwd.displayName;
-                pick.setPickTarget(cwd, displayName);
+                pick.setPickTarget(mState.action, cwd, displayName);
             }
         }
 
@@ -895,6 +924,7 @@
         dumpStack();
     }
 
+    @Override
     public void onStackPicked(DocumentStack stack) {
         try {
             // Update the restored stack to ensure we have freshest data
@@ -909,6 +939,7 @@
         }
     }
 
+    @Override
     public void onRootPicked(RootInfo root, boolean closeDrawer) {
         // Clear entire backstack and start in new root
         mState.stack.root = root;
@@ -955,6 +986,7 @@
         }
     }
 
+    @Override
     public void onAppPicked(ResolveInfo info) {
         final Intent intent = new Intent(getIntent());
         intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
@@ -985,6 +1017,7 @@
         }
     }
 
+    @Override
     public void onDocumentPicked(DocumentInfo doc) {
         final FragmentManager fm = getFragmentManager();
         if (doc.isDirectory()) {
@@ -1017,9 +1050,21 @@
                     Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
                 }
             }
+        } else if (mState.action == ACTION_BROWSE) {
+            // Go straight to viewing
+            final Intent view = new Intent(Intent.ACTION_VIEW);
+            view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            view.setData(doc.derivedUri);
+
+            try {
+                startActivity(view);
+            } catch (ActivityNotFoundException ex) {
+                Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
+            }
         }
     }
 
+    @Override
     public void onDocumentsPicked(List<DocumentInfo> docs) {
         if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
             final int size = docs.size();
@@ -1031,18 +1076,29 @@
         }
     }
 
+    @Override
     public void onSaveRequested(DocumentInfo replaceTarget) {
         new ExistingFinishTask(replaceTarget.derivedUri).executeOnExecutor(getCurrentExecutor());
     }
 
+    @Override
     public void onSaveRequested(String mimeType, String displayName) {
         new CreateFinishTask(mimeType, displayName).executeOnExecutor(getCurrentExecutor());
     }
 
+    @Override
     public void onPickRequested(DocumentInfo pickTarget) {
-        final Uri viaUri = DocumentsContract.buildTreeDocumentUri(pickTarget.authority,
-                pickTarget.documentId);
-        new PickFinishTask(viaUri).executeOnExecutor(getCurrentExecutor());
+        Uri result;
+        if (mState.action == ACTION_OPEN_TREE) {
+            result = DocumentsContract.buildTreeDocumentUri(
+                    pickTarget.authority, pickTarget.documentId);
+        } else if (mState.action == ACTION_OPEN_COPY_DESTINATION) {
+            result = pickTarget.derivedUri;
+        } else {
+            // Should not be reached.
+            throw new IllegalStateException("Invalid mState.action.");
+        }
+        new PickFinishTask(result).executeOnExecutor(getCurrentExecutor());
     }
 
     private void saveStackBlocking() {
@@ -1050,7 +1106,9 @@
         final ContentValues values = new ContentValues();
 
         final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
-        if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE) {
+        if (mState.action == ACTION_CREATE ||
+            mState.action == ACTION_OPEN_TREE ||
+            mState.action == ACTION_OPEN_COPY_DESTINATION) {
             // Remember stack for last create
             values.clear();
             values.put(RecentColumns.KEY, mState.stack.buildKey());
@@ -1083,11 +1141,14 @@
 
         if (mState.action == ACTION_GET_CONTENT) {
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        } else if (mState.action == ACTION_OPEN_TREE) {
+        } else if (mState.action == ACTION_OPEN_TREE ||
+                   mState.action == ACTION_OPEN_COPY_DESTINATION) {
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
+            // TODO: Move passing the stack to the separate ACTION_COPY action once it's implemented.
+            intent.putExtra(CopyService.EXTRA_STACK, (Parcelable)mState.stack);
         } else {
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
@@ -1188,102 +1249,6 @@
         }
     }
 
-    public static class State implements android.os.Parcelable {
-        public int action;
-        public String[] acceptMimes;
-
-        /** Explicit user choice */
-        public int userMode = MODE_UNKNOWN;
-        /** Derived after loader */
-        public int derivedMode = MODE_LIST;
-
-        /** Explicit user choice */
-        public int userSortOrder = SORT_ORDER_UNKNOWN;
-        /** Derived after loader */
-        public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
-
-        public boolean allowMultiple = false;
-        public boolean showSize = false;
-        public boolean localOnly = false;
-        public boolean forceAdvanced = false;
-        public boolean showAdvanced = false;
-        public boolean stackTouched = false;
-        public boolean restored = false;
-
-        /** Current user navigation stack; empty implies recents. */
-        public DocumentStack stack = new DocumentStack();
-        /** Currently active search, overriding any stack. */
-        public String currentSearch;
-
-        /** Instance state for every shown directory */
-        public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
-
-        public static final int ACTION_OPEN = 1;
-        public static final int ACTION_CREATE = 2;
-        public static final int ACTION_GET_CONTENT = 3;
-        public static final int ACTION_OPEN_TREE = 4;
-        public static final int ACTION_MANAGE = 5;
-
-        public static final int MODE_UNKNOWN = 0;
-        public static final int MODE_LIST = 1;
-        public static final int MODE_GRID = 2;
-
-        public static final int SORT_ORDER_UNKNOWN = 0;
-        public static final int SORT_ORDER_DISPLAY_NAME = 1;
-        public static final int SORT_ORDER_LAST_MODIFIED = 2;
-        public static final int SORT_ORDER_SIZE = 3;
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(action);
-            out.writeInt(userMode);
-            out.writeStringArray(acceptMimes);
-            out.writeInt(userSortOrder);
-            out.writeInt(allowMultiple ? 1 : 0);
-            out.writeInt(showSize ? 1 : 0);
-            out.writeInt(localOnly ? 1 : 0);
-            out.writeInt(forceAdvanced ? 1 : 0);
-            out.writeInt(showAdvanced ? 1 : 0);
-            out.writeInt(stackTouched ? 1 : 0);
-            out.writeInt(restored ? 1 : 0);
-            DurableUtils.writeToParcel(out, stack);
-            out.writeString(currentSearch);
-            out.writeMap(dirState);
-        }
-
-        public static final Creator<State> CREATOR = new Creator<State>() {
-            @Override
-            public State createFromParcel(Parcel in) {
-                final State state = new State();
-                state.action = in.readInt();
-                state.userMode = in.readInt();
-                state.acceptMimes = in.readStringArray();
-                state.userSortOrder = in.readInt();
-                state.allowMultiple = in.readInt() != 0;
-                state.showSize = in.readInt() != 0;
-                state.localOnly = in.readInt() != 0;
-                state.forceAdvanced = in.readInt() != 0;
-                state.showAdvanced = in.readInt() != 0;
-                state.stackTouched = in.readInt() != 0;
-                state.restored = in.readInt() != 0;
-                DurableUtils.readFromParcel(in, state.stack);
-                state.currentSearch = in.readString();
-                in.readMap(state.dirState, null);
-                return state;
-            }
-
-            @Override
-            public State[] newArray(int size) {
-                return new State[size];
-            }
-        };
-    }
-
     private void dumpStack() {
         Log.d(TAG, "Current stack: ");
         Log.d(TAG, " * " + mState.stack.root);
@@ -1291,8 +1256,4 @@
             Log.d(TAG, " +-- " + doc);
         }
     }
-
-    public static DocumentsActivity get(Fragment fragment) {
-        return (DocumentsActivity) fragment.getActivity();
-    }
 }
diff --git a/src/com/android/documentsui/FailureDialogFragment.java b/src/com/android/documentsui/FailureDialogFragment.java
new file mode 100644
index 0000000..1748c9c
--- /dev/null
+++ b/src/com/android/documentsui/FailureDialogFragment.java
@@ -0,0 +1,99 @@
+/*
+ * 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.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.DialogInterface;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Html;
+
+import com.android.documentsui.model.DocumentInfo;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+/**
+ * Alert dialog for failed operations.
+ */
+public class FailureDialogFragment extends DialogFragment
+        implements DialogInterface.OnClickListener {
+    private static final String TAG = "FailureDialogFragment";
+
+    private int mFailure;
+    private ArrayList<Uri> mFailedSrcList;
+
+    public static void show(FragmentManager fm, int failure, ArrayList<Uri> failedSrcList) {
+        // TODO: Add support for other failures than copy.
+        if (failure != CopyService.FAILURE_COPY) {
+            return;
+        }
+
+        final Bundle args = new Bundle();
+        args.putInt(CopyService.EXTRA_FAILURE, failure);
+        args.putParcelableArrayList(CopyService.EXTRA_SRC_LIST, failedSrcList);
+
+        final FragmentTransaction ft = fm.beginTransaction();
+        final FailureDialogFragment fragment = new FailureDialogFragment();
+        fragment.setArguments(args);
+
+        ft.add(fragment, TAG);
+        ft.commitAllowingStateLoss();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int whichButton) {
+      // TODO: Pass mFailure and mFailedSrcList to the parent fragment.
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle inState) {
+        super.onCreate(inState);
+
+        mFailure = getArguments().getInt(CopyService.EXTRA_FAILURE);
+        mFailedSrcList = getArguments().getParcelableArrayList(CopyService.EXTRA_SRC_LIST);
+
+        final StringBuilder list = new StringBuilder("<p>");
+        for (Uri documentUri : mFailedSrcList) {
+            try {
+                final DocumentInfo documentInfo = DocumentInfo.fromUri(
+                    getActivity().getContentResolver(), documentUri);
+                list.append(String.format("&#8226; %s<br>", documentInfo.displayName));
+            }
+            catch (FileNotFoundException ignore) {
+                // Source file most probably gone.
+            }
+        }
+        list.append("</p>");
+        final String message = String.format(getString(R.string.copy_failure_alert_content),
+                list.toString());
+
+        return new AlertDialog.Builder(getActivity())
+            .setTitle(getString(R.string.copy_failure_alert_title))
+            .setMessage(Html.fromHtml(message))
+            // TODO: Implement retrying the copy operation.
+            .setPositiveButton(R.string.retry, this)
+            .setNegativeButton(android.R.string.cancel, this)
+            .setIcon(android.R.drawable.ic_dialog_alert)
+            .create();
+    }
+}
diff --git a/src/com/android/documentsui/IconUtils.java b/src/com/android/documentsui/IconUtils.java
index 416aeb0..b43fedf 100644
--- a/src/com/android/documentsui/IconUtils.java
+++ b/src/com/android/documentsui/IconUtils.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
-import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.provider.DocumentsContract.Document;
 import android.util.TypedValue;
@@ -269,7 +268,7 @@
     public static Drawable applyTintColor(Context context, int drawableId, int tintColorId) {
         final Drawable icon = context.getDrawable(drawableId);
         icon.mutate();
-        icon.setTintList(context.getResources().getColorStateList(tintColorId));
+        icon.setTintList(context.getColorStateList(tintColorId));
         return icon;
     }
 
diff --git a/src/com/android/documentsui/PickFragment.java b/src/com/android/documentsui/PickFragment.java
index 5112c92..5e565bf 100644
--- a/src/com/android/documentsui/PickFragment.java
+++ b/src/com/android/documentsui/PickFragment.java
@@ -16,6 +16,8 @@
 
 package com.android.documentsui;
 
+import android.R.string;
+import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
@@ -40,6 +42,7 @@
 
     private View mContainer;
     private Button mPick;
+    private Button mCancel;
 
     public static void show(FragmentManager fm) {
         final PickFragment fragment = new PickFragment();
@@ -61,7 +64,10 @@
         mPick = (Button) mContainer.findViewById(android.R.id.button1);
         mPick.setOnClickListener(mPickListener);
 
-        setPickTarget(null, null);
+        mCancel = (Button) mContainer.findViewById(android.R.id.button2);
+        mCancel.setOnClickListener(mCancelListener);
+
+        setPickTarget(0, null, null);
 
         return mContainer;
     }
@@ -69,23 +75,48 @@
     private View.OnClickListener mPickListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
-            final DocumentsActivity activity = DocumentsActivity.get(PickFragment.this);
+            final BaseActivity activity = BaseActivity.get(PickFragment.this);
             activity.onPickRequested(mPickTarget);
         }
     };
 
-    public void setPickTarget(DocumentInfo pickTarget, CharSequence displayName) {
-        mPickTarget = pickTarget;
+    private View.OnClickListener mCancelListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            final BaseActivity activity = BaseActivity.get(PickFragment.this);
+            activity.setResult(Activity.RESULT_CANCELED);
+            activity.finish();
+        }
+    };
 
+    /**
+     * @param action Which action defined in BaseActivity.State is the picker shown for.
+     */
+    public void setPickTarget(int action,
+                              DocumentInfo pickTarget,
+                              CharSequence displayName) {
         if (mContainer != null) {
-            if (mPickTarget != null) {
+            if (pickTarget != null) {
                 mContainer.setVisibility(View.VISIBLE);
                 final Locale locale = getResources().getConfiguration().locale;
-                final String raw = getString(R.string.menu_select).toUpperCase(locale);
-                mPick.setText(TextUtils.expandTemplate(raw, displayName));
+                switch (action) {
+                    case BaseActivity.State.ACTION_OPEN_TREE:
+                        final String raw = getString(R.string.menu_select).toUpperCase(locale);
+                        mPick.setText(TextUtils.expandTemplate(raw, displayName));
+                        mCancel.setVisibility(View.GONE);
+                        break;
+                    case BaseActivity.State.ACTION_OPEN_COPY_DESTINATION:
+                        mPick.setText(getString(R.string.button_copy).toUpperCase(locale));
+                        mCancel.setVisibility(View.VISIBLE);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Illegal action for PickFragment.");
+                }
+
             } else {
                 mContainer.setVisibility(View.GONE);
             }
         }
+        mPickTarget = pickTarget;
     }
 }
diff --git a/src/com/android/documentsui/RecentLoader.java b/src/com/android/documentsui/RecentLoader.java
index 34ce42d..f5908c5 100644
--- a/src/com/android/documentsui/RecentLoader.java
+++ b/src/com/android/documentsui/RecentLoader.java
@@ -17,7 +17,7 @@
 package com.android.documentsui;
 
 import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
 
 import android.app.ActivityManager;
 import android.content.AsyncTaskLoader;
@@ -34,7 +34,7 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
 import com.google.android.collect.Maps;
 import com.google.common.collect.Lists;
diff --git a/src/com/android/documentsui/RecentsCreateFragment.java b/src/com/android/documentsui/RecentsCreateFragment.java
index dd75dbd..26aecc5 100644
--- a/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/src/com/android/documentsui/RecentsCreateFragment.java
@@ -45,7 +45,7 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.RecentsProvider.RecentColumns;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.DurableUtils;
@@ -95,7 +95,7 @@
         mListView.setAdapter(mAdapter);
 
         final RootsCache roots = DocumentsApplication.getRootsCache(context);
-        final State state = ((DocumentsActivity) getActivity()).getDisplayState();
+        final State state = ((BaseActivity) getActivity()).getDisplayState();
 
         mCallbacks = new LoaderCallbacks<List<DocumentStack>>() {
             @Override
@@ -110,7 +110,7 @@
 
                 // When launched into empty recents, show drawer
                 if (mAdapter.isEmpty() && !state.stackTouched) {
-                    ((DocumentsActivity) context).setRootsDrawerOpen(true);
+                    ((BaseActivity) context).setRootsDrawerOpen(true);
                 }
             }
 
@@ -139,7 +139,7 @@
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
             final DocumentStack stack = mAdapter.getItem(position);
-            ((DocumentsActivity) getActivity()).onStackPicked(stack);
+            ((BaseActivity) getActivity()).onStackPicked(stack);
         }
     };
 
diff --git a/src/com/android/documentsui/RootsCache.java b/src/com/android/documentsui/RootsCache.java
index d72db1d..27e8f20 100644
--- a/src/com/android/documentsui/RootsCache.java
+++ b/src/com/android/documentsui/RootsCache.java
@@ -36,7 +36,7 @@
 import android.provider.DocumentsContract.Root;
 import android.util.Log;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -360,14 +360,20 @@
 
             // Exclude read-only devices when creating
             if (state.action == State.ACTION_CREATE && !supportsCreate) continue;
+            if (state.action == State.ACTION_OPEN_COPY_DESTINATION && !supportsCreate) continue;
             // Exclude roots that don't support directory picking
             if (state.action == State.ACTION_OPEN_TREE && !supportsIsChild) continue;
             // Exclude advanced devices when not requested
             if (!state.showAdvanced && advanced) continue;
             // Exclude non-local devices when local only
             if (state.localOnly && !localOnly) continue;
+            // Exclude downloads roots that don't support directory creation
+            // TODO: Add flag to check the root supports directory creation or not.
+            if (state.directoryCopy && root.isDownloads()) continue;
             // Only show empty roots when creating
-            if (state.action != State.ACTION_CREATE && empty) continue;
+            if ((state.action != State.ACTION_CREATE ||
+                 state.action != State.ACTION_OPEN_TREE ||
+                 state.action != State.ACTION_OPEN_COPY_DESTINATION) && empty) continue;
 
             // Only include roots that serve requested content
             final boolean overlap =
diff --git a/src/com/android/documentsui/RootsFragment.java b/src/com/android/documentsui/RootsFragment.java
index 884cf31..ed5e123 100644
--- a/src/com/android/documentsui/RootsFragment.java
+++ b/src/com/android/documentsui/RootsFragment.java
@@ -16,8 +16,6 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT;
-
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
@@ -43,7 +41,7 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
 import com.google.common.collect.Lists;
@@ -101,7 +99,7 @@
 
         final Context context = getActivity();
         final RootsCache roots = DocumentsApplication.getRootsCache(context);
-        final State state = ((DocumentsActivity) context).getDisplayState();
+        final State state = ((BaseActivity) context).getDisplayState();
 
         mCallbacks = new LoaderCallbacks<Collection<RootInfo>>() {
             @Override
@@ -138,9 +136,9 @@
 
     public void onDisplayStateChanged() {
         final Context context = getActivity();
-        final State state = ((DocumentsActivity) context).getDisplayState();
+        final State state = ((BaseActivity) context).getDisplayState();
 
-        if (state.action == ACTION_GET_CONTENT) {
+        if (state.action == State.ACTION_GET_CONTENT) {
             mList.setOnItemLongClickListener(mItemLongClickListener);
         } else {
             mList.setOnItemLongClickListener(null);
@@ -153,7 +151,7 @@
     public void onCurrentRootChanged() {
         if (mAdapter == null) return;
 
-        final RootInfo root = ((DocumentsActivity) getActivity()).getCurrentRoot();
+        final RootInfo root = ((BaseActivity) getActivity()).getCurrentRoot();
         for (int i = 0; i < mAdapter.getCount(); i++) {
             final Object item = mAdapter.getItem(i);
             if (item instanceof RootItem) {
@@ -176,7 +174,7 @@
     private OnItemClickListener mItemListener = new OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            final DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
+            final BaseActivity activity = BaseActivity.get(RootsFragment.this);
             final Item item = mAdapter.getItem(position);
             if (item instanceof RootItem) {
                 activity.onRootPicked(((RootItem) item).root, true);
diff --git a/src/com/android/documentsui/RootsLoader.java b/src/com/android/documentsui/RootsLoader.java
index 8d37cdf..49651b4 100644
--- a/src/com/android/documentsui/RootsLoader.java
+++ b/src/com/android/documentsui/RootsLoader.java
@@ -19,7 +19,7 @@
 import android.content.AsyncTaskLoader;
 import android.content.Context;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
 
 import java.util.Collection;
diff --git a/src/com/android/documentsui/SaveFragment.java b/src/com/android/documentsui/SaveFragment.java
index ce98db2..a13fccc 100644
--- a/src/com/android/documentsui/SaveFragment.java
+++ b/src/com/android/documentsui/SaveFragment.java
@@ -113,7 +113,7 @@
     private View.OnClickListener mSaveListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
-            final DocumentsActivity activity = DocumentsActivity.get(SaveFragment.this);
+            final BaseActivity activity = BaseActivity.get(SaveFragment.this);
             if (mReplaceTarget != null) {
                 activity.onSaveRequested(mReplaceTarget);
             } else {
diff --git a/src/com/android/documentsui/SortingCursorWrapper.java b/src/com/android/documentsui/SortingCursorWrapper.java
index 6c8ca20..3ec3d1c 100644
--- a/src/com/android/documentsui/SortingCursorWrapper.java
+++ b/src/com/android/documentsui/SortingCursorWrapper.java
@@ -16,9 +16,9 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_DISPLAY_NAME;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_DISPLAY_NAME;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.BaseActivity.State.SORT_ORDER_SIZE;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 
diff --git a/src/com/android/documentsui/StandaloneActivity.java b/src/com/android/documentsui/StandaloneActivity.java
new file mode 100644
index 0000000..976f21d
--- /dev/null
+++ b/src/com/android/documentsui/StandaloneActivity.java
@@ -0,0 +1,937 @@
+/*
+ * 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 static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
+import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
+import static com.android.documentsui.DirectoryFragment.ANIM_SIDE;
+import static com.android.documentsui.DirectoryFragment.ANIM_UP;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.ComponentName;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Debug;
+import android.provider.DocumentsContract;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.DrawerLayout.DrawerListener;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuItem.OnActionExpandListener;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.SearchView;
+import android.widget.SearchView.OnQueryTextListener;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.Toolbar;
+
+import com.android.documentsui.FailureDialogFragment;
+import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.DurableUtils;
+import com.android.documentsui.model.RootInfo;
+
+import libcore.io.IoUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class StandaloneActivity extends BaseActivity {
+    public static final String TAG = "StandaloneFileManagement";
+
+    private static final String EXTRA_STATE = "state";
+
+    private static final int CODE_FORWARD = 42;
+
+    private SearchView mSearchView;
+
+    private Toolbar mToolbar;
+    private Spinner mToolbarStack;
+
+    private Toolbar mRootsToolbar;
+
+    private ActionBarDrawerToggle mDrawerToggle;
+
+    private DirectoryContainerView mDirectoryContainer;
+
+    private boolean mIgnoreNextNavigation;
+    private boolean mIgnoreNextClose;
+    private boolean mIgnoreNextCollapse;
+
+    private boolean mSearchExpanded;
+
+    private RootsCache mRoots;
+    private State mState;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        // Debug.waitForDebugger();
+        super.onCreate(icicle);
+
+        mRoots = DocumentsApplication.getRootsCache(this);
+
+        setResult(Activity.RESULT_CANCELED);
+        setContentView(R.layout.activity);
+
+        final Context context = this;
+        final Resources res = getResources();
+
+        // Strongly define our horizontal dimension; we leave vertical as
+        final WindowManager.LayoutParams a = getWindow().getAttributes();
+
+        final Point size = new Point();
+        getWindowManager().getDefaultDisplay().getSize(size);
+        // a.width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
+
+        getWindow().setAttributes(a);
+
+        mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
+
+        if (icicle != null) {
+            mState = icicle.getParcelable(EXTRA_STATE);
+        } else {
+            buildDefaultState();
+        }
+
+        mToolbar = (Toolbar) findViewById(R.id.toolbar);
+        mToolbar.setTitleTextAppearance(context,
+                android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
+
+        mToolbarStack = (Spinner) findViewById(R.id.stack);
+        mToolbarStack.setOnItemSelectedListener(mStackListener);
+
+        mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar);
+        if (mRootsToolbar != null) {
+            mRootsToolbar.setTitleTextAppearance(context,
+                    android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
+        }
+
+        setActionBar(mToolbar);
+
+        RootsFragment.show(getFragmentManager(), null);
+        if (!mState.restored) {
+            new RestoreStackTask().execute();
+            final Intent intent = getIntent();
+            final int failure = intent.getIntExtra(CopyService.EXTRA_FAILURE, 0);
+            if (failure != 0) {
+                final ArrayList<Uri> failedSrcList = intent.getParcelableArrayListExtra(
+                        CopyService.EXTRA_SRC_LIST);
+                FailureDialogFragment.show(getFragmentManager(), failure, failedSrcList);
+            }
+        } else {
+            onCurrentDirectoryChanged(ANIM_NONE);
+        }
+    }
+
+    private void buildDefaultState() {
+        mState = new State();
+
+        final Intent intent = getIntent();
+        mState.action = State.ACTION_BROWSE_ALL;
+        mState.acceptMimes = new String[] { "*/*" };
+        mState.allowMultiple = true;
+        mState.acceptMimes = new String[] { intent.getType() };
+        mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
+        mState.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
+        mState.showAdvanced = mState.forceAdvanced
+                | LocalPreferences.getDisplayAdvancedDevices(this);
+        mState.showSize = true;
+        final DocumentStack stack = intent.getParcelableExtra(CopyService.EXTRA_STACK);
+        if (stack != null)
+            mState.stack = stack;
+    }
+
+    private class RestoreStackTask extends AsyncTask<Void, Void, Void> {
+        private volatile boolean mRestoredStack;
+        private volatile boolean mExternal;
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            // Restore last stack for calling package
+            final String packageName = getCallingPackageMaybeExtra();
+            final Cursor cursor = getContentResolver()
+                    .query(RecentsProvider.buildResume(packageName), null, null, null, null);
+            try {
+                if (cursor.moveToFirst()) {
+                    mExternal = cursor.getInt(cursor.getColumnIndex(ResumeColumns.EXTERNAL)) != 0;
+                    final byte[] rawStack = cursor.getBlob(
+                            cursor.getColumnIndex(ResumeColumns.STACK));
+                    DurableUtils.readFromArray(rawStack, mState.stack);
+                    mRestoredStack = true;
+                }
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to resume: " + e);
+            } finally {
+                IoUtils.closeQuietly(cursor);
+            }
+
+            if (mRestoredStack) {
+                // Update the restored stack to ensure we have freshest data
+                final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
+                try {
+                    mState.stack.updateRoot(matchingRoots);
+                    mState.stack.updateDocuments(getContentResolver());
+                } catch (FileNotFoundException e) {
+                    Log.w(TAG, "Failed to restore stack: " + e);
+                    mState.stack.reset();
+                    mRestoredStack = false;
+                }
+            }
+
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            if (isDestroyed()) return;
+            mState.restored = true;
+            onCurrentDirectoryChanged(ANIM_NONE);
+        }
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        if (mDrawerToggle != null) {
+            mDrawerToggle.syncState();
+        }
+        updateActionBar();
+    }
+
+    @Override
+    public void setRootsDrawerOpen(boolean open) {
+        Log.w(TAG, "Trying to change state of roots drawer to > " + (open ? "open" : "closed"));
+      // throw new UnsupportedOperationException();
+    }
+
+    public void updateActionBar() {
+        final RootInfo root = getCurrentRoot();
+        mToolbar.setNavigationIcon(
+                root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
+        mToolbar.setNavigationContentDescription(R.string.drawer_open);
+        mToolbar.setNavigationOnClickListener(null);
+
+        if (mSearchExpanded) {
+            mToolbar.setTitle(null);
+            mToolbarStack.setVisibility(View.GONE);
+            mToolbarStack.setAdapter(null);
+        } else {
+            if (mState.stack.size() <= 1) {
+                mToolbar.setTitle(root.title);
+                mToolbarStack.setVisibility(View.GONE);
+                mToolbarStack.setAdapter(null);
+            } else {
+                mToolbar.setTitle(null);
+                mToolbarStack.setVisibility(View.VISIBLE);
+                mToolbarStack.setAdapter(mStackAdapter);
+
+                mIgnoreNextNavigation = true;
+                mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        getMenuInflater().inflate(R.menu.activity, menu);
+
+        for (int i = 0; i < menu.size(); i++) {
+            final MenuItem item = menu.getItem(i);
+            switch (item.getItemId()) {
+                case R.id.menu_advanced:
+                case R.id.menu_file_size:
+                    break;
+                default:
+                    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+            }
+        }
+
+        final MenuItem searchMenu = menu.findItem(R.id.menu_search);
+        mSearchView = (SearchView) searchMenu.getActionView();
+        mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
+            @Override
+            public boolean onQueryTextSubmit(String query) {
+                mSearchExpanded = true;
+                mState.currentSearch = query;
+                mSearchView.clearFocus();
+                onCurrentDirectoryChanged(ANIM_NONE);
+                return true;
+            }
+
+            @Override
+            public boolean onQueryTextChange(String newText) {
+                return false;
+            }
+        });
+
+        searchMenu.setOnActionExpandListener(new OnActionExpandListener() {
+            @Override
+            public boolean onMenuItemActionExpand(MenuItem item) {
+                mSearchExpanded = true;
+                updateActionBar();
+                return true;
+            }
+
+            @Override
+            public boolean onMenuItemActionCollapse(MenuItem item) {
+                mSearchExpanded = false;
+                if (mIgnoreNextCollapse) {
+                    mIgnoreNextCollapse = false;
+                    return true;
+                }
+
+                mState.currentSearch = null;
+                onCurrentDirectoryChanged(ANIM_NONE);
+                return true;
+            }
+        });
+
+        mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
+            @Override
+            public boolean onClose() {
+                mSearchExpanded = false;
+                if (mIgnoreNextClose) {
+                    mIgnoreNextClose = false;
+                    return false;
+                }
+
+                mState.currentSearch = null;
+                onCurrentDirectoryChanged(ANIM_NONE);
+                return false;
+            }
+        });
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+
+        final FragmentManager fm = getFragmentManager();
+
+        final RootInfo root = getCurrentRoot();
+        final DocumentInfo cwd = getCurrentDirectory();
+
+        final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
+        final MenuItem search = menu.findItem(R.id.menu_search);
+        final MenuItem sort = menu.findItem(R.id.menu_sort);
+        final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
+        final MenuItem grid = menu.findItem(R.id.menu_grid);
+        final MenuItem list = menu.findItem(R.id.menu_list);
+        final MenuItem advanced = menu.findItem(R.id.menu_advanced);
+        final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
+
+        sort.setVisible(cwd != null);
+        grid.setVisible(mState.derivedMode != State.MODE_GRID);
+        list.setVisible(mState.derivedMode != State.MODE_LIST);
+
+        if (mState.currentSearch != null) {
+            // Search uses backend ranking; no sorting
+            sort.setVisible(false);
+
+            search.expandActionView();
+
+            mSearchView.setIconified(false);
+            mSearchView.clearFocus();
+            mSearchView.setQuery(mState.currentSearch, false);
+        } else {
+            mIgnoreNextClose = true;
+            mSearchView.setIconified(true);
+            mSearchView.clearFocus();
+
+            mIgnoreNextCollapse = true;
+            search.collapseActionView();
+        }
+
+        // Only sort by size when visible
+        sortSize.setVisible(mState.showSize);
+
+        fileSize.setVisible(true);
+        search.setVisible(true);
+        createDir.setVisible(true);
+        advanced.setVisible(true);
+
+        advanced.setTitle(LocalPreferences.getDisplayAdvancedDevices(this)
+                ? R.string.menu_advanced_hide : R.string.menu_advanced_show);
+        fileSize.setTitle(LocalPreferences.getDisplayFileSize(this)
+                ? R.string.menu_file_size_hide : R.string.menu_file_size_show);
+
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
+            return true;
+        }
+
+        final int id = item.getItemId();
+        if (id == android.R.id.home) {
+            onBackPressed();
+            return true;
+        } else if (id == R.id.menu_create_dir) {
+            CreateDirectoryFragment.show(getFragmentManager());
+            return true;
+        } else if (id == R.id.menu_search) {
+            return false;
+        } else if (id == R.id.menu_sort_name) {
+            setUserSortOrder(State.SORT_ORDER_DISPLAY_NAME);
+            return true;
+        } else if (id == R.id.menu_sort_date) {
+            setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED);
+            return true;
+        } else if (id == R.id.menu_sort_size) {
+            setUserSortOrder(State.SORT_ORDER_SIZE);
+            return true;
+        } else if (id == R.id.menu_grid) {
+            setUserMode(State.MODE_GRID);
+            return true;
+        } else if (id == R.id.menu_list) {
+            setUserMode(State.MODE_LIST);
+            return true;
+        } else if (id == R.id.menu_advanced) {
+            setDisplayAdvancedDevices(!LocalPreferences.getDisplayAdvancedDevices(this));
+            return true;
+        } else if (id == R.id.menu_file_size) {
+            setDisplayFileSize(!LocalPreferences.getDisplayFileSize(this));
+            return true;
+        } else {
+            return super.onOptionsItemSelected(item);
+        }
+    }
+
+    private void setDisplayAdvancedDevices(boolean display) {
+        LocalPreferences.setDisplayAdvancedDevices(this, display);
+        mState.showAdvanced = mState.forceAdvanced | display;
+        RootsFragment.get(getFragmentManager()).onDisplayStateChanged();
+        invalidateOptionsMenu();
+    }
+
+    private void setDisplayFileSize(boolean display) {
+        LocalPreferences.setDisplayFileSize(this, display);
+        mState.showSize = display;
+        DirectoryFragment.get(getFragmentManager()).onDisplayStateChanged();
+        invalidateOptionsMenu();
+    }
+
+    @Override
+    public void onStateChanged() {
+        invalidateOptionsMenu();
+    }
+
+    /**
+     * Set state sort order based on explicit user action.
+     */
+    private void setUserSortOrder(int sortOrder) {
+        mState.userSortOrder = sortOrder;
+        DirectoryFragment.get(getFragmentManager()).onUserSortOrderChanged();
+    }
+
+    /**
+     * Set state mode based on explicit user action.
+     */
+    private void setUserMode(int mode) {
+        mState.userMode = mode;
+        DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
+    }
+
+    @Override
+    public void setPending(boolean pending) {
+        final SaveFragment save = SaveFragment.get(getFragmentManager());
+        if (save != null) {
+            save.setPending(pending);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (!mState.stackTouched) {
+            super.onBackPressed();
+            return;
+        }
+
+        final int size = mState.stack.size();
+        if (size > 1) {
+            mState.stack.pop();
+            onCurrentDirectoryChanged(ANIM_UP);
+        } else {
+            super.onBackPressed();
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle state) {
+        super.onSaveInstanceState(state);
+        state.putParcelable(EXTRA_STATE, mState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+    }
+
+    private BaseAdapter mStackAdapter = new BaseAdapter() {
+        @Override
+        public int getCount() {
+            return mState.stack.size();
+        }
+
+        @Override
+        public DocumentInfo getItem(int position) {
+            return mState.stack.get(mState.stack.size() - position - 1);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_subdir_title, parent, false);
+            }
+
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = getCurrentRoot();
+                title.setText(root.title);
+            } else {
+                title.setText(doc.displayName);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_subdir, parent, false);
+            }
+
+            final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = getCurrentRoot();
+                title.setText(root.title);
+                subdir.setVisibility(View.GONE);
+            } else {
+                title.setText(doc.displayName);
+                subdir.setVisibility(View.VISIBLE);
+            }
+
+            return convertView;
+        }
+    };
+
+    private OnItemSelectedListener mStackListener = new OnItemSelectedListener() {
+        @Override
+        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+            if (mIgnoreNextNavigation) {
+                mIgnoreNextNavigation = false;
+                return;
+            }
+
+            while (mState.stack.size() > position + 1) {
+                mState.stackTouched = true;
+                mState.stack.pop();
+            }
+            onCurrentDirectoryChanged(ANIM_UP);
+        }
+
+        @Override
+        public void onNothingSelected(AdapterView<?> parent) {
+            // Ignored
+        }
+    };
+
+    @Override
+    public RootInfo getCurrentRoot() {
+        if (mState.stack.root != null) {
+            return mState.stack.root;
+        } else {
+            return mRoots.getRecentsRoot();
+        }
+    }
+
+    public DocumentInfo getCurrentDirectory() {
+        return mState.stack.peek();
+    }
+
+    private String getCallingPackageMaybeExtra() {
+        final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME);
+        return (extra != null) ? extra : getCallingPackage();
+    }
+
+    public Executor getCurrentExecutor() {
+        final DocumentInfo cwd = getCurrentDirectory();
+        if (cwd != null && cwd.authority != null) {
+            return ProviderExecutor.forAuthority(cwd.authority);
+        } else {
+            return AsyncTask.THREAD_POOL_EXECUTOR;
+        }
+    }
+
+    @Override
+    public State getDisplayState() {
+        return mState;
+    }
+
+    private void onCurrentDirectoryChanged(int anim) {
+        final FragmentManager fm = getFragmentManager();
+        final RootInfo root = getCurrentRoot();
+        final DocumentInfo cwd = getCurrentDirectory();
+
+        mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
+
+        if (cwd == null) {
+            DirectoryFragment.showRecentsOpen(fm, anim);
+
+            // Start recents in grid when requesting visual things
+            final boolean visualMimes = MimePredicate.mimeMatches(
+                    MimePredicate.VISUAL_MIMES, mState.acceptMimes);
+            mState.userMode = visualMimes ? State.MODE_GRID : State.MODE_LIST;
+            mState.derivedMode = mState.userMode;
+        } else {
+            if (mState.currentSearch != null) {
+                // Ongoing search
+                DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
+            } else {
+                // Normal boring directory
+                DirectoryFragment.showNormal(fm, root, cwd, anim);
+            }
+        }
+
+        final RootsFragment roots = RootsFragment.get(fm);
+        if (roots != null) {
+            roots.onCurrentRootChanged();
+        }
+
+        updateActionBar();
+        invalidateOptionsMenu();
+        dumpStack();
+    }
+
+    @Override
+    public void onStackPicked(DocumentStack stack) {
+        try {
+            // Update the restored stack to ensure we have freshest data
+            stack.updateDocuments(getContentResolver());
+
+            mState.stack = stack;
+            mState.stackTouched = true;
+            onCurrentDirectoryChanged(ANIM_SIDE);
+
+        } catch (FileNotFoundException e) {
+            Log.w(TAG, "Failed to restore stack: " + e);
+        }
+    }
+
+    @Override
+    public void onRootPicked(RootInfo root, boolean closeDrawer) {
+        // Clear entire backstack and start in new root
+        mState.stack.root = root;
+        mState.stack.clear();
+        mState.stackTouched = true;
+
+        if (!mRoots.isRecentsRoot(root)) {
+            new PickRootTask(root).executeOnExecutor(getCurrentExecutor());
+        } else {
+            onCurrentDirectoryChanged(ANIM_SIDE);
+        }
+    }
+
+    private class PickRootTask extends AsyncTask<Void, Void, DocumentInfo> {
+        private RootInfo mRoot;
+
+        public PickRootTask(RootInfo root) {
+            mRoot = root;
+        }
+
+        @Override
+        protected DocumentInfo doInBackground(Void... params) {
+            try {
+                final Uri uri = DocumentsContract.buildDocumentUri(
+                        mRoot.authority, mRoot.documentId);
+                return DocumentInfo.fromUri(getContentResolver(), uri);
+            } catch (FileNotFoundException e) {
+                Log.w(TAG, "Failed to find root", e);
+                return null;
+            }
+        }
+
+        @Override
+        protected void onPostExecute(DocumentInfo result) {
+            if (result != null) {
+                mState.stack.push(result);
+                mState.stackTouched = true;
+                onCurrentDirectoryChanged(ANIM_SIDE);
+            }
+        }
+    }
+
+    @Override
+    public void onAppPicked(ResolveInfo info) {
+        final Intent intent = new Intent(getIntent());
+        intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+        intent.setComponent(new ComponentName(
+                info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
+        startActivityForResult(intent, CODE_FORWARD);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        Log.d(TAG, "onActivityResult() code=" + resultCode);
+
+        // Only relay back results when not canceled; otherwise stick around to
+        // let the user pick another app/backend.
+        if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
+
+            // Remember that we last picked via external app
+            final String packageName = getCallingPackageMaybeExtra();
+            final ContentValues values = new ContentValues();
+            values.put(ResumeColumns.EXTERNAL, 1);
+            getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
+
+            // Pass back result to original caller
+            setResult(resultCode, data);
+            finish();
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
+    }
+
+    @Override
+    public void onDocumentPicked(DocumentInfo doc) {
+        final FragmentManager fm = getFragmentManager();
+        if (doc.isDirectory()) {
+            mState.stack.push(doc);
+            mState.stackTouched = true;
+            onCurrentDirectoryChanged(ANIM_DOWN);
+        } else {
+            // Fall back to viewing
+            final Intent view = new Intent(Intent.ACTION_VIEW);
+            view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            view.setData(doc.derivedUri);
+
+            try {
+                startActivity(view);
+            } catch (ActivityNotFoundException ex2) {
+                Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
+    public void onDocumentsPicked(List<DocumentInfo> docs) {
+        // TODO
+    }
+
+    @Override
+    public void onSaveRequested(DocumentInfo replaceTarget) {
+        new ExistingFinishTask(replaceTarget.derivedUri).executeOnExecutor(getCurrentExecutor());
+    }
+
+    @Override
+    public void onSaveRequested(String mimeType, String displayName) {
+        new CreateFinishTask(mimeType, displayName).executeOnExecutor(getCurrentExecutor());
+    }
+
+    @Override
+    public void onPickRequested(DocumentInfo pickTarget) {
+        final Uri viaUri = DocumentsContract.buildTreeDocumentUri(pickTarget.authority,
+                pickTarget.documentId);
+        new PickFinishTask(viaUri).executeOnExecutor(getCurrentExecutor());
+    }
+
+    private void saveStackBlocking() {
+        final ContentResolver resolver = getContentResolver();
+        final ContentValues values = new ContentValues();
+
+        final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
+
+        // Remember location for next app launch
+        final String packageName = getCallingPackageMaybeExtra();
+        values.clear();
+        values.put(ResumeColumns.STACK, rawStack);
+        values.put(ResumeColumns.EXTERNAL, 0);
+        resolver.insert(RecentsProvider.buildResume(packageName), values);
+    }
+
+    private void onFinished(Uri... uris) {
+        Log.d(TAG, "onFinished() " + Arrays.toString(uris));
+
+        final Intent intent = new Intent();
+        if (uris.length == 1) {
+            intent.setData(uris[0]);
+        } else if (uris.length > 1) {
+            final ClipData clipData = new ClipData(
+                    null, mState.acceptMimes, new ClipData.Item(uris[0]));
+            for (int i = 1; i < uris.length; i++) {
+                clipData.addItem(new ClipData.Item(uris[i]));
+            }
+            intent.setClipData(clipData);
+        }
+
+        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+
+        setResult(Activity.RESULT_OK, intent);
+        finish();
+    }
+
+    private class CreateFinishTask extends AsyncTask<Void, Void, Uri> {
+        private final String mMimeType;
+        private final String mDisplayName;
+
+        public CreateFinishTask(String mimeType, String displayName) {
+            mMimeType = mimeType;
+            mDisplayName = displayName;
+        }
+
+        @Override
+        protected void onPreExecute() {
+            setPending(true);
+        }
+
+        @Override
+        protected Uri doInBackground(Void... params) {
+            final ContentResolver resolver = getContentResolver();
+            final DocumentInfo cwd = getCurrentDirectory();
+
+            ContentProviderClient client = null;
+            Uri childUri = null;
+            try {
+                client = DocumentsApplication.acquireUnstableProviderOrThrow(
+                        resolver, cwd.derivedUri.getAuthority());
+                childUri = DocumentsContract.createDocument(
+                        client, cwd.derivedUri, mMimeType, mDisplayName);
+            } catch (Exception e) {
+                Log.w(TAG, "Failed to create document", e);
+            } finally {
+                ContentProviderClient.releaseQuietly(client);
+            }
+
+            if (childUri != null) {
+                saveStackBlocking();
+            }
+
+            return childUri;
+        }
+
+        @Override
+        protected void onPostExecute(Uri result) {
+            if (result != null) {
+                onFinished(result);
+            } else {
+                Toast.makeText(StandaloneActivity.this, R.string.save_error, Toast.LENGTH_SHORT)
+                        .show();
+            }
+
+            setPending(false);
+        }
+    }
+
+    private class ExistingFinishTask extends AsyncTask<Void, Void, Void> {
+        private final Uri[] mUris;
+
+        public ExistingFinishTask(Uri... uris) {
+            mUris = uris;
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            saveStackBlocking();
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            onFinished(mUris);
+        }
+    }
+
+    private class PickFinishTask extends AsyncTask<Void, Void, Void> {
+        private final Uri mUri;
+
+        public PickFinishTask(Uri uri) {
+            mUri = uri;
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            saveStackBlocking();
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            onFinished(mUri);
+        }
+    }
+
+    private void dumpStack() {
+        Log.d(TAG, "Current stack: ");
+        Log.d(TAG, " * " + mState.stack.root);
+        for (DocumentInfo doc : mState.stack) {
+            Log.d(TAG, " +-- " + doc);
+        }
+    }
+
+    public static BaseActivity get(Fragment fragment) {
+        return (BaseActivity) fragment.getActivity();
+    }
+}
diff --git a/src/com/android/documentsui/model/DocumentInfo.java b/src/com/android/documentsui/model/DocumentInfo.java
index 1c5ca86..5d5f2eb 100644
--- a/src/com/android/documentsui/model/DocumentInfo.java
+++ b/src/com/android/documentsui/model/DocumentInfo.java
@@ -24,6 +24,7 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsProvider;
 import android.text.TextUtils;
 
@@ -161,8 +162,6 @@
         this.authority = authority;
         this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
         this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
-        this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
-        this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
         this.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
         this.lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
         this.flags = getCursorInt(cursor, Document.COLUMN_FLAGS);
diff --git a/src/com/android/documentsui/model/DocumentStack.java b/src/com/android/documentsui/model/DocumentStack.java
index 28bab6c..34bd696 100644
--- a/src/com/android/documentsui/model/DocumentStack.java
+++ b/src/com/android/documentsui/model/DocumentStack.java
@@ -17,6 +17,8 @@
 package com.android.documentsui.model;
 
 import android.content.ContentResolver;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.provider.DocumentsProvider;
 
 import java.io.DataInputStream;
@@ -31,7 +33,7 @@
  * Representation of a stack of {@link DocumentInfo}, usually the result of a
  * user-driven traversal.
  */
-public class DocumentStack extends LinkedList<DocumentInfo> implements Durable {
+public class DocumentStack extends LinkedList<DocumentInfo> implements Durable, Parcelable {
     private static final int VERSION_INIT = 1;
     private static final int VERSION_ADD_ROOT = 2;
 
@@ -135,4 +137,28 @@
             doc.write(out);
         }
     }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        DurableUtils.writeToParcel(dest, this);
+    }
+
+    public static final Creator<DocumentStack> CREATOR = new Creator<DocumentStack>() {
+        @Override
+        public DocumentStack createFromParcel(Parcel in) {
+            final DocumentStack stack = new DocumentStack();
+            DurableUtils.readFromParcel(in, stack);
+            return stack;
+        }
+
+        @Override
+        public DocumentStack[] newArray(int size) {
+            return new DocumentStack[size];
+        }
+    };
 }
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 81a2889..a312427 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -4,6 +4,17 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+        <provider
+            android:name="com.android.documentsui.StubProvider"
+            android:authorities="com.android.documentsui.stubprovider"
+            android:exported="true"
+            android:grantUriPermissions="true"
+            android:permission="android.permission.MANAGE_DOCUMENTS"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
+            </intent-filter>
+       </provider>
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/tests/src/com/android/documentsui/RootsCacheTest.java b/tests/src/com/android/documentsui/RootsCacheTest.java
index cdb6b33..7faa3ce 100644
--- a/tests/src/com/android/documentsui/RootsCacheTest.java
+++ b/tests/src/com/android/documentsui/RootsCacheTest.java
@@ -19,7 +19,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
 import com.google.android.collect.Lists;
 
diff --git a/tests/src/com/android/documentsui/StubProvider.java b/tests/src/com/android/documentsui/StubProvider.java
new file mode 100644
index 0000000..75effa7
--- /dev/null
+++ b/tests/src/com/android/documentsui/StubProvider.java
@@ -0,0 +1,316 @@
+/*
+ * 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.content.Context;
+import android.content.pm.ProviderInfo;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.MatrixCursor.RowBuilder;
+import android.database.MatrixCursor;
+import android.graphics.Point;
+import android.os.CancellationSignal;
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsProvider;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+
+public class StubProvider extends DocumentsProvider {
+    private static int STORAGE_SIZE = 1024 * 1024;  // 1 MB.
+    private static final String TAG = "StubProvider";
+    private static final String MY_ROOT_ID = "myRoot";
+
+    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
+            Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID,
+            Root.COLUMN_AVAILABLE_BYTES
+    };
+    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
+            Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME,
+            Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
+    };
+
+    private String mRootDocumentId;
+    private HashMap<String, StubDocument> mStorage = new HashMap<String, StubDocument>();
+    private int mStorageUsedBytes;
+    private Object mWriteLock = new Object();
+    private String mAuthority;
+
+    @Override
+    public void attachInfo(Context context, ProviderInfo info) {
+        mAuthority = info.authority;
+        super.attachInfo(context, info);
+    }
+
+    @Override
+    public boolean onCreate() {
+        final File cacheDir = getContext().getCacheDir();
+        removeRecursively(cacheDir);
+        final StubDocument document = new StubDocument(cacheDir, Document.MIME_TYPE_DIR, null);
+        mRootDocumentId = document.documentId;
+        mStorage.put(mRootDocumentId, document);
+        return true;
+    }
+
+    @Override
+    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+        final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION);
+        final RowBuilder row = result.newRow();
+        row.add(Root.COLUMN_ROOT_ID, MY_ROOT_ID);
+        row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD);
+        row.add(Root.COLUMN_TITLE, "Foobar SD 4GB");
+        row.add(Root.COLUMN_DOCUMENT_ID, mRootDocumentId);
+        row.add(Root.COLUMN_AVAILABLE_BYTES, STORAGE_SIZE - mStorageUsedBytes);
+        return result;
+    }
+
+    @Override
+    public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException {
+        final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
+        final StubDocument file = mStorage.get(documentId);
+        if (file == null) {
+            throw new FileNotFoundException();
+        }
+        includeDocument(result, file);
+        return result;
+    }
+
+    @Override
+    public boolean isChildDocument(String parentDocId, String docId) {
+        final StubDocument parentDocument = mStorage.get(parentDocId);
+        final StubDocument childDocument = mStorage.get(docId);
+        return FileUtils.contains(parentDocument.file, childDocument.file);
+    }
+
+    @Override
+    public String createDocument(String parentDocumentId, String mimeType, String displayName)
+            throws FileNotFoundException {
+        final StubDocument parentDocument = mStorage.get(parentDocumentId);
+        if (parentDocument == null || !parentDocument.file.isDirectory()) {
+            throw new FileNotFoundException();
+        }
+        final File file = new File(parentDocument.file, displayName);
+        if (mimeType.equals(Document.MIME_TYPE_DIR)) {
+            if (!file.mkdirs()) {
+                throw new FileNotFoundException();
+            }
+        } else {
+            try {
+                if (!file.createNewFile()) {
+                    throw new FileNotFoundException();
+                }
+            }
+            catch (IOException e) {
+                throw new FileNotFoundException();
+            }
+        }
+
+        final StubDocument document = new StubDocument(file, mimeType, parentDocument);
+        mStorage.put(document.documentId, document);
+        notifyParentChanged(document.parentId);
+        return document.documentId;
+    }
+
+    @Override
+    public void deleteDocument(String documentId)
+            throws FileNotFoundException {
+        final StubDocument document = mStorage.get(documentId);
+        final long fileSize = document.file.length();
+        if (document == null || !document.file.delete())
+            throw new FileNotFoundException();
+        synchronized (mWriteLock) {
+            mStorageUsedBytes -= fileSize;
+        }
+        notifyParentChanged(document.parentId);
+    }
+
+    @Override
+    public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException {
+        final StubDocument parentDocument = mStorage.get(parentDocumentId);
+        if (parentDocument == null || parentDocument.file.isFile()) {
+            throw new FileNotFoundException();
+        }
+        final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
+        result.setNotificationUri(getContext().getContentResolver(),
+                DocumentsContract.buildChildDocumentsUri(mAuthority, parentDocumentId));
+        StubDocument document;
+        for (File file : parentDocument.file.listFiles()) {
+            document = mStorage.get(StubDocument.getDocumentIdForFile(file));
+            if (document != null) {
+                includeDocument(result, document);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Cursor queryRecentDocuments(String rootId, String[] projection)
+            throws FileNotFoundException {
+        throw new FileNotFoundException();
+    }
+
+    @Override
+    public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        final StubDocument document = mStorage.get(docId);
+        if (document == null || !document.file.isFile())
+            throw new FileNotFoundException();
+
+        if ("r".equals(mode)) {
+            return ParcelFileDescriptor.open(document.file, ParcelFileDescriptor.MODE_READ_ONLY);
+        }
+        if ("w".equals(mode)) {
+            return startWrite(document);
+        }
+
+        throw new FileNotFoundException();
+    }
+
+    @Override
+    public AssetFileDescriptor openDocumentThumbnail(
+            String docId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException {
+        throw new FileNotFoundException();
+    }
+
+    private ParcelFileDescriptor startWrite(final StubDocument document)
+            throws FileNotFoundException {
+        ParcelFileDescriptor[] pipe;
+        try {
+            pipe = ParcelFileDescriptor.createReliablePipe();
+        }
+        catch (IOException exception) {
+            throw new FileNotFoundException();
+        }
+        final ParcelFileDescriptor readPipe = pipe[0];
+        final ParcelFileDescriptor writePipe = pipe[1];
+
+        new Thread() {
+            @Override
+            public void run() {
+                try {
+                    final FileInputStream inputStream = new FileInputStream(readPipe.getFileDescriptor());
+                    final FileOutputStream outputStream = new FileOutputStream(document.file);
+                    byte[] buffer = new byte[32 * 1024];
+                    int bytesToRead;
+                    int bytesRead = 0;
+                    while (bytesRead != -1) {
+                        synchronized (mWriteLock) {
+                            bytesToRead = Math.min(STORAGE_SIZE - mStorageUsedBytes, buffer.length);
+                            if (bytesToRead == 0) {
+                                closePipeWithErrorSilently(readPipe, "Not enough space.");
+                                break;
+                            }
+                            bytesRead = inputStream.read(buffer, 0, bytesToRead);
+                            if (bytesRead == -1) {
+                                break;
+                            }
+                            outputStream.write(buffer, 0, bytesRead);
+                            mStorageUsedBytes += bytesRead;
+                        }
+                    }
+                }
+                catch (IOException e) {
+                    closePipeWithErrorSilently(readPipe, e.getMessage());
+                }
+                finally {
+                    closePipeSilently(readPipe);
+                    notifyParentChanged(document.parentId);
+                }
+            }
+        }.start();
+
+        return writePipe;
+    }
+
+    private void closePipeWithErrorSilently(ParcelFileDescriptor pipe, String error) {
+        try {
+            pipe.closeWithError(error);
+        }
+        catch (IOException ignore) {
+        }
+    }
+
+    private void closePipeSilently(ParcelFileDescriptor pipe) {
+        try {
+            pipe.close();
+        }
+        catch (IOException ignore) {
+        }
+    }
+
+    private void notifyParentChanged(String parentId) {
+        getContext().getContentResolver().notifyChange(
+                DocumentsContract.buildChildDocumentsUri(mAuthority, parentId), null, false);
+        // Notify also about possible change in remaining space on the root.
+        getContext().getContentResolver().notifyChange(DocumentsContract.buildRootsUri(mAuthority), null, false);
+    }
+
+    private void includeDocument(MatrixCursor result, StubDocument document) {
+        final RowBuilder row = result.newRow();
+        row.add(Document.COLUMN_DOCUMENT_ID, document.documentId);
+        row.add(Document.COLUMN_DISPLAY_NAME, document.file.getName());
+        row.add(Document.COLUMN_SIZE, document.file.length());
+        row.add(Document.COLUMN_MIME_TYPE, document.mimeType);
+        int flags = Document.FLAG_SUPPORTS_DELETE;
+        // TODO: Add support for renaming.
+        if (document.file.isDirectory()) {
+            flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
+        } else {
+            flags |= Document.FLAG_SUPPORTS_WRITE;
+        }
+        row.add(Document.COLUMN_FLAGS, flags);
+        row.add(Document.COLUMN_LAST_MODIFIED, document.file.lastModified());
+    }
+
+    private void removeRecursively(File file) {
+        for (File childFile : file.listFiles()) {
+            if (childFile.isDirectory()) {
+                removeRecursively(childFile);
+            }
+            childFile.delete();
+        }
+    }
+}
+
+class StubDocument {
+    public final File file;
+    public final String mimeType;
+    public final String documentId;
+    public final String parentId;
+
+    StubDocument(File file, String mimeType, StubDocument parent) {
+        this.file = file;
+        this.mimeType = mimeType;
+        this.documentId = getDocumentIdForFile(file);
+        this.parentId = parent != null ? parent.documentId : null;
+    }
+
+    public static String getDocumentIdForFile(File file) {
+        return file.getAbsolutePath();
+    }
+}