diff --git a/Android.mk b/Android.mk
index 0a07ab3..aa7cbc7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -22,7 +22,6 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += $(call all-java-files-under, exchange1_src)
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-common com.android.emailcommon
 LOCAL_STATIC_JAVA_LIBRARIES += calendar-common
@@ -36,25 +35,9 @@
 include $(BUILD_PACKAGE)
 
 include $(CLEAR_VARS)
-#
-# Exchange2
-#
-LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += $(call all-java-files-under, exchange2_src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-common com.android.emailcommon2
-LOCAL_STATIC_JAVA_LIBRARIES += calendar-common
+##################################################
+# Build all sub-directories
 
-LOCAL_PACKAGE_NAME := Exchange2
-LOCAL_OVERRIDES_PACKAGES := Exchange
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-LOCAL_EMMA_COVERAGE_FILTER += +com.android.exchange.*
-
-include $(BUILD_PACKAGE)
-
-# additionally, build unit tests in a separate .apk
- include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/exchange2/Android.mk b/exchange2/Android.mk
new file mode 100644
index 0000000..24aba9a
--- /dev/null
+++ b/exchange2/Android.mk
@@ -0,0 +1,38 @@
+# Copyright 2008, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+#
+# Exchange2
+#
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-common com.android.emailcommon2
+LOCAL_STATIC_JAVA_LIBRARIES += calendar-common
+
+LOCAL_PACKAGE_NAME := Exchange2
+LOCAL_OVERRIDES_PACKAGES := Exchange
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+LOCAL_EMMA_COVERAGE_FILTER += +com.android.exchange.*
+
+include $(BUILD_PACKAGE)
+
+# additionally, build unit tests in a separate .apk
+ include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/exchange2/AndroidManifest.xml b/exchange2/AndroidManifest.xml
new file mode 100644
index 0000000..7537b73
--- /dev/null
+++ b/exchange2/AndroidManifest.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.exchange"
+    android:versionCode="500000"
+    android:versionName="5.0"
+     >
+
+    <uses-permission
+        android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
+    <uses-permission
+        android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission
+        android:name="android.permission.INTERNET"/>
+    <uses-permission
+        android:name="android.permission.VIBRATE"/>
+    <uses-permission
+        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission
+        android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission
+        android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission
+        android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission
+        android:name="android.permission.READ_SYNC_SETTINGS" />
+    <uses-permission
+        android:name="android.permission.WRITE_SYNC_SETTINGS" />
+
+    <uses-permission
+        android:name="android.permission.READ_CONTACTS"/>
+    <uses-permission
+        android:name="android.permission.WRITE_CONTACTS"/>
+    <uses-permission
+        android:name="android.permission.READ_CALENDAR"/>
+    <uses-permission
+        android:name="android.permission.WRITE_CALENDAR"/>
+    <uses-permission
+        android:name="android.permission.USE_CREDENTIALS"/>
+
+    <!-- Only required if a store implements push mail and needs to keep network open -->
+    <uses-permission
+        android:name="android.permission.WAKE_LOCK"/>
+    <uses-permission
+        android:name="android.permission.READ_PHONE_STATE"/>
+
+    <uses-permission
+        android:name="com.android.email.permission.READ_ATTACHMENT"/>
+    <uses-permission
+        android:name="com.android.email.permission.ACCESS_PROVIDER"/>
+
+    <application
+        android:icon="@mipmap/icon"
+        android:label="@string/app_name"
+        android:name="Exchange"
+        android:theme="@android:style/Theme.Holo.Light"
+        >
+
+        <receiver
+            android:name="com.android.exchange.EmailSyncAlarmReceiver"/>
+        <receiver
+            android:name="com.android.exchange.MailboxAlarmReceiver"/>
+
+        <receiver
+            android:name=".service.ExchangeBroadcastReceiver"
+            android:enabled="true">
+            <intent-filter>
+                <action
+                    android:name="android.intent.action.BOOT_COMPLETED" />
+                <action
+                    android:name="android.intent.action.DEVICE_STORAGE_LOW" />
+                <action
+                    android:name="android.intent.action.DEVICE_STORAGE_OK" />
+                <action
+                    android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
+            </intent-filter>
+        </receiver>
+
+        <service
+            android:name=".service.ExchangeBroadcastProcessorService" />
+
+        <!--Required stanza to register the EAS EmailSyncAdapterService with SyncManager -->
+        <service
+            android:name="com.android.exchange.EmailSyncAdapterService"
+            android:exported="true">
+            <intent-filter>
+                <action
+                    android:name="android.content.SyncAdapter" />
+            </intent-filter>
+            <meta-data android:name="android.content.SyncAdapter"
+                       android:resource="@xml/syncadapter_email" />
+        </service>
+
+        <!--Required stanza to register the EAS ContactsSyncAdapterService with SyncManager -->
+        <service
+            android:name="com.android.exchange.ContactsSyncAdapterService"
+            android:exported="true">
+            <intent-filter>
+                <action
+                    android:name="android.content.SyncAdapter" />
+            </intent-filter>
+            <meta-data android:name="android.content.SyncAdapter"
+                       android:resource="@xml/syncadapter_contacts" />
+        </service>
+
+        <!--Required stanza to register the EAS CalendarSyncAdapterService with SyncManager -->
+        <service
+            android:name="com.android.exchange.CalendarSyncAdapterService"
+            android:exported="true">
+            <intent-filter>
+                <action
+                    android:name="android.content.SyncAdapter" />
+            </intent-filter>
+            <meta-data android:name="android.content.SyncAdapter"
+                       android:resource="@xml/syncadapter_calendar" />
+        </service>
+
+        <!-- Add android:process=":remote" below to enable ExchangeService as a separate process -->
+        <service
+            android:name="com.android.exchange.ExchangeService"
+            android:enabled="true"
+            android:permission="com.android.email.permission.ACCESS_PROVIDER"
+            >
+            <intent-filter>
+                <action
+                    android:name="com.android.email.EXCHANGE_INTENT" />
+            </intent-filter>
+        </service>
+
+        <provider
+            android:name="com.android.exchange.provider.ExchangeDirectoryProvider"
+            android:authorities="com.android.exchange.directory.provider"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:multiprocess="false"
+            >
+          <meta-data
+              android:name="android.content.ContactDirectory"
+              android:value="true"/>
+        </provider>
+
+        <activity android:name=".EasCertificateRequestor">
+            <intent-filter>
+                <action android:name="com.android.emailcommon.REQUEST_CERT" />
+                <data android:scheme="eas" android:path="/certrequest" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SettingsRedirector">
+            <intent-filter>
+                <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/exchange2/proguard.flags b/exchange2/proguard.flags
new file mode 100644
index 0000000..0b7da4b
--- /dev/null
+++ b/exchange2/proguard.flags
@@ -0,0 +1,23 @@
+# keep names that are used by reflection.
+
+# Keep names that are used only by unit tests
+-keep class ** {
+  *** *ForTest(...);
+}
+
+-keepclasseswithmembers class com.android.exchange.adapter.Parser {
+  *** resetInput(java.io.InputStream);
+}
+
+-keepclasseswithmembers class com.android.exchange.provider.GalResult {
+  *** addGalData(com.android.exchange.provider.GalResult$GalData);
+  *** addGalData(long, java.lang.String, java.lang.String);
+}
+
+-keepclasseswithmembers class com.android.exchange.CalendarSyncEnabler {
+  public <init>(android.content.Context);
+}
+
+-keepclasseswithmembers class com.android.exchange.provider.MailboxUtilities {
+  *** setFlagsAndChildrensParentKey(android.content.Context, java.lang.String, java.lang.String);
+}
diff --git a/exchange2/res/drawable-hdpi/stat_notify_calendar.png b/exchange2/res/drawable-hdpi/stat_notify_calendar.png
new file mode 100644
index 0000000..5c8329d
--- /dev/null
+++ b/exchange2/res/drawable-hdpi/stat_notify_calendar.png
Binary files differ
diff --git a/exchange2/res/drawable-mdpi/stat_notify_calendar.png b/exchange2/res/drawable-mdpi/stat_notify_calendar.png
new file mode 100644
index 0000000..5758d04
--- /dev/null
+++ b/exchange2/res/drawable-mdpi/stat_notify_calendar.png
Binary files differ
diff --git a/exchange2/res/drawable-xhdpi/stat_notify_calendar.png b/exchange2/res/drawable-xhdpi/stat_notify_calendar.png
new file mode 100644
index 0000000..34fc22b
--- /dev/null
+++ b/exchange2/res/drawable-xhdpi/stat_notify_calendar.png
Binary files differ
diff --git a/exchange2/res/mipmap-hdpi/icon.png b/exchange2/res/mipmap-hdpi/icon.png
new file mode 100644
index 0000000..6fd0a98
--- /dev/null
+++ b/exchange2/res/mipmap-hdpi/icon.png
Binary files differ
diff --git a/exchange2/res/mipmap-mdpi/icon.png b/exchange2/res/mipmap-mdpi/icon.png
new file mode 100644
index 0000000..0369413
--- /dev/null
+++ b/exchange2/res/mipmap-mdpi/icon.png
Binary files differ
diff --git a/exchange2/res/mipmap-xhdpi/icon.png b/exchange2/res/mipmap-xhdpi/icon.png
new file mode 100644
index 0000000..777ef30
--- /dev/null
+++ b/exchange2/res/mipmap-xhdpi/icon.png
Binary files differ
diff --git a/exchange2/res/values-af/strings.xml b/exchange2/res/values-af/strings.xml
new file mode 100644
index 0000000..f2c0748
--- /dev/null
+++ b/exchange2/res/values-af/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Aanvaar: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Afgewys: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Voorlopig: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Gekanselleer: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Opgedateer: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Wanneer: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Waar: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Wanneer: <xliff:g id="EVENTDATE">%s</xliff:g> (herhalend)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Wanneer: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dag)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Wanneer: <xliff:g id="EVENTDATE">%s</xliff:g> (die hele dag, herhalend)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-kalender bygevoeg"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange-dienste"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Hierdie gebeurtenis is gekanselleer vir: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Die details van hierdie gebeurtenis het verander vir: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Moenie geheuekaarte toelaat nie"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Moenie ongetekende programme toelaat nie"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Moenie ongetekende programinstalleerders toelaat nie"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Moenie Wi-Fi toelaat nie"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Moenie teksboodskappe toelaat nie"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Moenie POP3- of IMAP-rekeninge toelaat nie"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Moenie infrarooi kommunikasie toelaat nie"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Moenie HTML-e-pos toelaat nie"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Moenie blaaiers toelaat nie"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Moenie verbruiker-e-pos toelaat nie"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Moenie internetdeling toelaat nie"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Vereis SMIME-boodskappe"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Beperk Bluetooth-gebruik"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Weier gespesifiseerde programme"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Laat net gespesifiseerde programme toe"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Beperk grootte van teks-e-pos"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Beperk grootte van HTML-e-pos"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Vereis SD-kaart-enkripsie"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Moenie aanhegsels toelaat nie"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Beperk aanhegselgrootte"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Laat net handmatige sinkronisasie toe tydens swerwing"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Vereis toestelenkripsie"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Outomaties"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Een dag"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Drie dae"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Een week"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Twee weke"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Een maand"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Alle"</string>
+</resources>
diff --git a/exchange2/res/values-am/strings.xml b/exchange2/res/values-am/strings.xml
new file mode 100644
index 0000000..f9712e3
--- /dev/null
+++ b/exchange2/res/values-am/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"የማይክሮሶፍት Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"ተቀብሏል፡ <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"ሳይቀበል ቀረ: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"ጊዜያዊ፡<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"ቀርቷል: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"የዘመነ፡<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"መቼ:<xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"የት: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"መቼ፡ <xliff:g id="EVENTDATE">%s</xliff:g>(ድግግሞሽ)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"የሚከተለው ሲሆን፤ <xliff:g id="EVENTDATE">%s</xliff:g> (ሁሉም ቀን)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"የሚከተለው ሲሆን፤ <xliff:g id="EVENTDATE">%s</xliff:g> (ሁሉም ቀን፣ ተደጋጋሚ)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"የቀን መቁጠሪያ ልውውጥ ታክሏል"</string>
+    <string name="app_name" msgid="5316597712787122829">"አገልግሎቶች ለዋውጥ"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"ይህ ከስተት ለ<xliff:g id="DATE">%s</xliff:g> ተሰርዟል።"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"የዚህ ክስተት ዝርዝሮች ለ፡<xliff:g id="DATE">%s</xliff:g> ተለውጠዋል"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"የማከማቻ ካርዶችን አትፍቀድ"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"ያልተረጋገጡ የትግበራ  አትፍቀድ"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"ያልተረጋገጡ የትግበራ ጫኞችን አትፍቀድ"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wi-Fi አትፍቀድ"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"የፅሁፍ መልዕክት አትፍቀድ"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3 ወይም IMAP መለያዎች አትፍቀድ"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"የታህተቀይ ግኑኙነት አትፍቀድ"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"የHTML ኢሜይል አትፍቀድ"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"አሳሾች አትፍቀድ"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"የሸማች ኢሜይል አትፍቀድ"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"የበይነ መረብ ማጋራት አትፍቀድ"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"የSMIME መልዕክቶች ጠይቅ"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"የብሉቱዝ አገልግሎትን ገድብ"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"የተወሰኑ ትግበራዎችን አትፍቀድ"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"የተወሰኑ ትግበራዎችን ብቻ ፍቀድ"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"የፅሁፍ ኢሜይል መጠንን ገድብ"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"የHTML ኢሜይል መጠን ገድብ"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"የsd ካርድ ምስጠራ ጠይቅ"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"አባሪዎች አትፍቀድ"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"የአባሪ መጠንን ገድብ"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"በእንቅስቃሴ ላይ በእጅ አመሳስል ብቻ ፍቀድ"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"የመሳሪያ ምስጠራ ጠይቅ"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"ራስ ሰር"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"አንድ ቀን"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"ሦስት ቀን"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"አንድ ሳምንት"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"ሁለት ሳምንቶች"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"አንድ ወር"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"ሁሉም"</string>
+</resources>
diff --git a/exchange2/res/values-ar/strings.xml b/exchange2/res/values-ar/strings.xml
new file mode 100644
index 0000000..395fa1f
--- /dev/null
+++ b/exchange2/res/values-ar/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"مقبول: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"مرفوض: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"موافقة مبدئية: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"تم الإلغاء: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"تم التحديث: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"متى: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"المكان: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"الموعد: <xliff:g id="EVENTDATE">%s</xliff:g> (متكرر)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"الموعد: <xliff:g id="EVENTDATE">%s</xliff:g> (اليوم كله)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"الموعد: <xliff:g id="EVENTDATE">%s</xliff:g> (اليوم كله، بشكل متكرر)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"تمت إضافة تقويم Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"خدمات Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"تم إلغاء هذا الحدث لـ: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"تم تغيير التفاصيل لهذا الحدث لـ: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"عدم السماح ببطاقات التخزين"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"عدم السماح بالتطبيقات غير الموقعة"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"عدم السماح بمثبتات التطبيقات غير الموقعة"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"عدم السماح باتصالات Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"عدم السماح بالرسائل النصية"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"عدم السماح بحسابات POP3 أو IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"عدم السماح باتصالات الأشعة تحت الحمراء"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"عدم السماح برسائل HTML الإلكترونية"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"عدم السماح للمتصفحات"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"عدم السماح برسائل المستهلكين الإلكترونية"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"عدم السماح بالمشاركة عبر الإنترنت"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"يلزم توفر الرسائل بتنسيق SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"تقييد استخدام البلوتوث"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"عدم السماح بتطبيقات محددة"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"السماح بتطبيقات محددة فقط"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"تقييد حجم الرسالة الإلكترونية النصية"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"تقييد حجم رسائل HTML الإلكترونية"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"يلزم تشفير بطاقة SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"عدم السماح بالمرفقات"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"تقييد حجم المرفق"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"السماح بالمزامنة اليدوية فقط أثناء التجوال"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"يلزم تشفير الجهاز"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"تلقائي"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"يوم واحد"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"ثلاثة أيام"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"أسبوع"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"أسبوعان"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"شهر واحد"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"الكل"</string>
+</resources>
diff --git a/exchange2/res/values-be/strings.xml b/exchange2/res/values-be/strings.xml
new file mode 100644
index 0000000..72a5396
--- /dev/null
+++ b/exchange2/res/values-be/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Прынята: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Адхілена: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Папярэдне: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Адменена: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Абноўлена: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Калі: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Дзе: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Калі: <xliff:g id="EVENTDATE">%s</xliff:g> (перыядычна)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Калі: <xliff:g id="EVENTDATE">%s</xliff:g> (на цэлы дзень)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Калі: <xliff:g id="EVENTDATE">%s</xliff:g> (на цэлы дзень, перыядычная)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Каляндар Exchange дададзены"</string>
+    <string name="app_name" msgid="5316597712787122829">"Службы Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Гэтае мерапрыемства было адмененае: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Параметры гэтай падзеі былі былі змененыя: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Забараніць карты памяці"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Забараніць непадпісаныя прыкладанні"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Забараніць усталяванне непадпісаных прыкладанняў"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Забараніць выкарыстанне Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Забараніць абмен тэкстав. паведамленнямі"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Забаранiць улiковыя запiсы з выкарыстаннем POP3 і IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Забараніць ІЧ-сувязь"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Забаранiць фармат HTML для электр. пошты"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Забаранiць для браўзэраў"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Забаранiць электр. пошту карыстальнiкаў"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Забараніць агульны доступ у Інтэрнэт"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Патрабаваць паведамленні SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Абмежаваць выкарыстанне Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Забараніць пэўныя прыкладанні"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Дазваляць толькі пэўныя прыкладанні"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Абмежаваць памер тэкста электр. лістоў"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Абмежаваць памер электронных лістоў HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Патрабаваць шыфраванне SD-карты"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Забараніць далучэннi"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Абмежаваць памер далучэнняў"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Дазваляць ручную сiнхранiзацыю ў роўмiнгу"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Патрабаваць шыфраванне прылады"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Аўтаматычна"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"1 дзень"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Тры дні"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"1 тыдзень"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Два тыдні"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Адзін месяц"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Усе"</string>
+</resources>
diff --git a/exchange2/res/values-bg/strings.xml b/exchange2/res/values-bg/strings.xml
new file mode 100644
index 0000000..d8d218d
--- /dev/null
+++ b/exchange2/res/values-bg/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Прието: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Отклонено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Колебливо: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Анулирано: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Актуализация:<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Кога: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Къде: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Кога: <xliff:g id="EVENTDATE">%s</xliff:g> (с повторения)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Кога: <xliff:g id="EVENTDATE">%s</xliff:g> (цял ден)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Кога: <xliff:g id="EVENTDATE">%s</xliff:g> (цял ден, периодично)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Добавен е календар от Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Услуги на Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Това събитие от <xliff:g id="DATE">%s</xliff:g> е анулирано"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Подробностите за това събитие са променени за: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Забраняване на карти за съхранение"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Без неподписани приложения"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Без неподп. инсталатори на приложения"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Без разрешаване на WiFi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Забраняване на текстови съобщения"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Забраняване на POP3 или IMAP профили"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Забраняване на инфрачервени комуникации"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Забраняване на HTML имейли"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Забраняване на браузъри"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Забраняване на маркетингови имейли"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Без споделяне на интернет"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Изискване на SMIME съобщения"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Ограничаване на ползването на Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Забраняване на посочените приложения"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Разрешаване само на посочени приложения"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Ограничаване на размера на текст. имейли"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Ограничаване на размера на HTML имейлите"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Изискване за шифроване на SD картата"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Забраняване на прикачени файлове"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Огранич. на размера на прикач. файлове"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Само ръчно синхронизиране при роуминг"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Изискване за шифроване на устройството"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Автоматично"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Един ден"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Три дни"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Една седмица"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Две седмици"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Един месец"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Всички"</string>
+</resources>
diff --git a/exchange2/res/values-ca/strings.xml b/exchange2/res/values-ca/strings.xml
new file mode 100644
index 0000000..9763ac6
--- /dev/null
+++ b/exchange2/res/values-ca/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Acceptada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Rebutjada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Provisional: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Cancel·lada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Actualitzada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Quan: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"On: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Quan: <xliff:g id="EVENTDATE">%s</xliff:g> (periòdica)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Quan: <xliff:g id="EVENTDATE">%s</xliff:g> (tot el dia)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Quan: <xliff:g id="EVENTDATE">%s</xliff:g> (tot el dia, periòdic)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"S\'ha afegit el calendari d\'Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Serveis d\'Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Aquest esdeveniment s\'ha cancel·lat per a: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Els detalls d\'aquest esdeveniment han canviat per a: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"No permetis targetes d\'emmagatzematge"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"No permetis aplicacions no signades"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"No permetis instal. d\'aplic. no sign."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"No permetis la Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"No permetis els missatges de text"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"No permetis els comptes POP3 ni IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"No permetis comunicacions per infraroigs"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"No permetis el correu electrònic HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"No permetis els navegadors"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"No permetis correus electr. de consum."</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"No permetis la compartició per Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Requereix missatges SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Restringeix l\'ús de Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"No permetis aplicacions especificades"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Permet només les aplicacions especif."</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Restring. mida de correu electr. de text"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Restringeix mida del correu electr. HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Requereix l\'encriptació de targetes SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"No permetis fitxers adjunts"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Restringeix la mida del fitxer adjunt"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Permet només sincr. manual en itineràn."</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Requereix l\'encriptació del dispositiu"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automàtic"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Un dia"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tres dies"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Una setmana"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dues setmanes"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Un mes"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Tots"</string>
+</resources>
diff --git a/exchange2/res/values-cs/strings.xml b/exchange2/res/values-cs/strings.xml
new file mode 100644
index 0000000..93b712f
--- /dev/null
+++ b/exchange2/res/values-cs/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Potvrzeno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Odmítnuto: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Možná: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Zrušeno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Aktualizováno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kdy: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kdy: <xliff:g id="EVENTDATE">%s</xliff:g> (pravidelně)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kdy: <xliff:g id="EVENTDATE">%s</xliff:g> (celý den)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kdy: <xliff:g id="EVENTDATE">%s</xliff:g> (celý den, opakující se)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Kalendář Exchange byl přidán"</string>
+    <string name="app_name" msgid="5316597712787122829">"Služby Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Tato událost byla zrušena pro datum: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Podrobnosti této události byly změněny pro datum: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Nepovolit paměťové karty"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Nepovolit nepodepsané aplikace"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Nepovolit nepodepsané instalátory"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Nepovolit připojení Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Nepovolit textové zprávy"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Nepovolovat účty POP3 a IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Nepovolit komunikaci IR"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Nepovolit e-maily ve formátu HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Nepovolit prohlížeče"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Nepovolit marketingové e-maily"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Nepovolit sdílení internetu"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Požadovat zprávy ve formátu SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Omezit použití připojení Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Blokovat zadané aplikace"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Povolit pouze zadané aplikace"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Omezit velikost textových e-mailů"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Omezit velikost e-mailů ve formátu HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Požadovat šifrování karty SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Nepovolit přílohy"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Omezit velikost příloh"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Při roamingu povolit jen ruční synch."</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Požadovat šifrování zařízení"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatické"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Jeden den"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tři dny"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Jeden týden"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dva týdny"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Jeden měsíc"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Vše"</string>
+</resources>
diff --git a/exchange2/res/values-da/strings.xml b/exchange2/res/values-da/strings.xml
new file mode 100644
index 0000000..7a4425b
--- /dev/null
+++ b/exchange2/res/values-da/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Accepteret: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Afvist: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Foreløbig: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Annulleret: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Opdateret: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Hvornår: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Hvor: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Hvornår: <xliff:g id="EVENTDATE">%s</xliff:g> (flere gange)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Hvornår: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dagen)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Hvornår: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dagen, tilbagevendende)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-kalender er tilføjet"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange-tjenester"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Denne begivenhed er annulleret for: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Oplysningerne om denne begivenhed er ændret for: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Tillad ikke hukommelseskort"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Tillad ikke usignerede apps"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Tillad ikke usignerede app-installationsprogrammer"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Tillad ikke Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Tillad ikke sms-beskeder"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Tillad ikke POP3- eller IMAP-konti"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Tillad ikke infrarød kommunikation"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Tillad ikke e-mail i HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Tillad ikke browsere"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Tillad ikke e-mail fra tredjepart"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Tillad ikke internetdeling"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Kræv SMIME-beskeder"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Begræns brugen af bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Tillad ikke angivne apps"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Tillad kun angivne apps"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Begræns tekststørrelsen for e-mail"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Begræns størrelsen på e-mail i HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Kræv kryptering af SD-kort"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Tillad ikke vedhæftede filer"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Begræns størrelsen på vedhæftede filer"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Tillad kun manuel synkron. under roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Kræv kryptering af enhed"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatisk"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"En dag"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tre dage"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"En uge"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"To uger"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"En måned"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Alle"</string>
+</resources>
diff --git a/exchange2/res/values-de/strings.xml b/exchange2/res/values-de/strings.xml
new file mode 100644
index 0000000..43e9c02
--- /dev/null
+++ b/exchange2/res/values-de/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Akzeptiert: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Abgelehnt: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Mit Vorbehalt: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Abgebrochen: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Aktualisiert: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Wann: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Wo: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Wann: <xliff:g id="EVENTDATE">%s</xliff:g> (wiederkehrend)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Wann: <xliff:g id="EVENTDATE">%s</xliff:g> (ganztägig)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Wann: <xliff:g id="EVENTDATE">%s</xliff:g> (ganztägig, wiederkehrend)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-Kalender hinzugefügt"</string>
+    <string name="app_name" msgid="5316597712787122829">"Austauschdienste"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Dieser Termin wurde storniert für: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Die Details dieses Termins wurden geändert für: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Speicherkarten nicht zulassen"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Keine unsignierten Apps"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Keine unsignierten App-Installer"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"WLAN nicht zulassen"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"SMS/MMS nicht zulassen"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3- oder IMAP-Konten nicht zulassen"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Infrarotkommunikation nicht zulassen"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTML-E-Mails nicht zulassen"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Browser nicht zulassen"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Verbraucher-E-Mails nicht zulassen"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Teilen über das Internet nicht zulassen"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"SMIME-Nachrichten erforderlich"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Bluetooth-Nutzung beschränken"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Angegebene Apps nicht zulassen"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Nur angegebene Apps zulassen"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"E-Mail-Text beschränken"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Größe von HTML-E-Mails beschränken"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"SD-Kartenverschlüsselung erforderlich"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Anhänge nicht zulassen"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Größe von Anhängen beschränken"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Bei Roaming nur manuelle Synchronis."</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Geräteverschlüsselung erforderlich"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatisch"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Ein Tag"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Drei Tage"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Eine Woche"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Zwei Wochen"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Ein Monat"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Alle"</string>
+</resources>
diff --git a/exchange2/res/values-el/strings.xml b/exchange2/res/values-el/strings.xml
new file mode 100644
index 0000000..79b27cf
--- /dev/null
+++ b/exchange2/res/values-el/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Έγινε αποδοχή: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Απορρίφθηκε: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Αβέβαιη παρουσία: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Ακυρώθηκε: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Ενημερώθηκε: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Πότε: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Που: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Πότε: <xliff:g id="EVENTDATE">%s</xliff:g> (επαναλαμβανόμενο)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Πότε: <xliff:g id="EVENTDATE">%s</xliff:g> (όλη την ημέρα)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Πότε: <xliff:g id="EVENTDATE">%s</xliff:g> (όλη την ημέρα, επαναλαμβανόμενα)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Προστέθηκε ημερολόγιο Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Υπηρεσίες Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Αυτό το συμβάν ακυρώθηκε για: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Οι λεπτομέρειες αυτού του συμβάντος άλλαξαν για: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Δεν επιτρέπονται κάρτες αποθήκευσης"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Απαγόρευση μη υπογεγραμμένων εφαρμογών"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Απαγόρ. μη υπογεγρ. προγ. εγκατ. εφαρμ."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Απαγόρευση σύνδεσης Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Δεν επιτρέπ. ανταλλαγή μηνυμ. κειμένου"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Δεν επιτρέπονται λογαρ. POP3 ή IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Δεν επιτρέπoνται υπέρυθρες επικοινωνίες"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Δεν επιτρέπεται ηλ. ταχ. HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Δεν επιτρέπονται προγρ. περιήγησης"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Δεν επιτρέπεται ηλ. ταχ. καταναλωτών"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Απαγόρευση κοινής χρήσης διαδικτύου"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Απαιτούνται μηνύματα SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Περιορισμός χρήσης bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Απαγόρευση συγκεκριμένων εφαρμογών"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Επιτρέπονται μόνο συγκεκριμ. εφαρμογές"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Περιορισμός μεγέθους κειμένου ηλ. ταχ."</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Περιορισμός μεγέθους ηλ. ταχ. HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Απαιτείται κρυπτογράφηση κάρτας SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Δεν επιτρέπονται συνημμένα"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Περιορισμός μεγέθους συνημμένων"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Σε περιαγωγή μόνο μη αυτ. συγχρονισμός"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Απαιτείται κρυπτογράφηση συσκευής"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Αυτόματη"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Μία ημέρα"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Τρεις ημέρες"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Μία εβδομάδα"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Δύο εβδομάδες"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Ένας μήνας"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Όλες"</string>
+</resources>
diff --git a/exchange2/res/values-en-rGB/strings.xml b/exchange2/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..069e0be
--- /dev/null
+++ b/exchange2/res/values-en-rGB/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Accepted: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Declined: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Tentative: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Cancelled: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Updated: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"When: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Where: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"When: <xliff:g id="EVENTDATE">%s</xliff:g> (recurring)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"When: <xliff:g id="EVENTDATE">%s</xliff:g> (all day)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"When: <xliff:g id="EVENTDATE">%s</xliff:g> (all day, recurring)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange calendar added"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"This event has been cancelled for: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"The details of this event have been changed for: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Don\'t allow storage cards"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Don\'t allow unsigned apps"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Don\'t allow unsigned app installers"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Don\'t allow Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Don\'t allow text messaging"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Don\'t allow POP3 or IMAP accounts"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Don\'t allow infrared communications"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Don\'t allow HTML email"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Don\'t allow browsers"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Don\'t allow consumer email"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Don\'t allow Internet sharing"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Require SMIME messages"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Restrict Bluetooth usage"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Disallow specified apps"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Allow only specified apps"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Restrict text email size"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Restrict HTML email size"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Require SD card encryption"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Don\'t allow attachments"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Restrict attachment size"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Only allow manual sync while roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Require device encryption"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatic"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"One day"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Three days"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"one week"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Two weeks"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"One month"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"All"</string>
+</resources>
diff --git a/exchange2/res/values-es-rUS/strings.xml b/exchange2/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..5753aba
--- /dev/null
+++ b/exchange2/res/values-es-rUS/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Aceptado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Rechazada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Tentativo: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Cancelado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Actualizado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Cuándo: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Dónde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Cuando: <xliff:g id="EVENTDATE">%s</xliff:g> (recurrente)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Cuándo: <xliff:g id="EVENTDATE">%s</xliff:g> (todo el día)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Cuándo: <xliff:g id="EVENTDATE">%s</xliff:g> (todo el día, se repite)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Calendario de Exchange agregado"</string>
+    <string name="app_name" msgid="5316597712787122829">"Servicios de Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Este evento ha sido cancelado para: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Los detalles de este evento se han modificado para: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"No permitir tarjetas de memoria"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"No instalar aplicaciones sin firmar"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"No permitir instaladores sin firmar"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"No permitir Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"No permitir envío de mensajes de texto"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"No permitir cuentas POP3 ni IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"No permitir comunicación por infrarrojos"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"No recibir correos electrónicos HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"No permitir el uso de navegadores"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"No recibir correos comerciales"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"No permitir uso compartido de Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Recibir solo mensajes SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Restringir el uso de Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Bloquear determinadas aplicaciones"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Permitir determinadas aplicaciones"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Restringir el tamaño de correos de texto"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Restringir el tamaño de los correos HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Requerir la encriptación de tarjetas SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"No descargar archivos adjuntos"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Restringir tamaño de archivos adjuntos"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Sincro. manual solo en itinerancia"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Requerir la encriptación del dispositivo"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automático"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Un día"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tres días"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Una semana"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dos semanas"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Un mes"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Todos"</string>
+</resources>
diff --git a/exchange2/res/values-es/strings.xml b/exchange2/res/values-es/strings.xml
new file mode 100644
index 0000000..1e7f3fe
--- /dev/null
+++ b/exchange2/res/values-es/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Aceptada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Rechazada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Provisional: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Cancelada: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Actualizado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Cuándo: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Dónde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Cuándo: <xliff:g id="EVENTDATE">%s</xliff:g> (periódico)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Cuando: <xliff:g id="EVENTDATE">%s</xliff:g> (todo el día)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Cuando: <xliff:g id="EVENTDATE">%s</xliff:g> (todo el día, periódico)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Se ha añadido un calendario de Exchange."</string>
+    <string name="app_name" msgid="5316597712787122829">"Servicios de Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Este evento se ha cancelado el día: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Los detalles de este evento se han cambiado al día: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"No permitir tarjetas de almacenamiento"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"No permitir aplicaciones sin firmar"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"No permitir instaladores sin firmar"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"No permitir Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"No permitir mensajes de texto"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"No permitir cuentas POP3 ni IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"No permitir comunicación por infrarrojos"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"No permitir correos HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"No permitir navegadores"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"No permitir correos comerciales"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"No permitir compartir conexión a Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Solicitar mensajes SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Restringir uso de Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"No permitir aplicaciones especificadas"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Permitir solo aplicaciones especificadas"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Restringir tamaño de letra del correo"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Restringir el tamaño del correo HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Solicitar encriptación de tarjeta SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"No permitir archivos adjuntos"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Restringir tamaño de archivos adjuntos"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Sincronización manual solo en itinerancia"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Solicitar encriptación de dispositivo"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automática"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Un día"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tres días"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Una semana"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dos semanas"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Un mes"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Todo"</string>
+</resources>
diff --git a/exchange2/res/values-et/strings.xml b/exchange2/res/values-et/strings.xml
new file mode 100644
index 0000000..139842b
--- /dev/null
+++ b/exchange2/res/values-et/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Vastu võetud: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Keeldutud: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Katseline: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Tühistatud: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Värskendatud: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Millal: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kus: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Millal: <xliff:g id="EVENTDATE">%s</xliff:g> (korduv)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Toimumisaeg: <xliff:g id="EVENTDATE">%s</xliff:g> (terve päev)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Toimumisaeg: <xliff:g id="EVENTDATE">%s</xliff:g> (terve päev, korduv)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange\'i kalender lisatud"</string>
+    <string name="app_name" msgid="5316597712787122829">"Vahetusteenused"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"See sündmus on tühistatud: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Selle sündmuse andmed on muutunud: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Keela mälukaardid"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Keela allkirjastamata rakendused"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Keela allkirjata rakenduste installerid"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Keela WiFi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Keela tekstsõnumside"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Keela POP3- või IMAP-kontod"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Keela infrapunaside"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Keela HTML-meilid"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Keela brauserid"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Keela tarbijate meilid"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Keela Interneti jagamine"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Nõua SMIME-sõnumeid"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Piira Bluetoothi kasutamist"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Keela määratud rakendused"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Luba ainult määratud rakendused"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Piira tekstmeilide suurust"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Piira HTML-meili suurust"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Nõua SD-kaardi krüpteerimist"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Keela manused"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Piira manuse suurust"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Luba käsitsi sünkr. ainult rändlusel"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Nõua seadme krüpteerimist"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automaatne"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Üks päev"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Kolm päeva"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Üks nädal"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Kaks nädalat"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Üks kuu"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Kõik"</string>
+</resources>
diff --git a/exchange2/res/values-fa/strings.xml b/exchange2/res/values-fa/strings.xml
new file mode 100644
index 0000000..13559bb
--- /dev/null
+++ b/exchange2/res/values-fa/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"پذیرفته شده: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"پذیرفته نشد: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"احتمالی: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"لغو شد: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"به روزرسانی شد: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"زمان: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"مکان: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"زمان: <xliff:g id="EVENTDATE">%s</xliff:g> (تکرار)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"زمان: <xliff:g id="EVENTDATE">%s</xliff:g> (در تمام طول روز)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"زمان: <xliff:g id="EVENTDATE">%s</xliff:g> (در تمام طول روز، بصورت تکراری)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"تقویم Exchange اضافه شد"</string>
+    <string name="app_name" msgid="5316597712787122829">"سرویس های Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"این رویداد لغو شده است به مدت: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"جزئیات این رویداد تغییر کرده اند به مدت: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"کارت‌های حافظه مجاز نیست"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"برنامه‌های امضا نشده مجاز نیستند"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"نصب کننده‌های برنامه امضا نشده مجاز نیستند"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wi-Fi مجاز نیست"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"پیام‌رسانی نوشتاری مجاز نیست"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"حساب‌های POP3 یا IMAP مجاز نیست"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"ارتباطات مادون قرمز مجاز نیست"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"ایمیل HTML مجاز نیست"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"مرورگرها مجاز نیستند"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"ایمیل مصرف‌کننده مجاز نیست"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"اشتراک‌گذاری اینترنتی مجاز نیست"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"پیامهای SMIME لازم است"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"استفاده از بلوتوث محدود است"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"برنامه‌های خاص مجاز نیستند"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"فقط برنامه‌های خاص مجاز هستند"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"اندازه نوشتار ایمیل محدود است"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"اندازه ایمیل HTML محدود است"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"کارت sd باید رمزگذاری شود"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"پیوست‌ها مجاز نیستند"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"اندازه پیوست محدود است"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"در حالت رومینگ فقط همگام‌سازی دستی مجاز است"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"دستگاه باید رمزگذاری شود"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"خودکار"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"یک روز"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"سه روز"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"یک هفته"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"دو هفته"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"یک ماه"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"همه"</string>
+</resources>
diff --git a/exchange2/res/values-fi/strings.xml b/exchange2/res/values-fi/strings.xml
new file mode 100644
index 0000000..3fbc7eb
--- /dev/null
+++ b/exchange2/res/values-fi/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Hyväksytty: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Hylätty: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Alustava: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Peruutettu: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Päivitetty: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Milloin: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Missä: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Milloin: <xliff:g id="EVENTDATE">%s</xliff:g> (toistuva)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Milloin: <xliff:g id="EVENTDATE">%s</xliff:g> (koko päivän)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Milloin: <xliff:g id="EVENTDATE">%s</xliff:g> (koko päivän, toistuva)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-kalenteri lisätty"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Poikkeus toistuvassa tapahtumassa, peruutettu <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Poikkeus toistuvassa tapahtumassa, muutettu <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Älä salli tallennuskortteja"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Älä salli allekirjoittamatt. sovelluksia"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Älä salli allekirjoittamatt. sov. asent."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Älä salli wifi-yhteyttä"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Älä salli tekstiviestejä"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Älä salli POP3- tai IMAP-tilejä"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Älä salli infrapunaviestintää"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Älä salli HTML-sähköpostia"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Älä salli selaimia"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Älä salli kuluttajasähköpostia"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Älä salli internet-jakamista"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Vaadi SMIME-viestit"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Rajoita bluetoothin käyttöä"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Älä salli määritettyjä sovelluksia"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Salli vain määritetyt sovellukset"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Rajoita tekstimuot. sähköpostien kokoa"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Rajoita HTML-muot. sähköpostien kokoa"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Vaatii SD-kortin salauksen"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Älä salli liitetiedostoja"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Rajoita liitetiedostojen kokoa"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Salli vain man. synkr. roaming-tilassa"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Vaatii laitteen salauksen"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automaattinen"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Yksi päivä"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Kolme päivää"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Yksi viikko"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Kaksi viikkoa"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Yksi kuukausi"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Kaikki"</string>
+</resources>
diff --git a/exchange2/res/values-fr/strings.xml b/exchange2/res/values-fr/strings.xml
new file mode 100644
index 0000000..6f89dc7
--- /dev/null
+++ b/exchange2/res/values-fr/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Réunion acceptée : <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Réunion refusée : <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Projet de réunion : <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Réunion annulée : <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Mise à jour : <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Date : <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Lieu : <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Date : <xliff:g id="EVENTDATE">%s</xliff:g> (périodique)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Quand : <xliff:g id="EVENTDATE">%s</xliff:g> (toute la journée)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Quand : <xliff:g id="EVENTDATE">%s</xliff:g> (toute la journée, récurrent)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Agenda Exchange ajouté"</string>
+    <string name="app_name" msgid="5316597712787122829">"Services Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Cet événement a été annulé pour : <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Les détails de cet événement ont été modifiés pour : <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Ne pas autoriser les cartes de stockage"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Ne pas autoriser programmes d\'installation non signés"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Ne pas autoriser programmes d\'installation non signés"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Ne pas autoriser les communications Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Ne pas autoriser les SMS"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Ne pas autoriser les comptes POP3 ni IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Ne pas autoriser communication infrarouge"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Ne pas autoriser e-mails au format HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Ne pas autoriser les navigateurs"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Ne pas autoriser e-mails publicitaires"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Ne pas autoriser partage connexion Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Exiger le format SMIME pour les messages"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Limiter l\'utilisation de Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Interdire les applications spécifiées"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Autoriser applications spécifiées uniq."</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Autoriser e-mails texte selon taille"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Autoriser e-mails HTML selon taille"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Exiger le chiffrement de la carte SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Ne pas autoriser les pièces jointes"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Autoriser pièces jointes selon taille"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Interdire synchro auto en itinérance"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Exiger le chiffrement de l\'appareil"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatique"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Un jour"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Trois jours"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Une semaine"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Deux semaines"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Un mois"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Tous"</string>
+</resources>
diff --git a/exchange2/res/values-hi/strings.xml b/exchange2/res/values-hi/strings.xml
new file mode 100644
index 0000000..15c7b80
--- /dev/null
+++ b/exchange2/res/values-hi/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"स्‍वीकृत: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"अस्‍वीकृत: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"अस्थायी: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"रद्द हो गई: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"अपडेट किया गया: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"कब: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"कहां: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"कब: <xliff:g id="EVENTDATE">%s</xliff:g> (पुनरावर्ती)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"कब: <xliff:g id="EVENTDATE">%s</xliff:g> (पूरा दिन)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"कब: <xliff:g id="EVENTDATE">%s</xliff:g> (पूरा दिन, पुनरावृत्ति)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange कैलेंडर जोड़ा गया"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"यह ईवेंट इसके लिए रद्द कर दिया गया है: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"इस ईवेंट का विवरण इसके लिए ‍बदल दिया गया है: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"संग्रहण कार्ड को अनुमति न दें"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"अहस्ताक्षरित एप्लिकेशन की अनुमति न दें"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"अहस्ता. एप्लि. इंस्‍टॉलर को अनुमति न दें"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wi-Fi की अनुमति न दें"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"पाठ संदेश सेवा की अनुमति न दें"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3 या IMAP खातों को अनुमति न दें"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"अवरक्त संचारों को अनुमति न दें"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTML ईमेल को अनुमति न दें"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"ब्राउज़र को अनुमति न दें"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"उपभोक्ता ईमेल की अनुमति न दें"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"इंटरनेट साझाकरण की अनुमति न दें"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"SMIME संदेश आवश्‍यक"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Bluetooth का उपयोग प्रतिबंधित करें"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"निर्दिष्ट एप्लिकेशन की अनुमति न दें"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"केवल निर्दिष्ट एप्लिकेशन की अनुमति दें"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"पाठ ईमेल का आकार प्रतिबंधित करें"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"HTML ईमेल का आकार प्रतिबंधित करें"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"SD कार्ड एन्‍क्रिप्शन आवश्‍यक"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"अनुलग्नकों की अनुमति न दें"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"अनुलग्‍नक का आकार प्रतिबंधित करें"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"रोमिंग पर मैन्‍युअल समन्वयन ही करने दें"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"उपकरण एन्‍क्रिप्शन आवश्‍यक"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"स्वचालित"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"एक दिन"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"तीन दिन"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"एक सप्‍ताह"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"दो सप्‍ताह"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"एक माह"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"सभी"</string>
+</resources>
diff --git a/exchange2/res/values-hr/strings.xml b/exchange2/res/values-hr/strings.xml
new file mode 100644
index 0000000..ad41a0d
--- /dev/null
+++ b/exchange2/res/values-hr/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Prihvaćeno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Odbijeno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Probno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Otkazano: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Ažurirano: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kad: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Gdje: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kada: <xliff:g id="EVENTDATE">%s</xliff:g> (ponavljanje)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kada: <xliff:g id="EVENTDATE">%s</xliff:g> (cijeli dan)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kada: <xliff:g id="EVENTDATE">%s</xliff:g> (cijeli dan, ponavlja se)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Dodan je Exchange kalendar"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Ovaj je događaj otkazan za: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Pojedinosti ovog događaja promijenjene su za: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Ne dopusti memorijske kartice"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Ne dopusti nepotpisane aplikacije"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Ne dopusti instal. prog. nepotpis. apl."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Ne dopusti WiFi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Ne dopusti slanje SMS poruka"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Ne dopusti POP3 ili IMAP račune"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Ne dopusti infracrvenu komunikaciju"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Ne dopusti e-poštu u HTML-u"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Ne dopusti preglednike"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Ne dopusti potrošačku e-poštu"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Ne dopusti dijeljenje na internetu"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Zahtijevaj SMIME poruke"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Ograniči upotrebu Bluetootha"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Odbaci navedene aplikacije"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Dopusti samo navedene aplikacije"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Ograniči veličinu tekstualne e-pošte"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Ograniči veličinu e-pošte u HTML-u"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Zahtijevaj enkripciju SD kartice"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Ne dopusti privitke"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Ograniči veličinu privitka"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Dopusti samo ručnu sinkr. u roamingu"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Zahtijevaj enkripciju uređaja"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatski"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Jedan dan"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tri dana"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Jedan tjedan"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dva tjedna"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Jedan mjesec"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Sve"</string>
+</resources>
diff --git a/exchange2/res/values-hu/strings.xml b/exchange2/res/values-hu/strings.xml
new file mode 100644
index 0000000..0f20934
--- /dev/null
+++ b/exchange2/res/values-hu/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Elfogadva: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Elutasítva: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Feltételes: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Lemondva: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Frissítve: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Időpont: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Helyszín: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Időpont: <xliff:g id="EVENTDATE">%s</xliff:g> (ismétlődő)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Időpont: <xliff:g id="EVENTDATE">%s</xliff:g> (egész nap)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Időpont: <xliff:g id="EVENTDATE">%s</xliff:g> (egész nap, ismétlődő)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-naptár hozzáadva"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange szolgáltatások"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Ezt az eseményt törölték: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Az esemény részletei a következőre módosultak: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Memóriakártyák nem engedélyezettek"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Csak hiteles alkalmazások engedélyezése"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Csak hiteles alkalmazásokat telepítsen"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wi-Fi tiltása"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Szöveges üzenetküldés nem engedélyezett"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3/IMAP-fiókok nem engedélyezettek"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Infra kommunikáció nem engedélyezett"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTML e-mailek nem engedélyezettek"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"A böngészők nem engedélyezettek"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Fogyasztói e-mailek nem engedélyezettek"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Internetmegosztás tiltása"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"SMIME-üzenetek szükségesek"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Bluetooth használatának korlátozása"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Meghatározott alkalmazások tiltása"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Csak megadott alkalmazások engedélyezése"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Szöveges e-mailek méretének korlátozása"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"HTML e-mailek méretének korlátozása"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"SD-kártya titkosítása szükséges"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Mellékletek nem engedélyezettek"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Mellékletek méretének korlátozása"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Csak kézi szinkronizálás barangoláskor"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Eszköztitkosítás szükséges"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatikus"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Egy nap"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Három nap"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Egy hét"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Két hét"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Egy hónap"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Összes"</string>
+</resources>
diff --git a/exchange2/res/values-in/strings.xml b/exchange2/res/values-in/strings.xml
new file mode 100644
index 0000000..be67dd0
--- /dev/null
+++ b/exchange2/res/values-in/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Diterima: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Ditolak: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Tentatif: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Dibatalkan: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Diperbarui: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kapan: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Di mana: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Waktu: <xliff:g id="EVENTDATE">%s</xliff:g> (terjadi berulang)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kapan: <xliff:g id="EVENTDATE">%s</xliff:g> (sepanjang hari)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kapan: <xliff:g id="EVENTDATE">%s</xliff:g> (sepanjang hari, berulang)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Tukar kalender yang ditambahkan"</string>
+    <string name="app_name" msgid="5316597712787122829">"Layanan Pertukaran"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Acara ini telah dibatalkan untuk: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Detail acara ini telah diubah untuk: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Jangan izinkan kartu penyimpanan"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Jangan izinkan apl tak bertanda tangan"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Jgn izinkan pmasang apl tak bertanda tgn"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Jangan izinkan Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Jangan izinkan pesan teks"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Jangan izinkan akun POP3 atau IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Jangan izinkan komunikasi inframerah"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Jangan izinkan email HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Jangan izinkan browser"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Jangan izinkan email pelanggan"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Jangan izinkan berbagi internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Memerlukan pesan SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Batasi penggunaan Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Tolak apl yang disebutkan"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Izinkan apl yang disebutkan saja"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Batasi ukuran email teks"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Batasi ukuran email HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Membutuhkan enkripsi kartu SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Jangan izinkan lampiran"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Batasi ukuran lampiran"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Hanya izinkan sinkr. manual saat roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Memerlukan enkripsi perangkat"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Otomatis"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Satu hari"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tiga hari"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Satu minggu"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dua minggu"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Satu bulan"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Semua"</string>
+</resources>
diff --git a/exchange2/res/values-it/strings.xml b/exchange2/res/values-it/strings.xml
new file mode 100644
index 0000000..406d1a0
--- /dev/null
+++ b/exchange2/res/values-it/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Accettato: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Rifiutato: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Tentativo: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Annullato: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Aggiornamento riuscito: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Quando: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Dove: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (ricorrente)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (tutto il giorno)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (tutto il giorno, ricorrente)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Calendario Exchange aggiunto"</string>
+    <string name="app_name" msgid="5316597712787122829">"Servizi Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Questo evento è stato annullato per la data: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"I dettagli di questo evento sono cambiati per la data: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Non consentire schede di memoria"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Non consentire applicazioni non firmate"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Non consentire installer app. non firmate"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Non consentire Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Non consentire messaggi di testo"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Non consentire account POP3 o IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Non consentire comunicazione a infrarossi"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Non consentire email HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Non consentire browser"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Non consentire email di livello consumer"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Non consentire condivisione Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Richiedi messaggi SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Limita utilizzo Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Non consentire applicazioni specificate"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Consenti solo applicazioni specificate"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Limita dimensioni testo email"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Limita dimensioni email HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Richiedi crittografia scheda SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Non consentire allegati"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Limita dimensioni allegati"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Consenti solo sincr. manuale in roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Richiedi crittografia dispositivo"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatico"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Un giorno"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tre giorni"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Una settimana"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Due settimane"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Un mese"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Tutto"</string>
+</resources>
diff --git a/exchange2/res/values-iw/strings.xml b/exchange2/res/values-iw/strings.xml
new file mode 100644
index 0000000..f32b378
--- /dev/null
+++ b/exchange2/res/values-iw/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"התקבלה: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"נדחה: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"לא סופי: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"בוטל: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"עודכן: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"מתי: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"היכן: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"מתי: <xliff:g id="EVENTDATE">%s</xliff:g> (אירוע חוזר)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"מתי: <xliff:g id="EVENTDATE">%s</xliff:g> (כל יום)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"מתי: <xliff:g id="EVENTDATE">%s</xliff:g> (כל היום, חוזר)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"נוסף יומן של Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"שירותי Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"אירוע זה בוטל לתאריך: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"הפרטים של אירוע זה השתנו בתאריך: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"אל תאפשר כרטיסי אחסון"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"אל תאפשר יישומים לא חתומים"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"אל תאפשר תוכנות התקנה לא חתומות של יישום."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"אל תאפשר WiFi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"אל תאפשר העברת הודעות טקסט"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"אל תאפשר חשבונות מסוג POP3 או IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"אל תאפשר תקשורת אינפרא-אדום"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"אל תאפשר דוא\"ל בפורמט HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"אל תאפשר דפדפנים"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"אל תאפשר דוא\"ל צרכן"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"אל תאפשר שיתוף באינטרנט"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"נדרשת העברת הודעות SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"הגבל את השימוש ב-Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"אל תאפשר יישומים שצוינו"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"אפשר רק יישומים שצוינו"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"הגבל את גודל הטקסט בדוא\"ל"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"הגבל גודל דוא\"ל בפורמט HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"נדרשת הצפנת כרטיס SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"אל תאפשר קבצים מצורפים"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"הגבל את גודל הקובץ המצורף"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"אפשר רק סינכרון ידני בעת נדידה"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"נדרשת הצפנת מכשיר"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"אוטומטי"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"יום אחד"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"שלושה ימים"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"שבוע אחד"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"שבועיים"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"חודש אחד"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"הכל"</string>
+</resources>
diff --git a/exchange2/res/values-ja/strings.xml b/exchange2/res/values-ja/strings.xml
new file mode 100644
index 0000000..7cdfafe
--- /dev/null
+++ b/exchange2/res/values-ja/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"承諾しました: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"辞退しました: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"仮承諾: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"辞退しました: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"更新されました: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"日時: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"場所: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"日時: <xliff:g id="EVENTDATE">%s</xliff:g>（定期的）"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"日付: <xliff:g id="EVENTDATE">%s</xliff:g>（終日）"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"日付: <xliff:g id="EVENTDATE">%s</xliff:g>（終日、定期的）"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchangeカレンダーを追加しました"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchangeサービス"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"この予定はキャンセルされました: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"この予定の詳細が変更されました: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"SDカードを許可しない"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"無署名のアプリを許可しない"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"無署名のアプリインストーラを許可しない"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wi-Fiを許可しない"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"テキストメッセージを許可しない"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3/IMAPアカウントを許可しない"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"赤外線通信を許可しない"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTMLメールを許可しない"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"ブラウザを許可しない"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"ダイレクトメールを許可しない"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"インターネット共有を許可しない"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"SMIME形式のメッセージを必須とする"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Bluetoothの使用を制限する"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"指定したアプリを許可しない"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"指定したアプリのみ許可する"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"テキストメールのサイズを制限する"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"HTMLメールのサイズを制限する"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"SDカードの暗号化を必須とする"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"添付ファイルを許可しない"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"添付ファイルのサイズを制限する"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"ローミング中は手動での同期のみを許可する"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"端末の暗号化を必須とする"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"自動"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"1日"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"3日間"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"1週間"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"2週間"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"1か月"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"すべて"</string>
+</resources>
diff --git a/exchange2/res/values-ko/strings.xml b/exchange2/res/values-ko/strings.xml
new file mode 100644
index 0000000..516705f
--- /dev/null
+++ b/exchange2/res/values-ko/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"수락: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"거부: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"미정: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"취소: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"업데이트: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"일시: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"장소: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"일시: <xliff:g id="EVENTDATE">%s</xliff:g>(반복 일정)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"일시: <xliff:g id="EVENTDATE">%s</xliff:g>(종일)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"일시: <xliff:g id="EVENTDATE">%s</xliff:g>(종일, 반복)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange 캘린더 추가됨"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange 서비스"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"<xliff:g id="DATE">%s</xliff:g>에 있을 이 일정이 취소되었습니다."</string>
+    <string name="exception_updated" msgid="3397583105901142050">"<xliff:g id="DATE">%s</xliff:g>에 있을 이 일정의 세부사항이 변경되었습니다."</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"저장 카드 허용 안함"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"서명되지 않은 앱 허용 안함"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"서명되지 않은 앱 설치 프로그램 허용 안함"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wi-Fi 허용 안함"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"문자 메시지 허용 안함"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3 또는 IMAP 계정 허용 안함"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"적외선 통신 허용 안함"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTML 이메일 허용 안함"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"브라우저 허용 안함"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"소비자 이메일 허용 안함"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"인터넷 공유 허용 안함"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"SMIME 메시지 필요"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"블루투스 사용 제한"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"지정된 앱 허용 안함"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"지정한 앱만 허용"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"텍스트 이메일 크기 제한"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"HTML 이메일 크기 제한"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"SD 카드 암호화 필요"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"첨부 파일 허용 안함"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"첨부 파일 크기 제한"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"로밍 중에 수동 동기화만 허용"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"기기 암호화 필요"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"자동"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"하루"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"3일"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"1주"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"2주"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"1달"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"전체"</string>
+</resources>
diff --git a/exchange2/res/values-lt/strings.xml b/exchange2/res/values-lt/strings.xml
new file mode 100644
index 0000000..1174644
--- /dev/null
+++ b/exchange2/res/values-lt/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Priimta: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Atmesta: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Neapsispręsta: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Atšaukta: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Atnaujinta: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kada: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kur: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kada: <xliff:g id="EVENTDATE">%s</xliff:g> (pasikartojantis)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kada: <xliff:g id="EVENTDATE">%s</xliff:g> (visą dieną)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kada: <xliff:g id="EVENTDATE">%s</xliff:g> (visą dieną, pasikartojantis)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Pridėtas „Exchange“ kalendorius"</string>
+    <string name="app_name" msgid="5316597712787122829">"Keitimo paslaugos"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Šis įvykis atšauktas: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Išsami šio įvykio informacija buvo pakeista: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Neleisti atminties kortelių"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Neleisti anoniminių programų"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Neleisti anon. programų diegimo progr."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Neleisti „Wi-Fi“"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Neleisti teksto pranešimų"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Neleisti POP3 ar IMAP prieigos paskyrų"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Neleisti infraraudonųjų spindulių ryšių"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Neleisti HTML el. laiškų"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Neleisti naršyklių"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Neleisti vartotojų el. laiškų"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Neleisti bendrinimo internetu"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Reikalauti SMIME pranešimų"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Apriboti „Bluetooth“ naudojimą"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Neleisti nurodytų programų"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Leisti tik nurodytas programas"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Riboti teksto el. laiškų dydį"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Riboti HTML el. laiškų dydį"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Reikalauti SD kortelės šifravimo"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Neleisti priedų"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Riboti priedo dydį"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Veikiant tarptink. r. sinch. tik pačiam"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Reikalauti įrenginių šifravimo"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatinis"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Vieną dieną"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tris dienas"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Viena savaitė"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dvi savaitės"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Vienas mėnuo"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Visas"</string>
+</resources>
diff --git a/exchange2/res/values-lv/strings.xml b/exchange2/res/values-lv/strings.xml
new file mode 100644
index 0000000..b615f28
--- /dev/null
+++ b/exchange2/res/values-lv/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Pieņemts: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Noraidīts: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Pagaidu: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Atcelts: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Atjaunināts: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kad: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kur: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kad: <xliff:g id="EVENTDATE">%s</xliff:g> (tiek atkārtots)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kad: <xliff:g id="EVENTDATE">%s</xliff:g> (visu dienu)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kad: <xliff:g id="EVENTDATE">%s</xliff:g> (visu dienu, atkārtoti)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange kalendārs ir pievienots"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange pakalpojumi"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Pasākums šajā datumā ir atcelts: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Šī pasākuma dati šādā datumā ir mainīti: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Neatļaut atmiņas kartes"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Neatļaut neparakstītas lietotnes"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Neatļaut neparakst. lietotņu instal. p."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Neatļaut Wi-Fi savienojumu"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Neatļaut īsziņas"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Neatļaut POP3 vai IMAP kontus"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Neatļaut infrasarkanos sakarus"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Neatļaut HTML e-pasta ziņojumus"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Neatļaut pārlūkprogrammas"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Neatļaut patērētāju e-pasta ziņojumus"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Neatļaut kopīgošanu internetā"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Pieprasīt SMIME formāta ziņojumus"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Ierobežot Bluetooth lietošanu"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Neatļaut noteiktas lietotnes"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Atļaut tikai norādītās lietotnes"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Ierobežot teksta e-pasta ziņojumu izmēru"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Ierobežot HTML e-pasta ziņojumu izmēru"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Pieprasīt SD kartes šifrēšanu"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Neatļaut pielikumus"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Ierobežot pielikumu izmēru"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Atļaut tikai man. sinhr., izm. viesabon."</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Pieprasīt ierīces šifrēšanu"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automātiski"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Viena diena"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Trīs dienas"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Viena nedēļa"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Divas nedēļas"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Viens mēnesis"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Visi"</string>
+</resources>
diff --git a/exchange2/res/values-ms/strings.xml b/exchange2/res/values-ms/strings.xml
new file mode 100644
index 0000000..d838e16
--- /dev/null
+++ b/exchange2/res/values-ms/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Diterima: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Ditolak: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Sementaraan: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Dibatalkan: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Dikemas kini: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Bila: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Di mana: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Bila: <xliff:g id="EVENTDATE">%s</xliff:g> (berulangan)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Bila: <xliff:g id="EVENTDATE">%s</xliff:g> (sepanjang hari)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Bila: <xliff:g id="EVENTDATE">%s</xliff:g> (sepanjang hari, berulang-ulang)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Kalendar Exchange ditambah"</string>
+    <string name="app_name" msgid="5316597712787122829">"Perkhidmatan Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Acara ini sudah dibatalkan untuk: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Butiran acara ini telah ditukar kepada: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Jgn benarkan kad storan"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Jgn bnrkan apl tanpa tandatangan"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Jgn bnrkan pemsng apl tanpa tandatangan"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Jgn benarkan Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Jgn benarkan pemesejan teks"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Jgn benarkan akaun POP3 atau IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Jgn benarkan komunikasi inframerah"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Jgn benarkan e-mel HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Jgn benarkan penyemak imbas"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Jgn benarkan e-mel pengguna"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Jgn benarkan perkongsian internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Perlukan mesej SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Hadkan penggunaan Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Jgn benarkan apl tertentu"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Benarnya hanya apl dinyatakan"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Hadkan saiz e-mel teks"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Hadkan saiz e-mel HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Memerlukan penyulitan kad SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Jgn benarkan lampiran"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Hadkan saiz lampiran"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Bnr sgrk manual sj semasa perayauan"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Perlukan penyulitan peranti"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatik"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Satu hari"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tiga hari"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Satu minggu"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dua minggu"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Satu bulan"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Semua"</string>
+</resources>
diff --git a/exchange2/res/values-nb/strings.xml b/exchange2/res/values-nb/strings.xml
new file mode 100644
index 0000000..2557782
--- /dev/null
+++ b/exchange2/res/values-nb/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Godtatt: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Avslått: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Foreslått: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Kansellert: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Oppdatert: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Når: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Hvor: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Når: <xliff:g id="EVENTDATE">%s</xliff:g> (gjentakende)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Når: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dagen)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Når: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dagen, gjentakende)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-kalender er lagt til"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange-tjenester"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Denne aktiviteten er kansellert for: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Detaljene for denne aktiviteten er endret for: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Ikke tillat minnekort"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Ikke tillat usignerte apper"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Ikke tillat usign. appinstallasjonsprog."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Ikke tillat Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Ikke tillat tekstmeldinger"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Ikke tillat POP3- eller IMAP-kontoer"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Ikke tillat infrarød kommunikasjon"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Ikke tillat e-post i HTML-format"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Ikke tillat nettlesere"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Ikke tillat forbruker-e-post"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Ikke tillat Internett-deling"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Krev SMIME-meldinger"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Begrens bruk av Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Forby angitte apper"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Tillat bare spesifikke apper"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Begrens størr. på e-post i tekstformat"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Begrens størr. på e-post i HTML-format"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Krev kryptering av SD-kort"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Ikke tillat vedlegg"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Begrens vedleggsstørrelse"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Bare tillat manuell synk. ved streifing"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Krev enhetskryptering"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatisk"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Én dag"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tre dager"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Én uke"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"To uker"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Én måned"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Alle"</string>
+</resources>
diff --git a/exchange2/res/values-nl/strings.xml b/exchange2/res/values-nl/strings.xml
new file mode 100644
index 0000000..c211304
--- /dev/null
+++ b/exchange2/res/values-nl/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Geaccepteerd: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Afgewezen: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Voorlopig: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Geannuleerd: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Bijgewerkt: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Wanneer: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Waar: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Wanneer: <xliff:g id="EVENTDATE">%s</xliff:g> (herhalen)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Wanneer: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dag)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Wanneer: <xliff:g id="EVENTDATE">%s</xliff:g> (hele dag, herhalen)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-agenda toegevoegd"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Deze afspraak is geannuleerd voor: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"De details van deze afspraak zijn gewijzigd voor: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Geheugenkaarten niet toestaan"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Niet-ondertekende apps niet toestaan"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Niet-ondertekende appinstallers weigeren"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Wifi niet toestaan"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Sms\'en niet toestaan"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3- of IMAP-accounts niet toestaan"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Infraroodcommunicatie niet toestaan"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTML-e-mail niet toestaan"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Browsers niet toestaan"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Consumenten-e-mail niet toestaan"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Internet delen niet toestaan"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"SMIME-berichten vereisen"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Het gebruik van Bluetooth beperken"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Opgegeven apps niet toestaan"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Alleen opgegeven apps toestaan"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Tekstgrootte van e-mail beperken"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Grootte van HTML-e-mails beperken"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Codering van SD-kaart vereisen"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Bijlagen niet toestaan"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Grootte van bijlagen beperken"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Alleen handm. synchr. toestn bij roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Apparaatencryptie vereisen"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatisch"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Eén dag"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Drie dagen"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Eén week"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Twee weken"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Eén maand"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Alles"</string>
+</resources>
diff --git a/exchange2/res/values-pl/strings.xml b/exchange2/res/values-pl/strings.xml
new file mode 100644
index 0000000..af7db82
--- /dev/null
+++ b/exchange2/res/values-pl/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Zaakceptowano: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Odrzucono: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Wahanie: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Anulowano: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Zaktualizowano: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kiedy: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Gdzie: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kiedy: <xliff:g id="EVENTDATE">%s</xliff:g> (powtarzane)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Data: <xliff:g id="EVENTDATE">%s</xliff:g> (cały dzień)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Data: <xliff:g id="EVENTDATE">%s</xliff:g> (cały dzień, cykliczne)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Dodano kalendarz Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Usługi wymiany"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"To zdarzenie zostało anulowane dla: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Szczegóły tego zdarzenia zostały zmienione dla: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Nie zezwalaj na karty pamięci"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Nie zezwalaj na niepodpisane aplikacje"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Nie zezwalaj na niepodpisane instalatory"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Nie zezwalaj na używanie sieci Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Nie zezwalaj na wiadomości SMS"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Nie zezwalaj na konta POP3 ani IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Nie zezwalaj na łączność w podczerwieni"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Nie zezwalaj na e-maile w formacie HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Nie zezwalaj na przeglądarki"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Nie zezwalaj na e-maile komercyjne"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Nie zezwalaj na udostępnianie internetu"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Wymagaj wiadomości w formacie SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Ogranicz użycie Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Nie zezwalaj na określone aplikacje"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Zezwalaj tylko na określone aplikacje"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Ograniczaj rozmiar e-maili tekstowych"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Ogranicz rozmiar e-maili w formacie HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Wymagaj szyfrowania na karcie SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Nie zezwalaj na załączniki"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Ograniczaj rozmiar załączników"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"W roamingu tylko synchronizacja ręczna"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Wymagaj szyfrowania w urządzeniu"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatycznie"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Jeden dzień"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Trzy dni"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Jeden tydzień"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dwa tygodnie"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Jeden miesiąc"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Wszystkie"</string>
+</resources>
diff --git a/exchange2/res/values-pt-rPT/strings.xml b/exchange2/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..f9ad5e9
--- /dev/null
+++ b/exchange2/res/values-pt-rPT/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Aceite: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Recusado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Provisório: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Cancelado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Actualizado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Quando: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Onde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (periódica)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (todo o dia)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (todo o dia, recorrente)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Calendário do Exchange adicionado"</string>
+    <string name="app_name" msgid="5316597712787122829">"Serviços do Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Este evento foi cancelado para: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Os detalhes deste evento foram alterados para: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Não permitir cartões de armazenamento"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Não permitir aplicações não assinadas"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Não permitir prog. de inst. não assinados"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Não permitir Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Não permitir mensagens de texto"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Não permitir contas POP3 ou IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Não permitir comun. por infravermelhos"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Não permitir e-mails em HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Não permitir navegadores"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Não permitir e-mails ao consumidor"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Não permitir partilha de internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Solicitar mensagens SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Limitar utilização de Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Não permitir aplicações especificadas"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Permitir apenas aplicações especificadas"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Limitar tamanho de e-mails de texto"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Limitar tamanho de e-mails em HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Solicitar encriptação do cartão SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Não permitir anexos"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Limitar tamanho dos anexos"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Permitir apenas sinc. manual em roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Solicitar encriptação do aparelho"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automático"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Um dia"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Três dias"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Uma semana"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Duas semanas"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Um mês"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Todas"</string>
+</resources>
diff --git a/exchange2/res/values-pt/strings.xml b/exchange2/res/values-pt/strings.xml
new file mode 100644
index 0000000..1944e59
--- /dev/null
+++ b/exchange2/res/values-pt/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Aceito: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Recusado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Tentativa: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Cancelado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Atualizado: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Quando:<xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Onde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (recorrente)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (o dia todo)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Quando: <xliff:g id="EVENTDATE">%s</xliff:g> (o dia todo, recorrente)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Agenda do Exchange adicionada"</string>
+    <string name="app_name" msgid="5316597712787122829">"Trocar serviços"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Este evento foi cancelado para: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Os detalhes deste evento foram alterados para: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Não permitir cartões de armazenamento"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Não permitir aplicativos não assinados"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Não permitir instal. aplic. não assinado"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Não permitir Wi-FI"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Não permitir mensagens de texto"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Não permitir contas POP3 ou IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Não permitir comunic. via infravermelho"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Não permitir e-mail em HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Não permitir navegadores"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Não permitir e-mail do consumidor"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Não permitir compart. pela Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Exigir mensagens em SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Restringir o uso de Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Desautorizar aplicativos especificados"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Permitir somente aplic. especificados"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Restringir o tamanho do e-mail em texto"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Restringir tamanho do e-mail em HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Exigir criptografia do cartão SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Não permitir anexos"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Restringir tamanho do anexo"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Permitir sinc. manual somente em roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Exigir criptografia do dispositivo"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automático"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Um dia"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Três dias"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Uma semana"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Duas semanas"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Um mês"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Todos"</string>
+</resources>
diff --git a/exchange2/res/values-rm/strings.xml b/exchange2/res/values-rm/strings.xml
new file mode 100644
index 0000000..13b3491
--- /dev/null
+++ b/exchange2/res/values-rm/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Acceptà: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Refusà: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Project dad inscunter: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Interrut: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Actualisà: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Cura: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Nua: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Cura: <xliff:g id="EVENTDATE">%s</xliff:g> (periodic)"</string>
+    <!-- no translation found for meeting_allday (6696389765484663513) -->
+    <skip />
+    <!-- no translation found for meeting_allday_recurring (2320264182781062684) -->
+    <skip />
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Agiuntà in chalender Exchange"</string>
+    <!-- no translation found for app_name (5316597712787122829) -->
+    <skip />
+    <string name="exception_cancel" msgid="6160117429428313805">"Questa occurrenza è vegnida annullada: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Ils detagls da questa occurrenza èn vegnids modifitgads: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <!-- no translation found for policy_dont_allow_storage_cards (2765447013574188473) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_unsigned_apps (4896164334956001479) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_unsigned_installers (1326544905185523540) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_wifi (3109487776704143995) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_text_messaging (7846141657345860427) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_pop_imap (4702932192358698651) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_irda (1848561629495912430) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_html (5888652525907651489) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_browser (1018764395507493616) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_consumer_email (6958427300686692292) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_internet_sharing (2370083814654927695) -->
+    <skip />
+    <!-- no translation found for policy_require_smime (673557150920820590) -->
+    <skip />
+    <!-- no translation found for policy_bluetooth_restricted (5248824127186039567) -->
+    <skip />
+    <!-- no translation found for policy_app_blacklist (8169194058285873461) -->
+    <skip />
+    <!-- no translation found for policy_app_whitelist (3670572644342165306) -->
+    <skip />
+    <!-- no translation found for policy_text_truncation (1783448050735715818) -->
+    <skip />
+    <!-- no translation found for policy_html_truncation (102158408055486343) -->
+    <skip />
+    <!-- no translation found for policy_require_sd_encryption (366468398301273342) -->
+    <skip />
+    <!-- no translation found for policy_dont_allow_attachments (6250520458670348907) -->
+    <skip />
+    <!-- no translation found for policy_max_attachment_size (4020279603050888661) -->
+    <skip />
+    <!-- no translation found for policy_require_manual_sync_roaming (6637416341015662148) -->
+    <skip />
+    <!-- no translation found for policy_require_encryption (7984702283392885348) -->
+    <skip />
+    <!-- no translation found for account_setup_options_mail_window_auto (4188895354366183790) -->
+    <skip />
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"In di"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Trais dis"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Ina emna"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Duas emnas"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"In mais"</string>
+    <!-- no translation found for account_setup_options_mail_window_all (5372861827683632364) -->
+    <skip />
+</resources>
diff --git a/exchange2/res/values-ro/strings.xml b/exchange2/res/values-ro/strings.xml
new file mode 100644
index 0000000..c5d8825
--- /dev/null
+++ b/exchange2/res/values-ro/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Acceptat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Refuzat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Tentativă: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Anulat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Actualizat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Când: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Unde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Când: <xliff:g id="EVENTDATE">%s</xliff:g> (recurent)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Când: <xliff:g id="EVENTDATE">%s</xliff:g> (toată ziua)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Când: <xliff:g id="EVENTDATE">%s</xliff:g> (toată ziua, repetat)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Calendar Exchange adăugat"</string>
+    <string name="app_name" msgid="5316597712787122829">"Servicii Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Acest eveniment a fost anulat pentru: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Detaliile acestui eveniment au fost modificate pentru: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Nu permiteţi carduri de stocare"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Nu permiteţi aplicaţii nesemnate"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Nu permiteţi instal. aplic. nesemnate"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Nu permiteţi Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Nu permiteţi mesagerie text"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Nu permiteţi conturi POP3 sau IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Nu permiteţi comunicaţiile în infraroşu"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Nu permiteţi e-mailuri HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Nu permiteţi browserele"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Nu permiteţi e-mailuri client"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Nu permiteţi distribuirea prin internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Solicitaţi mesaje SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Limitaţi util. funcţiilor Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Nu permiteţi anumite aplicaţii"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Permiteţi numai aplicaţii indicate"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Limitaţi dimensiunea e-mailurilor text"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Limitaţi dimensiunea e-mailurilor HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Necesită criptarea cardului SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Nu permiteţi ataşamente"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Limitaţi dimensiunea ataşamentului"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"În roaming permiteţi doar sincr. manuală"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Solicitaţi criptarea dispozitivului"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automat"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"O zi"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Trei zile"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"O săptămână"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Două săptămâni"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"O lună"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Toate"</string>
+</resources>
diff --git a/exchange2/res/values-ru/strings.xml b/exchange2/res/values-ru/strings.xml
new file mode 100644
index 0000000..7bb86c2
--- /dev/null
+++ b/exchange2/res/values-ru/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Принято: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Отклонено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Может быть: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Отменено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Обновлено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Время: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Где: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Время: <xliff:g id="EVENTDATE">%s</xliff:g> (повторяющееся)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Дата: <xliff:g id="EVENTDATE">%s</xliff:g> (весь день)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Дата: <xliff:g id="EVENTDATE">%s</xliff:g> (весь день, повторяется)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Календарь Exchange добавлен"</string>
+    <string name="app_name" msgid="5316597712787122829">"Службы Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Это мероприятие отменено: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Сведения об этом мероприятии были изменены: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Не использовать карты памяти"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Запрещать неподписанные приложения"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Запрещать неподписанные установщики"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Не использовать Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Запрещать SMS"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Не использовать аккаунты POP3 и IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Не использовать инфракрасный порт"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Не принимать письма в формате HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Не использовать браузеры"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Не принимать пользовательскую почту"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Не использовать режим модема"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Принимать только письма в формате SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Ограничить использование Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Запрещать указанные приложения"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Разрешать только указанные приложения"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Ограничивать размер текстовых писем"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Ограничивать размер писем в формате HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Всегда шифровать SD-карты"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Не загружать прикрепленные файлы"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Ограничивать размер прикрепленных файлов"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"В роуминге только ручная синхронизация"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Всегда шифровать устройство"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Автоматически"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Один день"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Три дня"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Одна неделя"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Две недели"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Один месяц"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Все"</string>
+</resources>
diff --git a/exchange2/res/values-sk/strings.xml b/exchange2/res/values-sk/strings.xml
new file mode 100644
index 0000000..0a907ea
--- /dev/null
+++ b/exchange2/res/values-sk/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Potvrdené: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Odmietnuté: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Možno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Zrušené: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Aktualizované: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kedy: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kde: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kedy: <xliff:g id="EVENTDATE">%s</xliff:g> (pravidelne)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kedy: <xliff:g id="EVENTDATE">%s</xliff:g> (celý deň)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kedy: <xliff:g id="EVENTDATE">%s</xliff:g> (celý deň, opakujúce sa)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Kalendár Exchange bol pridaný"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Táto udalosť bola zrušená pre termín: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Došlo k zmene podrobností tejto udalosti pre termín: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Nepovoliť karty s ukladacím priestorom"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Nepovoliť nepodpísané aplikácie"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Nepovoliť nepodpísané inštalátory aplikácií"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Nepovoliť siete Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Nepovoliť správy SMS a MMS"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Nepovoliť účty POP3 ani IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Nepovoliť infračervenú komunikáciu"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Nepovoliť e-mail vo formáte HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Nepovoliť prehliadače"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Nepovoliť marketingové e-maily"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Nepovoliť zdieľanie internetu"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Vyžadovať správy vo formáte SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Obmedziť použitie rozhrania Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Nepovoliť určené aplikácie"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Povoliť iba určené aplikácie"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Obmedziť veľkosť textového e-mailu"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Obmedziť veľkosť e-mailu vo formáte HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Vyžadovať šifrovanie kariet SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Nepovoliť prílohy"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Obmedziť veľkosť prílohy"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Povoliť ručnú synchr. len pri roamingu"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Vyžadovať šifrovanie zariadenia"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automaticky"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Jeden deň"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tri dni"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Týždeň"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dva týdny"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Jeden mesiac"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Všetky"</string>
+</resources>
diff --git a/exchange2/res/values-sl/strings.xml b/exchange2/res/values-sl/strings.xml
new file mode 100644
index 0000000..61bfbf9
--- /dev/null
+++ b/exchange2/res/values-sl/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Sprejeto: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Zavrnjeno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Pogojno sprejeto: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Preklicano: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Posodobljeno: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kdaj: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kje: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kdaj: <xliff:g id="EVENTDATE">%s</xliff:g> (se ponavlja)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kdaj: <xliff:g id="EVENTDATE">%s</xliff:g> (ves dan)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kdaj: <xliff:g id="EVENTDATE">%s</xliff:g> (ves dan, ponavljajoče)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Dodan koledar računa Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Storitve Exchange Services"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Ta dogodek je bil preklican za: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Podrobnosti tega dogodka so bile spremenjene: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Ne dovoli pomnilniških kartic"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Ne dovoli nepodpisanih programov"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Ne dovoli nepodpisanih namest. programov"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Ne dovoli povezave Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Ne dovoli sporočil SMS"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Ne dovoli računov POP3 ali IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Ne dovoli komunik. z infrardečo povezavo"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Ne dovoli e-poštnih sporočil HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Ne dovoli brskalnikov"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Ne dovoli potrošnišk. e-poštnih sporočil"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Ne dovoli skupne rabe interneta"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Zahtevaj sporočila v obliki zapisa SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Omeji uporabo Bluetootha"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Ne dovoli navedenih programov"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Dovoli samo navedene programe"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Omeji besedilo v e-poštnem sporočilu"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Omeji velikost e-poštnih sporočil HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Zahtevaj šifriranje kartice SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Ne dovoli prilog"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Omeji velikost prilog"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Med gostovanjem dovoli samo ročno sinhr."</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Zahtevaj šifriranje naprave"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Samodejno"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"En dan"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tri dni"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"En teden"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dva tedna"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"En mesec"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Vse"</string>
+</resources>
diff --git a/exchange2/res/values-sr/strings.xml b/exchange2/res/values-sr/strings.xml
new file mode 100644
index 0000000..6abf45c
--- /dev/null
+++ b/exchange2/res/values-sr/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Прихваћено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Одбијен: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Проба: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Отказано: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Ажурирано: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Када: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Где: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Када: <xliff:g id="EVENTDATE">%s</xliff:g> (редовно)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Када: <xliff:g id="EVENTDATE">%s</xliff:g> (цео дан)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Када: <xliff:g id="EVENTDATE">%s</xliff:g> (цео дан, понавља се)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Додат је Exchange календар"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange услуге"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Овај догађај је отказан за: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Детаљи овог догађаја су промењени за: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Не дозволи меморијске картице"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Не дозволи непотписане апликације"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Не дозволи непотписане инст. програме апликација"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Не дозволи Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Не дозволи размену текстуалних порука"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Не дозволи POP3 или IMAP налоге"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Не дозволи инфрацрвене комуникације"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Не дозволи HTML е-пошту"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Не дозволи прегледаче"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Не дозволи корисничку е-пошту"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Не дозволи дељење интернет везе"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Захтевај SMIME поруке"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Ограничи коришћење Bluetooth-а"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Онемогући наведене апликације"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Дозволи само наведене апликације"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Ограничи величину текста порука е-поште"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Ограничи величину HTML порука е-поште"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Захтевај шифровање SD картице"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Не дозволи прилоге"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Ограничи величину прилога"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Дозволи само ручну синхрониз. у ромингу"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Захтевај шифровање уређаја"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Аутоматски"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Један дан"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Три дана"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Недељу дана"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Две недеље"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Месец дана"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Све"</string>
+</resources>
diff --git a/exchange2/res/values-sv/strings.xml b/exchange2/res/values-sv/strings.xml
new file mode 100644
index 0000000..45d9454
--- /dev/null
+++ b/exchange2/res/values-sv/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Accepterat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Avvisat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Preliminärt: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Inställt: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Uppdaterat: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"När: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Var: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"När: <xliff:g id="EVENTDATE">%s</xliff:g> (återkommande)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"När: <xliff:g id="EVENTDATE">%s</xliff:g> (hela dagen)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"När: <xliff:g id="EVENTDATE">%s</xliff:g> (hela dagen, återkommande)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange-kalendern har lagts till"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange-tjänster"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Det här händelsen har ställts in för: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Den här händelsens information har ändrats för: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Tillåt inte minneskort"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Tillåt inte osignerade appar"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Tillåt inte installationsprogram för osignerade appar"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Tillåt inte Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Tillåt inte SMS"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Tillåt inte POP3- eller IMAP-konton"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Tillåt inte infraröd kommunikation"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Tillåt inte HTML-e-post"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Tillåt inte webbläsare"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Tillåt inte e-post från konsument"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Tillåt inte Internetdelning"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Kräv SMIME-meddelanden"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Begränsa Bluetooth-användning"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Tillåt inte specificerade appar"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Tillåt endast specificerade appar"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Begränsa textstorleken i e-post"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Begränsa storleken på HTML-e-post"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Kräv kryptering av SD-kort"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Tillåt inte bilagor"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Begränsa bilagans storlek"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Tillåt endast manuell synk vid roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Kräv enhetskryptering"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Automatisk"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"En dag"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tre dagar"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"En vecka"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Två veckor"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"En månad"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Alla"</string>
+</resources>
diff --git a/exchange2/res/values-sw/strings.xml b/exchange2/res/values-sw/strings.xml
new file mode 100644
index 0000000..e424e5e
--- /dev/null
+++ b/exchange2/res/values-sw/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Amekubali: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Amekataa: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Kwa sasa: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Zilizoghairiwa: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Imesasishwa: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Lini: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Wapi: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Wakati: <xliff:g id="EVENTDATE">%s</xliff:g> (itarudiwa)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Lini: <xliff:g id="EVENTDATE">%s</xliff:g> (siku nzima)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Lini: <xliff:g id="EVENTDATE">%s</xliff:g> (siku nzima, inajirudia)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Kalenda ya Exchange imeongezwa"</string>
+    <string name="app_name" msgid="5316597712787122829">"Huduma za Ubadilishanaji"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Tukio hili limeghairiwa kwa: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Maelezo ya tukio hili yamebadilishwa kwa: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"usiruhusu kadi za kuhifadhi"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Usiruhusu programu ambazo hazina saini"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Usiruhusu visakanishaji vya programu ambavyo havina saini"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Usiruhusu Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Usiruhusu utumaji ujumbe wa maandishi"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"usiruhusu akaunti za POP3 au IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"usiruhusu mawasiliano ya infraredi"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Usiruhusu barua pepe ya HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"usiruhusu vivinjari"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Usiruhusu barua pepe ya watumiaji"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Usiruhusu ushiriki kwenye mtandao"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Inahitaji ujumbe wa SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Zuia matumizi ya Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Usiruhusu programu zilizobainishwa"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Ruhusu programu zilizobainishwa pekee"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"weka mipaka ya ukubwa wa barua pepe ya maandishi"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"weka mipaka ya ukubwa wa barua pepe ya HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Inahitaji usimbaji fiche wa kadi ya SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Usiruhusu viambatisho"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"weka mipaka ya ukubwa wa viambatisho"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Ruhusu usawazishaji wa mkono wakati wa urandaji pekee"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Inahitaji usimbaji fiche wa kifaa"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Kiotomatiki"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Siku moja"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Siku tatu"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Wiki moja"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Wiki mbili"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Mwezi mmoja"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Zote"</string>
+</resources>
diff --git a/exchange2/res/values-th/strings.xml b/exchange2/res/values-th/strings.xml
new file mode 100644
index 0000000..85f6652
--- /dev/null
+++ b/exchange2/res/values-th/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"ตกลงเข้าร่วม: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"ปฏิเสธ: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"ชั่วคราว: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"ยกเลิกแล้ว: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"อัปเดต: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"เวลา: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"สถานที่: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"เวลา: <xliff:g id="EVENTDATE">%s</xliff:g> (เกิดซ้ำ)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"เมื่อ: <xliff:g id="EVENTDATE">%s</xliff:g> (ตลอดวัน)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"เมื่อ: <xliff:g id="EVENTDATE">%s</xliff:g> (ตลอดวัน เกิดซ้ำ)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"เพิ่มปฏิทิน Exchange แล้ว"</string>
+    <string name="app_name" msgid="5316597712787122829">"บริการแลกเปลี่ยน"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"กิจกรรมถูกยกเลิกแล้วในวันที่: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"วันที่ของกิจกรรมนี้ถูกเปลี่ยนเป็น: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"ไม่อนุญาตให้มีการ์ดบันทึกข้อมูล"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"ไม่อนุญาตแอปพลิเคชันที่ไม่ได้ลงชื่อ"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"ไม่อนุญาตตัวติดตั้งแอปฯ ที่ไม่ได้ลงชื่อ"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"ไม่อนุญาตให้ใช้ WiFi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"ไม่อนุญาตการรับส่งข้อความ"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"ไม่อนุญาตให้ใช้บัญชี POP3 หรือ IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"ไม่อนุญาตให้มีการสื่อสารอินฟราเรด"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"ไม่อนุญาตให้รับอีเมลแบบ HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"ไม่อนุญาตให้ใช้เบราว์เซอร์"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"ไม่อนุญาตให้รับอีเมลลูกค้า"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"ไม่อนุญาตการแบ่งปันอินเทอร์เน็ต"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"ต้องมีข้อความรูปแบบ SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"จำกัดการใช้บลูทูธ"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"ไม่อนุญาตให้ใช้แอปพลิเคชันที่ระบุ"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"อนุญาตแอปพลิเคชันที่ระบุเท่านั้น"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"จำกัดขนาดอีเมลแบบข้อความ"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"จำกัดขนาดอีเมลแบบ HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"ต้องมีการเข้ารหัสการ์ด SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"ไม่อนุญาตให้ดาวน์โหลดไฟล์แนบ"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"จำกัดขนาดไฟล์แนบ"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"อนุญาตเฉพาะการซิงค์ด้วยตนเองขณะโรมมิ่ง"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"ต้องมีการเข้ารหัสอุปกรณ์"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"อัตโนมัติ"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"หนึ่งวัน"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"3 วัน"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"1 สัปดาห์"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"สองสัปดาห์"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"1 เดือน"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"ทั้งหมด"</string>
+</resources>
diff --git a/exchange2/res/values-tl/strings.xml b/exchange2/res/values-tl/strings.xml
new file mode 100644
index 0000000..8c4083a
--- /dev/null
+++ b/exchange2/res/values-tl/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Tinanggap: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Tinanggihan: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Pansamantala: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Kinansela: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Na-update: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Kailan: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Saan: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Kailan: <xliff:g id="EVENTDATE">%s</xliff:g> (paulit-ulit)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Kailan: <xliff:g id="EVENTDATE">%s</xliff:g> (buong araw)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Kailan: <xliff:g id="EVENTDATE">%s</xliff:g> (buong araw, umuulit)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Idinagdag ang kalendaryong Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Magpalitan ng Mga Serbisyo"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Kinansela ang kaganapang ito para sa: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Ang mga detalye ng kaganapang ito ay binago para sa: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Huwag payagan ang mga storage card"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Huwag payagan ang mga di-pirmadong app"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Huwag payagan di-pirmadong app installer"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Huwag payagan ang Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Huwag payagan pagpapadala text message"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Huwag payagan mga POP3 o IMAP na account"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Wag payagan mga komunikasyon sa infrared"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Huwag payagan ang HTML na email"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Huwag payagan ang mga browser"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Huwag payagan ang email ng consumer"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Huwag payagan pagbabahagi ng internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Hilingin ang mga SMIME na mensahe"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Paghigpitan ang paggamit ng Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Huwag payagan ang mga tinukoy na app"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Payagan lamang ang mga tinukoy na app"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Paghigpitan ang laki ng tekstong email"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Paghigpitan ang laki ng HTML na email"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Hilingin ang pag-encrypt ng SD card"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Huwag payagan ang mga attachment"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Paghigpitan ang laki ng attachment"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Payag lang manu-mano sync kapag roaming"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Hilingin ang pag-encrypt ng device"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Awtomatiko"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Isang araw"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Tatlong araw"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Isang linggo"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Dalawang linggo"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Isang buwan"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Lahat"</string>
+</resources>
diff --git a/exchange2/res/values-tr/strings.xml b/exchange2/res/values-tr/strings.xml
new file mode 100644
index 0000000..a3373db
--- /dev/null
+++ b/exchange2/res/values-tr/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Kabul edildi: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Reddedildi: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Kararsız: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"İptal Edildi: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Güncellendi: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Zaman: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Yer: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Zaman: <xliff:g id="EVENTDATE">%s</xliff:g> (yinelenen)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Tarih: <xliff:g id="EVENTDATE">%s</xliff:g> (tüm gün)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Tarih: <xliff:g id="EVENTDATE">%s</xliff:g> (tüm gün, düzenli)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Exchange takvimi eklendi"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange Hizmetleri"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Bu olay şu tarih için iptal edildi: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Bu olayın ayrıntıları değiştirildi: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Depolama kartlarına izin verme"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"İmzasız uygulamalara izin verme"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"İmzasız uygulama yükleyicilere izin verme"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Kablosuza izin verme"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Kısa mesaja izin verme"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"POP3 veya IMAP hesaplarına izin verme"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Kızılötesi iletişime izin verme"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"HTML e-postaya izin verme"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Tarayıcılara izin verme"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Tüketici e-postasına izin verme"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"İnternet paylaşımına izin verme"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"İletilerin SMIME olmasını gerektir"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Bluetooth kullanımını kısıtla"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Belirtilen uygulamalara izin verme"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Sadece belirtilen uygulamalara izin ver"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Metin e-posta boyutunu kısıtla"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"HTML e-posta boyutunu kısıtla"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"SD kart şifrelemesi gerektir"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Eklere izin verme"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Ek boyutunu kısıtla"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Dolaşımda sadece elle senk. izin ver"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Cihaz şifrelemesi gerektir"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Otomatik"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Bir gün"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Üç gün"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Bir hafta"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"İki hafta"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Bir ay"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Tümü"</string>
+</resources>
diff --git a/exchange2/res/values-uk/strings.xml b/exchange2/res/values-uk/strings.xml
new file mode 100644
index 0000000..9980194
--- /dev/null
+++ b/exchange2/res/values-uk/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Прийнято: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Відхилено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Попередньо: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Скасовано: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Оновлено: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Коли: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Де: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Коли: <xliff:g id="EVENTDATE">%s</xliff:g> (повтор.)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Коли: <xliff:g id="EVENTDATE">%s</xliff:g> (увесь день)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Коли: <xliff:g id="EVENTDATE">%s</xliff:g> (увесь день, періодично)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Додано календар Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Служби Exchange"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Цю подію було скасовано для: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Деталі цієї події змінено на: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Не дозволяти карти пам’яті"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Не дозволяти непідписані програми"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Не дозвол. встановлюв. непідпис. прогр."</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Не дозволяти Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Не дозволяти текстові повідомлення"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Не дозволяти облік. записи POP3 або IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Не дозволяти інфрачервоний зв’язок"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Не дозволяти листи у форматі HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Не дозволяти веб-переглядачі"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Не дозволяти поштові сервіси"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Не дозвол. надання доступу до Інтернету"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Вимагати повідомлення у форматі SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Обмежувати використання Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Забороняти вказані програми"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Дозволяти лише вказані програми"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Обмежувати розмір тексту листів"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Обмежувати розмір листів у форматі HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Вимагати шифрування карти SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Не дозволяти вкладені файли"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Обмежувати розмір вкладених файлів"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Дозвол. синхрон. вручну лише в роумінгу"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Вимагати шифрування пристрою"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Автоматично"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Один день"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Три дні"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"1 тиждень"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"2 тижні"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Один місяць"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Усі"</string>
+</resources>
diff --git a/exchange2/res/values-vi/strings.xml b/exchange2/res/values-vi/strings.xml
new file mode 100644
index 0000000..fc77541
--- /dev/null
+++ b/exchange2/res/values-vi/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Được chấp nhận: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Đã từ chối: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Dự kiến: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Đã hủy: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Đã cập nhật: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Thời gian: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Địa điểm: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Thời gian: <xliff:g id="EVENTDATE">%s</xliff:g> (lặp lại)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Thời gian: <xliff:g id="EVENTDATE">%s</xliff:g> (cả ngày)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Thời gian: <xliff:g id="EVENTDATE">%s</xliff:g> (cả ngày, lặp lại)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Đã thêm lịch Exchange"</string>
+    <string name="app_name" msgid="5316597712787122829">"Dịch vụ hối đoái"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Sự kiện này đã bị hủy cho: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Chi tiết về sự kiện này đã được thay đổi cho: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"Không cho phép thẻ lưu trữ"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Không cho phép ứng dụng chưa kiểm tra"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Ko cho phép tr.cài đặt ứ.dụng chưa k.tra"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Không cho phép Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"Không cho phép nhắn tin văn bản"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Không cho phép tài khoản POP3 hoặc IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"Không cho phép giao tiếp bằng hồng ngoại"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"Không cho phép email HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"Không cho phép trình duyệt"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"Không cho phép email của người dùng"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Không cho phép chia sẻ kết nối Internet"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"Yêu cầu tin nhắn  SMIME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Hạn chế sử dụng Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Ko cho phép các ứng dụng được chỉ định"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Chỉ cho phép các ứng dụng được chỉ định"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Hạn chế kích thước email văn bản"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Hạn chế kích thước email HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Yêu cầu mã hóa thẻ SD"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"Không cho phép tệp đính kèm"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Hạn chế kích thước của tệp đính kèm"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"Chỉ được đ.bộ hóa thủ công khi ch.vùng"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"Yêu cầu mã hóa thiết bị"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Tự động"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Một ngày"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Ba ngày"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Một tuần"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Hai tuần"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Một tháng"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Tất cả"</string>
+</resources>
diff --git a/exchange2/res/values-zh-rCN/strings.xml b/exchange2/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..2c004ed
--- /dev/null
+++ b/exchange2/res/values-zh-rCN/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"已接受：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"已拒绝：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"暂定：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"已取消：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"已更新：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"时间：<xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"地点：<xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"时间：<xliff:g id="EVENTDATE">%s</xliff:g>（重复）"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"日期：<xliff:g id="EVENTDATE">%s</xliff:g>（全天）"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"日期：<xliff:g id="EVENTDATE">%s</xliff:g>（全天，循环）"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"已添加 Exchange 日历"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange 服务"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"定于以下日期的活动已取消：<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"定于以下日期的活动的详细信息已更改：<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"不允许使用存储卡"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"不允许安装未签名的应用"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"不允许通过未签名的安装程序来安装应用"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"不允许使用 Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"不允许使用短信功能"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"不允许使用 POP3 或 IMAP 帐户"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"不允许红外通信"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"不允许接收 HTML 电子邮件"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"不允许使用浏览器"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"不允许接收消费者电子邮件"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"不允许共享互联网连接"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"电子邮件必须采用 SMIME 格式"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"限制蓝牙功能"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"不允许使用指定的应用"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"只允许使用指定的应用"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"限制文本电子邮件的大小"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"限制 HTML 电子邮件的大小"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"要求 SD 卡加密"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"不允许下载附件"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"限制附件的大小"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"只允许在漫游时手动同步"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"要求设备加密"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"自动"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"一天"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"三天"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"一周"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"两周"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"一个月"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"全部"</string>
+</resources>
diff --git a/exchange2/res/values-zh-rTW/strings.xml b/exchange2/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..12842a6
--- /dev/null
+++ b/exchange2/res/values-zh-rTW/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Microsoft Exchange ActiveSync"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"已接受：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"已拒絕：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"未定：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"已取消：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"已更新：<xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"登入時間：<xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"地點：<xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"時間：<xliff:g id="EVENTDATE">%s</xliff:g> (週期性)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"時間：<xliff:g id="EVENTDATE">%s</xliff:g> (整天)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"時間：<xliff:g id="EVENTDATE">%s</xliff:g> (整天，週期性)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"已新增 Exchange 日曆"</string>
+    <string name="app_name" msgid="5316597712787122829">"Exchange 服務"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"已將 <xliff:g id="DATE">%s</xliff:g> 時的此活動取消"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"已變更此活動於 <xliff:g id="DATE">%s</xliff:g> 時的詳細資料"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"不允許儲存卡"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"不允許未簽署的應用程式"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"不允許未簽署的應用程式安裝程式"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"不允許 WiFi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"不允許傳送簡訊"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"不允許 POP3 或 IMAP 帳戶"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"不允許紅外線通訊"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"不允許接收 HTML 電子郵件"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"不允許瀏覽器"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"不允許接收消費者電子郵件"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"不允許網際網路共用功能"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"需要 SMIME 郵件"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"限制藍牙使用量"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"不允許指定的應用程式"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"只允許指定的應用程式"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"限制文字電子郵件大小"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"限制 HTML 電子郵件大小"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"需要 SD 卡加密"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"不允許附件"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"限制附件大小"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"漫遊時僅允許手動同步處理"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"需要裝置加密"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"自動"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"1 天"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"3 天"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"1 週"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"2 週"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"1 個月"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"全部"</string>
+</resources>
diff --git a/exchange2/res/values-zu/strings.xml b/exchange2/res/values-zu/strings.xml
new file mode 100644
index 0000000..b97af51
--- /dev/null
+++ b/exchange2/res/values-zu/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="exchange_name_alternate" msgid="5772529644749041052">"Ukuvumelanisa Okusebenzayo Kokushintshanisa kwe-Microsoft"</string>
+    <string name="meeting_accepted" msgid="8796609373330400268">"Kwamukeliwe: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_declined" msgid="6707617183246608552">"Inqabile: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_tentative" msgid="8250995722130443785">"Okwesikhashana: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_canceled" msgid="3949893881872084244">"Kukhanseliwe: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_updated" msgid="8529675857361702860">"Kubuyekeziwe: <xliff:g id="SUBJECT">%s</xliff:g>"</string>
+    <string name="meeting_when" msgid="2765696159697448656">"Nini: <xliff:g id="WHEN">%s</xliff:g>"</string>
+    <string name="meeting_where" msgid="5992367535856553079">"Kuphi: <xliff:g id="WHERE">%s</xliff:g>"</string>
+    <string name="meeting_recurring" msgid="3134262212606714023">"Nini: <xliff:g id="EVENTDATE">%s</xliff:g> (okuvela njalo)"</string>
+    <string name="meeting_allday" msgid="6696389765484663513">"Nini: <xliff:g id="EVENTDATE">%s</xliff:g> (usuku lonke)"</string>
+    <string name="meeting_allday_recurring" msgid="2320264182781062684">"Nini: <xliff:g id="EVENTDATE">%s</xliff:g> (usuku lonke, okuqhubekayo)"</string>
+    <string name="notification_exchange_calendar_added" msgid="6823659622379350159">"Ukushintsha ikhalenda kufakiwe"</string>
+    <string name="app_name" msgid="5316597712787122829">"Amasevisi Okushintshelana"</string>
+    <string name="exception_cancel" msgid="6160117429428313805">"Lesi senzakalo sikhanselwe i-<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="exception_updated" msgid="3397583105901142050">"Imininingwane yalesenzakalo ishintshelwe:<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="policy_dont_allow_storage_cards" msgid="2765447013574188473">"ungavumeli amakhadi okulonda"</string>
+    <string name="policy_dont_allow_unsigned_apps" msgid="4896164334956001479">"Ungavumeli ama-apps angabhalisiwe"</string>
+    <string name="policy_dont_allow_unsigned_installers" msgid="1326544905185523540">"Ungafumeli izifaki ze-app ezingangenanga"</string>
+    <string name="policy_dont_allow_wifi" msgid="3109487776704143995">"Ungavumeli i-Wi-Fi"</string>
+    <string name="policy_dont_allow_text_messaging" msgid="7846141657345860427">"ungavumeli imilayezo yombhalo"</string>
+    <string name="policy_dont_allow_pop_imap" msgid="4702932192358698651">"Ungavumeli i-POP3 noma ama-akhawunti e-IMAP"</string>
+    <string name="policy_dont_allow_irda" msgid="1848561629495912430">"ungavumeli ukukhulumisana kwe-infrared"</string>
+    <string name="policy_dont_allow_html" msgid="5888652525907651489">"ungavumeli i-imeyli ye-HTML"</string>
+    <string name="policy_dont_allow_browser" msgid="1018764395507493616">"ungavumeli isiphequluli"</string>
+    <string name="policy_dont_allow_consumer_email" msgid="6958427300686692292">"ungavumeli i-imeyli yomthengi"</string>
+    <string name="policy_dont_allow_internet_sharing" msgid="2370083814654927695">"Ungavumeli ukwabelana nge-inthanethi"</string>
+    <string name="policy_require_smime" msgid="673557150920820590">"idinga imiyalezo ye-SMME"</string>
+    <string name="policy_bluetooth_restricted" msgid="5248824127186039567">"Nciphisa ukusetshenziswa kwe-Bluetooth"</string>
+    <string name="policy_app_blacklist" msgid="8169194058285873461">"Ungavumeli ama-apps angacacisiwe"</string>
+    <string name="policy_app_whitelist" msgid="3670572644342165306">"Vumela ama-apps avunyelwe"</string>
+    <string name="policy_text_truncation" msgid="1783448050735715818">"Nciphisa usayizi wombhalo we-imeyli"</string>
+    <string name="policy_html_truncation" msgid="102158408055486343">"Nciphisa usayizi wama-imeyli e-HTML"</string>
+    <string name="policy_require_sd_encryption" msgid="366468398301273342">"Idinga ikhadimfihlo lekhadi le-sd"</string>
+    <string name="policy_dont_allow_attachments" msgid="6250520458670348907">"ungavumeli okunamathiselwa ku-imeyli"</string>
+    <string name="policy_max_attachment_size" msgid="4020279603050888661">"Nciphisa usayizi wokunamathiselwa ku-imeyli"</string>
+    <string name="policy_require_manual_sync_roaming" msgid="6637416341015662148">"vumela ukuvumelanisa ngokwenziwa ngezandla kuphela uma uzulazula"</string>
+    <string name="policy_require_encryption" msgid="7984702283392885348">"idinga amakhodimfihlo edivayisi"</string>
+    <string name="account_setup_options_mail_window_auto" msgid="4188895354366183790">"Okuzenzakalelayo"</string>
+    <string name="account_setup_options_mail_window_1day" msgid="3965715241135811407">"Usuku olulodwa"</string>
+    <string name="account_setup_options_mail_window_3days" msgid="736181102295878114">"Izinsuku ezintathu"</string>
+    <string name="account_setup_options_mail_window_1week" msgid="5639718031108023741">"Iviki elilodwa"</string>
+    <string name="account_setup_options_mail_window_2weeks" msgid="4567049268124213035">"Amaviki amabili"</string>
+    <string name="account_setup_options_mail_window_1month" msgid="5846359669750047081">"Inyanga eyodwa"</string>
+    <string name="account_setup_options_mail_window_all" msgid="5372861827683632364">"Konke"</string>
+</resources>
diff --git a/exchange2/res/values/arrays.xml b/exchange2/res/values/arrays.xml
new file mode 100644
index 0000000..d2f24f6
--- /dev/null
+++ b/exchange2/res/values/arrays.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <!-- Mail sync window sizes for EAS accounts -->
+    <!--  The window length array/strings below MUST remain in sync with com.android.email -->
+    <string-array name="account_settings_mail_window_entries">
+        <item>@string/account_setup_options_mail_window_auto</item>
+        <item>@string/account_setup_options_mail_window_1day</item>
+        <item>@string/account_setup_options_mail_window_3days</item>
+        <item>@string/account_setup_options_mail_window_1week</item>
+        <item>@string/account_setup_options_mail_window_2weeks</item>
+        <item>@string/account_setup_options_mail_window_1month</item>
+        <item>@string/account_setup_options_mail_window_all</item>
+    </string-array>
+
+</resources>
diff --git a/exchange2/res/values/strings.xml b/exchange2/res/values/strings.xml
new file mode 100644
index 0000000..1716e35
--- /dev/null
+++ b/exchange2/res/values/strings.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Deprecated strings - Move the identifiers to this section, mark as
+        DO NOT TRANSLATE, and remove the actual text. These will be removed in a
+        bulk operation. -->
+    <!-- Do Not Translate. Unused string. -->
+
+    <!-- Name of Microsoft Exchange account type; used by AccountManager -->
+    <string name="exchange_name">Corporate</string>
+    <!-- Name of Microsoft Exchange account type; used by AccountManager -->
+    <string name="exchange_name_alternate">Microsoft Exchange ActiveSync</string>
+
+    <!-- Message subject for meeting accepted response. This will be followed
+        by a colon and the title of the meeting (i.e. the title of the meeting becomes
+        part of the subject of the message that's sent) -->
+    <string name="meeting_accepted">
+        Accepted:
+        <xliff:g id="subject">%s</xliff:g>
+    </string>
+    <!-- Message subject for meeting declined response. This is followed by
+        a colon and the title of the meeting (i.e. the title of the meeting becomes
+        part of the subject of the message that's sent) -->
+    <string name="meeting_declined">
+        Declined:
+        <xliff:g id="subject">%s</xliff:g>
+    </string>
+    <!-- Message subject for meeting tentative response. This is followed by
+        a colon and the title of the meeting (i.e. the title of the meeting becomes
+        part of the subject of the message that's sent) -->
+    <string name="meeting_tentative">
+        Tentative:
+        <xliff:g id="subject">%s</xliff:g>
+    </string>
+    <!-- Message subject for a canceled meeting email. This is followed by a
+        colon and the title of the meeting (i.e. the title of the meeting becomes
+        part of the subject of the message that's sent) -->
+    <string name="meeting_canceled">
+        Canceled:
+        <xliff:g id="subject">%s</xliff:g>
+    </string>
+    <!-- Message subject for an updated meeting email. This is followed by a
+        colon and the title of the meeting (i.e. the title of the meeting becomes
+        part of the subject of the message that's sent) -->
+    <string name="meeting_updated">
+        Updated:
+        <xliff:g id="subject">%s</xliff:g>
+    </string>
+
+    <!-- Indicate when a meeting takes place. This is presented in in bullet
+        form, as in, "When: xxx" followed by "Where: xxx" -->
+    <string name="meeting_when">
+        When:
+        <xliff:g id="when">%s</xliff:g>
+    </string>
+    <!-- Indicate where a meeting takes place. This is presented in in bullet
+        form, as in, "When: xxx" followed by "Where: xxx" -->
+    <string name="meeting_where">
+        Where:
+        <xliff:g id="where">%s</xliff:g>
+    </string>
+    <!-- Indicate that a meeting is recurring. This would normally be presented
+        after "When: xxx", e.g. "When: Tue, Mar 10, 2010 at 2:30pm (recurring)" -->
+    <string name="meeting_recurring">
+        When:
+        <xliff:g id="eventdate" example="Tue, Mar 10, 2010 at 2:30 pm">%s</xliff:g>
+        (recurring)
+    </string>
+    <!-- Indicate that a meeting lasts all day. This would normally be presented
+        after "When: xxx", e.g. "When: Tue, Mar 10, 2010 (all day)" -->
+    <string name="meeting_allday">
+        When:
+        <xliff:g id="eventdate" example="Tue, Mar 10, 2010 ">%s</xliff:g>
+        (all day)
+    </string>
+    <!-- Indicate that a meeting lasts all day and is recurring. This would normally be presented
+        after "When: xxx", e.g. "When: Tue, Mar 10, 2010 (all day, recurring)" -->
+    <string name="meeting_allday_recurring">
+        When:
+        <xliff:g id="eventdate" example="Tue, Mar 10, 2010 ">%s</xliff:g>
+        (all day, recurring)
+    </string>
+
+    <!-- Notification message in notifications window when calendar sync is
+        automatically enabled for pre-existing Exchange accounts on upgrade -->
+    <string name="notification_exchange_calendar_added">Exchange calendar added</string>
+
+    <!-- The name of this APK as shown in manage applications settings. [CHAR LIMIT=30] -->
+    <string name="app_name" >Exchange Services</string>
+
+    <!-- Used as the body text of a message reporting to an attendee that a
+        specific instance of a recurring meeting has been canceled -->
+    <string name="exception_cancel">
+        This event has been canceled
+        for:
+        <xliff:g id="date">%s</xliff:g>
+    </string>
+    <!-- Used as the body text of a message reporting to an attendee that a
+        specific instance of a recurring meeting has been changed -->
+    <string name="exception_updated">
+        The details of this event have been changed
+        for:
+        <xliff:g id="date">%s</xliff:g>
+    </string>
+
+    <!-- The following are a list of policies that the user's server might require, but that can't
+        be enforced by our device.  We will list them separated by commas, as required -->
+    <!-- A policy in which the device may not have a storage card [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_storage_cards">Don\'t allow storage cards</string>
+    <!-- A policy in which the device may not have unsigned applications installed
+        [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_unsigned_apps">Don\'t allow unsigned apps</string>
+    <!-- A policy in which the device may not allow application installation via an unsigned
+        installer [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_unsigned_installers">Don\'t allow unsigned app
+        installers</string>
+    <!-- A policy in which the device may not allow wifi communications [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_wifi">Don\'t allow Wi-Fi</string>
+    <!-- A policy in which the device may not allow text messaging [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_text_messaging">Don\'t allow text messaging</string>
+    <!-- A policy in which the device may not allow POP3 or IMAP email accounts [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_pop_imap">Don\'t allow POP3 or IMAP accounts</string>
+    <!-- A policy in which the device may allow infrared communications [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_irda">Don\'t allow infrared communications</string>
+    <!-- A policy in which the device may allow HTML email to be received [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_html">Don\'t allow HTML email</string>
+    <!-- A policy in which the device may not allow the user of web browsers [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_browser">Don\'t allow browsers</string>
+    <!-- A policy in which the device may not allow the receipt of consumer email
+        [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_consumer_email">Don\'t allow consumer email</string>
+    <!-- A policy in which the device may not allow internet connection sharing
+        [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_internet_sharing">Don\'t allow Internet sharing</string>
+    <!-- A policy in which messages must be in SMIME format [CHAR LIMIT=50] -->
+    <string name="policy_require_smime">Require SMIME messages</string>
+    <!-- A policy in which the device's bluetooth capabilities are restricted [CHAR LIMIT=50] -->
+    <string name="policy_bluetooth_restricted">Restrict Bluetooth usage</string>
+    <!-- A policy in which the device blocks specified applications [CHAR LIMIT=50]-->
+    <string name="policy_app_blacklist">Disallow specified apps</string>
+    <!-- A policy in which the device allows only specified applications [CHAR LIMIT=50] -->
+    <string name="policy_app_whitelist">Allow only specified apps</string>
+    <!-- A policy in which the device limits the amount of text that can be displayed for a
+        given message [CHAR LIMIT=50] -->
+    <string name="policy_text_truncation">Restrict text email size</string>
+    <!-- A policy in which the device limits the amount of HTML text that can be displayed for a
+        given message [CHAR LIMIT=50] -->
+    <string name="policy_html_truncation">Restrict HTML email size</string>
+    <!-- A policy in which the device requires device or sd card encryption [CHAR LIMIT=50] -->
+    <string name="policy_require_sd_encryption">Require SD card encryption</string>
+
+    <!-- The following are a list of policies that the user's server requires and that are
+         in force.  We will list them separated by commas, as required -->
+    <!-- A policy in which attachments aren't allowed to be downloaded [CHAR LIMIT=50] -->
+    <string name="policy_dont_allow_attachments">Don\'t allow attachments</string>
+    <!-- A policy in which the device restricts the size of attachments that can be downloaded
+        [CHAR LIMIT=50] -->
+    <string name="policy_max_attachment_size">Restrict attachment size</string>
+    <!-- A policy in which the device may only sync manually while roaming [CHAR LIMIT=50] -->
+    <string name="policy_require_manual_sync_roaming">Only allow manual sync while roaming</string>
+
+    <!-- The following is a policy that may or not be supported on a particular device -->
+    <!-- A policy in which the device requires device or sd card encryption [CHAR LIMIT=50] -->
+    <string name="policy_require_encryption">Require device encryption</string>
+
+
+    <!--  The window length strings below MUST remain in sync with those in com.android.email -->
+    <!-- In account setup options & account settings screens (exchange), sync window length; this
+        implies loading a 'reasonable' number of messages [CHAR LIMIT=25] -->
+    <string name="account_setup_options_mail_window_auto">Automatic</string>
+    <!-- A sync window length setting (i.e. load messages this far back) [CHAR LIMIT=25]  -->
+    <string name="account_setup_options_mail_window_1day">One day</string>
+    <!-- A sync window length setting (i.e. load messages this far back) [CHAR LIMIT=25]  -->
+    <string name="account_setup_options_mail_window_3days">Three days</string>
+    <!-- A sync window length setting (i.e. load messages this far back) [CHAR LIMIT=25]  -->
+    <string name="account_setup_options_mail_window_1week">One week</string>
+    <!-- A sync window length setting (i.e. load messages this far back) [CHAR LIMIT=25]  -->
+    <string name="account_setup_options_mail_window_2weeks">Two weeks</string>
+    <!-- A sync window length setting (i.e. load messages this far back) [CHAR LIMIT=25]  -->
+    <string name="account_setup_options_mail_window_1month">One month</string>
+    <!-- A sync window length setting (i.e. load messages this far back) [CHAR LIMIT=25]  -->
+    <string name="account_setup_options_mail_window_all">All</string>
+</resources>
diff --git a/exchange2/res/xml/syncadapter_calendar.xml b/exchange2/res/xml/syncadapter_calendar.xml
new file mode 100644
index 0000000..a6c0fc6
--- /dev/null
+++ b/exchange2/res/xml/syncadapter_calendar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the SyncAdapter. -->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+    android:contentAuthority="com.android.calendar"
+    android:accountType="com.android.exchange"
+/>
diff --git a/exchange2/res/xml/syncadapter_contacts.xml b/exchange2/res/xml/syncadapter_contacts.xml
new file mode 100644
index 0000000..4691aee
--- /dev/null
+++ b/exchange2/res/xml/syncadapter_contacts.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the SyncAdapter. -->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+    android:contentAuthority="com.android.contacts"
+    android:accountType="com.android.exchange"
+/>
diff --git a/exchange2/res/xml/syncadapter_email.xml b/exchange2/res/xml/syncadapter_email.xml
new file mode 100644
index 0000000..c7ca850
--- /dev/null
+++ b/exchange2/res/xml/syncadapter_email.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the SyncAdapter. -->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+    android:contentAuthority="com.android.email.provider"
+    android:accountType="com.android.exchange"
+    android:supportsUploading="false"
+/>
diff --git a/exchange2/src/com/android/exchange/AbstractSyncService.java b/exchange2/src/com/android/exchange/AbstractSyncService.java
new file mode 100644
index 0000000..6ccc7c3
--- /dev/null
+++ b/exchange2/src/com/android/exchange/AbstractSyncService.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.HostAuth;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.utility.FileLogger;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Base class for all protocol services SyncManager (extends Service, implements
+ * Runnable) instantiates subclasses to run a sync (either timed, or push, or
+ * mail placed in outbox, etc.) EasSyncService is currently implemented; my goal
+ * would be to move IMAP to this structure when it comes time to introduce push
+ * functionality.
+ */
+public abstract class AbstractSyncService implements Runnable {
+
+    public String TAG = "AbstractSyncService";
+
+    public static final int SECONDS = 1000;
+    public static final int MINUTES = 60*SECONDS;
+    public static final int HOURS = 60*MINUTES;
+    public static final int DAYS = 24*HOURS;
+
+    public static final int CONNECT_TIMEOUT = 30*SECONDS;
+    public static final int NETWORK_WAIT = 15*SECONDS;
+
+    public static final String EAS_PROTOCOL = "eas";
+    public static final int EXIT_DONE = 0;
+    public static final int EXIT_IO_ERROR = 1;
+    public static final int EXIT_LOGIN_FAILURE = 2;
+    public static final int EXIT_EXCEPTION = 3;
+    public static final int EXIT_SECURITY_FAILURE = 4;
+    public static final int EXIT_ACCESS_DENIED = 5;
+
+    public Mailbox mMailbox;
+    protected long mMailboxId;
+    protected int mExitStatus = EXIT_EXCEPTION;
+    protected String mMailboxName;
+    public Account mAccount;
+    public Context mContext;
+    public int mChangeCount = 0;
+    public volatile int mSyncReason = 0;
+    protected volatile boolean mStop = false;
+    protected volatile Thread mThread;
+    protected final Object mSynchronizer = new Object();
+
+    protected volatile long mRequestTime = 0;
+    protected LinkedBlockingQueue<Request> mRequestQueue = new LinkedBlockingQueue<Request>();
+
+    /**
+     * Sent by SyncManager to request that the service stop itself cleanly
+     */
+    public abstract void stop();
+
+    /**
+     * Sent by SyncManager to indicate that an alarm has fired for this service, and that its
+     * pending (network) operation has timed out. The service is NOT automatically stopped,
+     * although the behavior is service dependent.
+     *
+     * @return true if the operation was stopped normally; false if the thread needed to be
+     * interrupted.
+     */
+    public abstract boolean alarm();
+
+    /**
+     * Sent by SyncManager to request that the service reset itself cleanly; the meaning of this
+     * operation is service dependent.
+     */
+    public abstract void reset();
+
+    /**
+     * Called to validate an account; abstract to allow each protocol to do what
+     * is necessary. For consistency with the Email app's original
+     * functionality, success is indicated by a failure to throw an Exception
+     * (ugh). Parameters are self-explanatory
+     *
+     * @param hostAuth
+     * @return a Bundle containing a result code and, depending on the result, a PolicySet or an
+     * error message
+     */
+    public abstract Bundle validateAccount(HostAuth hostAuth, Context context);
+
+    public AbstractSyncService(Context _context, Mailbox _mailbox) {
+        mContext = _context;
+        mMailbox = _mailbox;
+        mMailboxId = _mailbox.mId;
+        mMailboxName = _mailbox.mServerId;
+        mAccount = Account.restoreAccountWithId(_context, _mailbox.mAccountKey);
+    }
+
+    // Will be required when subclasses are instantiated by name
+    public AbstractSyncService(String prefix) {
+    }
+
+    /**
+     * The UI can call this static method to perform account validation.  This method wraps each
+     * protocol's validateAccount method.   Arguments are self-explanatory, except where noted.
+     *
+     * @param klass the protocol class (EasSyncService.class for example)
+     * @param hostAuth
+     * @param context
+     * @return a Bundle containing a result code and, depending on the result, a PolicySet or an
+     * error message
+     */
+    public static Bundle validate(Class<? extends AbstractSyncService> klass,
+            HostAuth hostAuth, Context context) {
+        AbstractSyncService svc;
+        try {
+            svc = klass.newInstance();
+            return svc.validateAccount(hostAuth, context);
+        } catch (IllegalAccessException e) {
+        } catch (InstantiationException e) {
+        }
+        return null;
+    }
+
+    public static class ValidationResult {
+        static final int NO_FAILURE = 0;
+        static final int CONNECTION_FAILURE = 1;
+        static final int VALIDATION_FAILURE = 2;
+        static final int EXCEPTION = 3;
+
+        static final ValidationResult succeeded = new ValidationResult(true, NO_FAILURE, null);
+        boolean success;
+        int failure = NO_FAILURE;
+        String reason = null;
+        Exception exception = null;
+
+        ValidationResult(boolean _success, int _failure, String _reason) {
+            success = _success;
+            failure = _failure;
+            reason = _reason;
+        }
+
+        ValidationResult(boolean _success) {
+            success = _success;
+        }
+
+        ValidationResult(Exception e) {
+            success = false;
+            failure = EXCEPTION;
+            exception = e;
+        }
+
+        public boolean isSuccess() {
+            return success;
+        }
+
+        public String getReason() {
+            return reason;
+        }
+    }
+
+    public boolean isStopped() {
+        return mStop;
+    }
+
+    public Object getSynchronizer() {
+        return mSynchronizer;
+    }
+
+    /**
+     * Convenience methods to do user logging (i.e. connection activity).  Saves a bunch of
+     * repetitive code.
+     */
+    public void userLog(String string, int code, String string2) {
+        if (Eas.USER_LOG) {
+            userLog(string + code + string2);
+        }
+    }
+
+    public void userLog(String string, int code) {
+        if (Eas.USER_LOG) {
+            userLog(string + code);
+        }
+    }
+
+    public void userLog(String str, Exception e) {
+        if (Eas.USER_LOG) {
+            Log.e(TAG, str, e);
+        } else {
+            Log.e(TAG, str + e);
+        }
+        if (Eas.FILE_LOG) {
+            FileLogger.log(e);
+        }
+    }
+
+    /**
+     * Standard logging for EAS.
+     * If user logging is active, we concatenate any arguments and log them using Log.d
+     * We also check for file logging, and log appropriately
+     * @param strings strings to concatenate and log
+     */
+    public void userLog(String ...strings) {
+        if (Eas.USER_LOG) {
+            String logText;
+            if (strings.length == 1) {
+                logText = strings[0];
+            } else {
+                StringBuilder sb = new StringBuilder(64);
+                for (String string: strings) {
+                    sb.append(string);
+                }
+                logText = sb.toString();
+            }
+            Log.d(TAG, logText);
+            if (Eas.FILE_LOG) {
+                FileLogger.log(TAG, logText);
+            }
+        }
+    }
+
+    /**
+     * Error log is used for serious issues that should always be logged
+     * @param str the string to log
+     */
+    public void errorLog(String str) {
+        Log.e(TAG, str);
+        if (Eas.FILE_LOG) {
+            FileLogger.log(TAG, str);
+        }
+    }
+
+    /**
+     * Waits for up to 10 seconds for network connectivity; returns whether or not there is
+     * network connectivity.
+     *
+     * @return whether there is network connectivity
+     */
+    public boolean hasConnectivity() {
+        ConnectivityManager cm =
+                (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        int tries = 0;
+        while (tries++ < 1) {
+            // Use the same test as in ExchangeService#waitForConnectivity
+            // TODO: Create common code for this test in emailcommon
+            NetworkInfo info = cm.getActiveNetworkInfo();
+            if (info != null) {
+                return true;
+            }
+            try {
+                Thread.sleep(10*SECONDS);
+            } catch (InterruptedException e) {
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Request handling (common functionality)
+     * Can be overridden if desired
+     */
+
+    public void addRequest(Request req) {
+        mRequestQueue.offer(req);
+    }
+
+    public void removeRequest(Request req) {
+        mRequestQueue.remove(req);
+    }
+
+    public boolean hasPendingRequests() {
+        return !mRequestQueue.isEmpty();
+    }
+
+    public void clearRequests() {
+        mRequestQueue.clear();
+    }
+}
diff --git a/exchange2/src/com/android/exchange/CalendarSyncAdapterService.java b/exchange2/src/com/android/exchange/CalendarSyncAdapterService.java
new file mode 100644
index 0000000..5ff03b3
--- /dev/null
+++ b/exchange2/src/com/android/exchange/CalendarSyncAdapterService.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import android.accounts.Account;
+import android.accounts.OperationCanceledException;
+import android.app.Service;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.provider.CalendarContract.Events;
+import android.util.Log;
+
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.Mailbox;
+
+public class CalendarSyncAdapterService extends Service {
+    private static final String TAG = "EAS CalendarSyncAdapterService";
+    private static SyncAdapterImpl sSyncAdapter = null;
+    private static final Object sSyncAdapterLock = new Object();
+
+    private static final String ACCOUNT_AND_TYPE_CALENDAR =
+        MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_CALENDAR;
+    private static final String DIRTY_IN_ACCOUNT =
+        Events.DIRTY + "=1 AND " + Events.ACCOUNT_NAME + "=?";
+    private static final String[] ID_SYNC_KEY_PROJECTION =
+        new String[] {MailboxColumns.ID, MailboxColumns.SYNC_KEY};
+    private static final int ID_SYNC_KEY_MAILBOX_ID = 0;
+    private static final int ID_SYNC_KEY_SYNC_KEY = 1;
+
+    public CalendarSyncAdapterService() {
+        super();
+    }
+
+    private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
+        private Context mContext;
+
+        public SyncAdapterImpl(Context context) {
+            super(context, true /* autoInitialize */);
+            mContext = context;
+        }
+
+        @Override
+        public void onPerformSync(Account account, Bundle extras,
+                String authority, ContentProviderClient provider, SyncResult syncResult) {
+            try {
+                CalendarSyncAdapterService.performSync(mContext, account, extras,
+                        authority, provider, syncResult);
+            } catch (OperationCanceledException e) {
+            }
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        synchronized (sSyncAdapterLock) {
+            if (sSyncAdapter == null) {
+                sSyncAdapter = new SyncAdapterImpl(getApplicationContext());
+            }
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return sSyncAdapter.getSyncAdapterBinder();
+    }
+
+    /**
+     * Partial integration with system SyncManager; we tell our EAS ExchangeService to start a
+     * calendar sync when we get the signal from SyncManager.
+     * The missing piece at this point is integration with the push/ping mechanism in EAS; this will
+     * be put in place at a later time.
+     */
+    private static void performSync(Context context, Account account, Bundle extras,
+            String authority, ContentProviderClient provider, SyncResult syncResult)
+            throws OperationCanceledException {
+        ContentResolver cr = context.getContentResolver();
+        boolean logging = Eas.USER_LOG;
+        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
+            Cursor c = cr.query(Events.CONTENT_URI,
+                    new String[] {Events._ID}, DIRTY_IN_ACCOUNT, new String[] {account.name}, null);
+            try {
+                if (!c.moveToFirst()) {
+                    if (logging) {
+                        Log.d(TAG, "No changes for " + account.name);
+                    }
+                    return;
+                }
+            } finally {
+                c.close();
+            }
+        }
+
+        // Find the (EmailProvider) account associated with this email address
+        Cursor accountCursor =
+            cr.query(com.android.emailcommon.provider.Account.CONTENT_URI,
+                    EmailContent.ID_PROJECTION, AccountColumns.EMAIL_ADDRESS + "=?",
+                    new String[] {account.name}, null);
+        try {
+            if (accountCursor.moveToFirst()) {
+                long accountId = accountCursor.getLong(0);
+                // Now, find the calendar mailbox associated with the account
+                Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, ID_SYNC_KEY_PROJECTION,
+                        ACCOUNT_AND_TYPE_CALENDAR, new String[] {Long.toString(accountId)}, null);
+                try {
+                     if (mailboxCursor.moveToFirst()) {
+                        if (logging) {
+                            Log.d(TAG, "Upload sync requested for " + account.name);
+                        }
+                        String syncKey = mailboxCursor.getString(ID_SYNC_KEY_SYNC_KEY);
+                        if ((syncKey == null) || (syncKey.equals("0"))) {
+                            if (logging) {
+                                Log.d(TAG, "Can't sync; mailbox in initial state");
+                            }
+                            return;
+                        }
+                        // Ask for a sync from our sync manager
+                        ExchangeService.serviceRequest(mailboxCursor.getLong(
+                                ID_SYNC_KEY_MAILBOX_ID), ExchangeService.SYNC_UPSYNC);
+                    }
+                } finally {
+                    mailboxCursor.close();
+                }
+            }
+        } finally {
+            accountCursor.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange2/src/com/android/exchange/CalendarSyncEnabler.java b/exchange2/src/com/android/exchange/CalendarSyncEnabler.java
new file mode 100644
index 0000000..5989614
--- /dev/null
+++ b/exchange2/src/com/android/exchange/CalendarSyncEnabler.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import com.android.emailcommon.Logging;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.CalendarContract;
+import android.util.Log;
+
+/**
+ * Utility class to enable Exchange calendar sync for all existing Exchange accounts.
+ *
+ * <p>Exchange calendar was first supported on Froyo.  It wasn't supported on Eclair, which
+ * was the first version that supported Exchange email.
+ *
+ * <p>This class is used only once when the devices is upgraded to Froyo (or later) from Eclair,
+ * to enable calendar sync for all the existing Exchange accounts.
+ */
+public class CalendarSyncEnabler {
+    private final Context mContext;
+
+    public CalendarSyncEnabler(Context context) {
+        this.mContext = context;
+    }
+
+    /**
+     * Enable calendar sync for all the existing exchange accounts, and post a notification if any.
+     */
+    public final void enableEasCalendarSync() {
+        String emailAddresses = enableEasCalendarSyncInternalForTest();
+        if (emailAddresses.length() > 0) {
+            // Exchange account(s) found.
+            showNotificationForTest(emailAddresses.toString());
+        }
+    }
+
+    /**
+     * Enable calendar sync for all the existing exchange accounts
+     *
+     * @return email addresses of the Exchange accounts joined with spaces as delimiters,
+     *     or the empty string if there's no Exchange accounts.
+     */
+    /* package for testing */ final String enableEasCalendarSyncInternalForTest() {
+        StringBuilder emailAddresses = new StringBuilder();
+
+        Account[] exchangeAccounts = AccountManager.get(mContext)
+                .getAccountsByType(Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+        for (Account account : exchangeAccounts) {
+            final String emailAddress = account.name;
+            Log.i(Logging.LOG_TAG, "Enabling Exchange calendar sync for " + emailAddress);
+
+            ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 1);
+            ContentResolver.setSyncAutomatically(account, CalendarContract.AUTHORITY, true);
+
+            // Accumulate addresses for notification.
+            if (emailAddresses.length() > 0) {
+                emailAddresses.append(' ');
+            }
+            emailAddresses.append(emailAddress);
+        }
+        return emailAddresses.toString();
+    }
+
+    // *** Taken from NotificationController
+    public static final int NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED = 2;
+
+    /**
+     * Show the "Exchange calendar added" notification.
+     *
+     * @param emailAddresses space delimited list of email addresses of Exchange accounts.  It'll
+     *     be shown on the notification.
+     */
+    /* package for testing */ void showNotificationForTest(String emailAddresses) {
+        // Launch Calendar app when clicked.
+        PendingIntent launchCalendarPendingIntent = PendingIntent.getActivity(mContext, 0,
+                createLaunchCalendarIntent(), 0);
+
+        String tickerText = mContext.getString(R.string.notification_exchange_calendar_added);
+        Notification n = new Notification(R.drawable.stat_notify_calendar,
+                tickerText, System.currentTimeMillis());
+        n.setLatestEventInfo(mContext, tickerText, emailAddresses, launchCalendarPendingIntent);
+        n.flags = Notification.FLAG_AUTO_CANCEL;
+
+        NotificationManager nm =
+                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        nm.notify(NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED, n);
+    }
+
+    /** @return {@link Intent} to launch the Calendar app. */
+    private Intent createLaunchCalendarIntent() {
+        return new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.calendar/time"));
+    }
+}
diff --git a/exchange2/src/com/android/exchange/CommandStatusException.java b/exchange2/src/com/android/exchange/CommandStatusException.java
new file mode 100644
index 0000000..80b405a
--- /dev/null
+++ b/exchange2/src/com/android/exchange/CommandStatusException.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+/**
+ * ActiveSync command error status definitions (EAS 14.0 and later); these are in addition to the
+ * command-specific errors defined for earlier protocol versions
+ */
+public class CommandStatusException extends EasException {
+    private static final long serialVersionUID = 1L;
+
+    // A status response to an EAS account. Responses < 16 correspond to command-specific errors as
+    // reported by EAS versions < 14.0; responses > 100 correspond to generic errors as reported
+    // by EAS versions 14.0 and greater
+    public final int mStatus;
+    // If the error refers to a specific data item, that item's id (as provided by the server) is
+    // stored here
+    public final String mItemId;
+
+    public static class CommandStatus {
+        private static final long serialVersionUID = 1L;
+
+        // Fatal user/provisioning issues (put on security hold)
+        public static final int USER_DISABLED_FOR_SYNC = 126;
+        public static final int USERS_DISABLED_FOR_SYNC = 127;
+        public static final int USER_ON_LEGACY_SERVER_CANT_SYNC = 128;
+        public static final int DEVICE_QUARANTINED = 129;
+        public static final int ACCESS_DENIED = 130;
+        public static final int USER_ACCOUNT_DISABLED = 131;
+        public static final int NOT_PROVISIONABLE_PARTIAL = 139;
+        public static final int NOT_PROVISIONABLE_LEGACY_DEVICE = 141;
+        public static final int TOO_MANY_PARTNERSHIPS = 177;
+
+        // Sync state problems (bad key, multiple client conflict, etc.)
+        public static final int SYNC_STATE_LOCKED = 133;
+        public static final int SYNC_STATE_CORRUPT = 134;
+        public static final int SYNC_STATE_EXISTS = 135;
+        public static final int SYNC_STATE_INVALID = 136;
+
+        // Soft provisioning errors, we need to send Provision command
+        public static final int NEEDS_PROVISIONING_WIPE = 140;
+        public static final int NEEDS_PROVISIONING = 142;
+        public static final int NEEDS_PROVISIONING_REFRESH = 143;
+        public static final int NEEDS_PROVISIONING_INVALID = 144;
+
+        // WTF issues (really shouldn't happen in our implementation)
+        public static final int WTF_INVALID_COMMAND = 137;
+        public static final int WTF_INVALID_PROTOCOL = 138;
+        public static final int WTF_DEVICE_CLAIMS_EXTERNAL_MANAGEMENT = 145;
+        public static final int WTF_UNKNOWN_ITEM_TYPE = 147;
+        public static final int WTF_REQUIRES_PROXY_WITHOUT_SSL = 148;
+
+        // For SmartReply/SmartForward
+        public static final int ITEM_NOT_FOUND = 150;
+
+        // Transient or possibly transient errors
+        public static final int SERVER_ERROR_RETRY = 111;
+        public static final int SYNC_STATE_NOT_FOUND = 132;
+
+        // String version of error status codes (for logging only)
+        private static final int STATUS_TEXT_START = 101;
+        private static final int STATUS_TEXT_END = 150;
+        private static final String[] STATUS_TEXT = {
+            "InvalidContent", "InvalidWBXML", "InvalidXML", "InvalidDateTime", "InvalidIDCombo",
+            "InvalidIDs", "InvalidMIME", "DeviceIdError", "DeviceTypeError", "ServerError",
+            "ServerErrorRetry", "ADAccessDenied", "Quota", "ServerOffline", "SendQuota",
+            "RecipientUnresolved", "ReplyNotAllowed", "SentPreviously", "NoRecipient", "SendFailed",
+            "ReplyFailed", "AttsTooLarge", "NoMailbox", "CantBeAnonymous", "UserNotFound",
+            "UserDisabled", "NewMailbox", "LegacyMailbox", "DeviceBlocked", "AccessDenied",
+            "AcctDisabled", "SyncStateNF", "SyncStateLocked", "SyncStateCorrupt", "SyncStateExists",
+            "SyncStateInvalid", "BadCommand", "BadVersion", "NotFullyProvisionable", "RemoteWipe",
+            "LegacyDevice", "NotProvisioned", "PolicyRefresh", "BadPolicyKey", "ExternallyManaged",
+            "NoRecurrence", "UnexpectedClass", "RemoteHasNoSSL", "InvalidRequest", "ItemNotFound"
+        };
+
+        public static boolean isNeedsProvisioning(int status) {
+            return (status == CommandStatus.NEEDS_PROVISIONING ||
+                    status == CommandStatus.NEEDS_PROVISIONING_REFRESH ||
+                    status == CommandStatus.NEEDS_PROVISIONING_INVALID ||
+                    status == CommandStatus.NEEDS_PROVISIONING_WIPE);
+        }
+
+        public static boolean isBadSyncKey(int status) {
+            return (status == CommandStatus.SYNC_STATE_CORRUPT ||
+                    status == CommandStatus.SYNC_STATE_INVALID);
+        }
+
+        public static boolean isDeniedAccess(int status) {
+            return (status == CommandStatus.USER_DISABLED_FOR_SYNC ||
+                    status == CommandStatus.USERS_DISABLED_FOR_SYNC ||
+                    status == CommandStatus.USER_ON_LEGACY_SERVER_CANT_SYNC ||
+                    status == CommandStatus.DEVICE_QUARANTINED ||
+                    status == CommandStatus.ACCESS_DENIED ||
+                    status == CommandStatus.USER_ACCOUNT_DISABLED ||
+                    status == CommandStatus.NOT_PROVISIONABLE_LEGACY_DEVICE ||
+                    status == CommandStatus.NOT_PROVISIONABLE_PARTIAL ||
+                    status == CommandStatus.TOO_MANY_PARTNERSHIPS);
+        }
+
+        public static boolean isTransientError(int status) {
+            return status == CommandStatus.SYNC_STATE_NOT_FOUND ||
+                status == CommandStatus.SERVER_ERROR_RETRY;
+        }
+
+        public static String toString(int status) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(status);
+            sb.append(" (");
+            if (status < STATUS_TEXT_START || status > STATUS_TEXT_END) {
+                sb.append("unknown");
+            } else {
+                int offset = status - STATUS_TEXT_START;
+                if (offset <= STATUS_TEXT.length) {
+                    sb.append(STATUS_TEXT[offset]);
+                }
+            }
+            sb.append(")");
+            return sb.toString();
+        }
+    }
+
+    public CommandStatusException(int status) {
+        mStatus = status;
+        mItemId = null;
+    }
+
+    public CommandStatusException(int status, String itemId) {
+        mStatus = status;
+        mItemId = itemId;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/ContactsSyncAdapterService.java b/exchange2/src/com/android/exchange/ContactsSyncAdapterService.java
new file mode 100644
index 0000000..97706e7
--- /dev/null
+++ b/exchange2/src/com/android/exchange/ContactsSyncAdapterService.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.Mailbox;
+
+import android.accounts.Account;
+import android.accounts.OperationCanceledException;
+import android.app.Service;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.RawContacts;
+import android.util.Log;
+
+public class ContactsSyncAdapterService extends Service {
+    private static final String TAG = "EAS ContactsSyncAdapterService";
+    private static SyncAdapterImpl sSyncAdapter = null;
+    private static final Object sSyncAdapterLock = new Object();
+
+    private static final String[] ID_PROJECTION = new String[] {"_id"};
+    private static final String ACCOUNT_AND_TYPE_CONTACTS =
+        MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_CONTACTS;
+
+    public ContactsSyncAdapterService() {
+        super();
+    }
+
+    private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
+        private Context mContext;
+
+        public SyncAdapterImpl(Context context) {
+            super(context, true /* autoInitialize */);
+            mContext = context;
+        }
+
+        @Override
+        public void onPerformSync(Account account, Bundle extras,
+                String authority, ContentProviderClient provider, SyncResult syncResult) {
+            try {
+                ContactsSyncAdapterService.performSync(mContext, account, extras,
+                        authority, provider, syncResult);
+            } catch (OperationCanceledException e) {
+            }
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        synchronized (sSyncAdapterLock) {
+            if (sSyncAdapter == null) {
+                sSyncAdapter = new SyncAdapterImpl(getApplicationContext());
+            }
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return sSyncAdapter.getSyncAdapterBinder();
+    }
+
+    private static boolean hasDirtyRows(ContentResolver resolver, Uri uri, String dirtyColumn) {
+        Cursor c = resolver.query(uri, ID_PROJECTION, dirtyColumn + "=1", null, null);
+        try {
+            return c.getCount() > 0;
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Partial integration with system SyncManager; we tell our EAS ExchangeService to start a
+     * contacts sync when we get the signal from SyncManager.
+     * The missing piece at this point is integration with the push/ping mechanism in EAS; this will
+     * be put in place at a later time.
+     */
+    private static void performSync(Context context, Account account, Bundle extras,
+            String authority, ContentProviderClient provider, SyncResult syncResult)
+            throws OperationCanceledException {
+        ContentResolver cr = context.getContentResolver();
+
+        // If we've been asked to do an upload, make sure we've got work to do
+        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
+            Uri uri = RawContacts.CONTENT_URI.buildUpon()
+                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
+                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE)
+                .build();
+            // See if we've got dirty contacts or dirty groups containing our contacts
+            boolean changed = hasDirtyRows(cr, uri, RawContacts.DIRTY);
+            if (!changed) {
+                uri = Groups.CONTENT_URI.buildUpon()
+                    .appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
+                    .appendQueryParameter(RawContacts.ACCOUNT_TYPE,
+                            Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE)
+                    .build();
+                changed = hasDirtyRows(cr, uri, Groups.DIRTY);
+            }
+            if (!changed) {
+                Log.i(TAG, "Upload sync; no changes");
+                return;
+            }
+        }
+
+        // Find the (EmailProvider) account associated with this email address
+        Cursor accountCursor =
+            cr.query(com.android.emailcommon.provider.Account.CONTENT_URI, ID_PROJECTION,
+                AccountColumns.EMAIL_ADDRESS + "=?", new String[] {account.name}, null);
+        try {
+            if (accountCursor.moveToFirst()) {
+                long accountId = accountCursor.getLong(0);
+                // Now, find the contacts mailbox associated with the account
+                Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, ID_PROJECTION,
+                        ACCOUNT_AND_TYPE_CONTACTS, new String[] {Long.toString(accountId)}, null);
+                try {
+                     if (mailboxCursor.moveToFirst()) {
+                        Log.i(TAG, "Contact sync requested for " + account.name);
+                        // Ask for a sync from our sync manager
+                        ExchangeService.serviceRequest(mailboxCursor.getLong(0),
+                                ExchangeService.SYNC_UPSYNC);
+                    }
+                } finally {
+                    mailboxCursor.close();
+                }
+            }
+        } finally {
+            accountCursor.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange2/src/com/android/exchange/Eas.java b/exchange2/src/com/android/exchange/Eas.java
new file mode 100644
index 0000000..9789f43
--- /dev/null
+++ b/exchange2/src/com/android/exchange/Eas.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.util.Log;
+
+import com.android.emailcommon.service.EmailServiceProxy;
+import com.android.emailcommon.service.SyncWindow;
+
+/**
+ * Constants used throughout the EAS implementation are stored here.
+ *
+ */
+public class Eas {
+    // For debugging
+    public static boolean WAIT_DEBUG = false;   // DO NOT CHECK IN WITH THIS SET TO TRUE
+    public static boolean DEBUG = false;         // DO NOT CHECK IN WITH THIS SET TO TRUE
+
+    // The following two are for user logging (the second providing more detail)
+    public static boolean USER_LOG = false;     // DO NOT CHECK IN WITH THIS SET TO TRUE
+    public static boolean PARSER_LOG = false;   // DO NOT CHECK IN WITH THIS SET TO TRUE
+    public static boolean FILE_LOG = false;     // DO NOT CHECK IN WITH THIS SET TO TRUE
+
+    public static final String CLIENT_VERSION = "EAS-1.3";
+    public static final String ACCOUNT_MAILBOX_PREFIX = "__eas";
+
+    // Define our default protocol version as 2.5 (Exchange 2003)
+    public static final String SUPPORTED_PROTOCOL_EX2003 = "2.5";
+    public static final double SUPPORTED_PROTOCOL_EX2003_DOUBLE = 2.5;
+    public static final String SUPPORTED_PROTOCOL_EX2007 = "12.0";
+    public static final double SUPPORTED_PROTOCOL_EX2007_DOUBLE = 12.0;
+    public static final String SUPPORTED_PROTOCOL_EX2007_SP1 = "12.1";
+    public static final double SUPPORTED_PROTOCOL_EX2007_SP1_DOUBLE = 12.1;
+    public static final String SUPPORTED_PROTOCOL_EX2010 = "14.0";
+    public static final double SUPPORTED_PROTOCOL_EX2010_DOUBLE = 14.0;
+    public static final String SUPPORTED_PROTOCOL_EX2010_SP1 = "14.1";
+    public static final double SUPPORTED_PROTOCOL_EX2010_SP1_DOUBLE = 14.1;
+    public static final String DEFAULT_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_EX2003;
+
+    public static final String EXCHANGE_ACCOUNT_MANAGER_TYPE = "com.android.exchange";
+
+    // From EAS spec
+    //                Mail Cal
+    // 0 No filter    Yes  Yes
+    // 1 1 day ago    Yes  No
+    // 2 3 days ago   Yes  No
+    // 3 1 week ago   Yes  No
+    // 4 2 weeks ago  Yes  Yes
+    // 5 1 month ago  Yes  Yes
+    // 6 3 months ago No   Yes
+    // 7 6 months ago No   Yes
+
+    public static final String FILTER_AUTO =  Integer.toString(SyncWindow.SYNC_WINDOW_AUTO);
+    // TODO Rationalize this with SYNC_WINDOW_ALL
+    public static final String FILTER_ALL = "0";
+    public static final String FILTER_1_DAY = Integer.toString(SyncWindow.SYNC_WINDOW_1_DAY);
+    public static final String FILTER_3_DAYS =  Integer.toString(SyncWindow.SYNC_WINDOW_3_DAYS);
+    public static final String FILTER_1_WEEK =  Integer.toString(SyncWindow.SYNC_WINDOW_1_WEEK);
+    public static final String FILTER_2_WEEKS =  Integer.toString(SyncWindow.SYNC_WINDOW_2_WEEKS);
+    public static final String FILTER_1_MONTH =  Integer.toString(SyncWindow.SYNC_WINDOW_1_MONTH);
+    public static final String FILTER_3_MONTHS = "6";
+    public static final String FILTER_6_MONTHS = "7";
+
+    public static final String BODY_PREFERENCE_TEXT = "1";
+    public static final String BODY_PREFERENCE_HTML = "2";
+
+    public static final String MIME_BODY_PREFERENCE_TEXT = "0";
+    public static final String MIME_BODY_PREFERENCE_MIME = "2";
+
+    // For EAS 12, we use HTML, so we want a larger size than in EAS 2.5
+    public static final String EAS12_TRUNCATION_SIZE = "200000";
+    // For EAS 2.5, truncation is a code; the largest is "7", which is 100k
+    public static final String EAS2_5_TRUNCATION_SIZE = "7";
+
+    public static final int FOLDER_STATUS_OK = 1;
+    public static final int FOLDER_STATUS_INVALID_KEY = 9;
+
+    public static final int EXCHANGE_ERROR_NOTIFICATION = 0x10;
+
+    public static void setUserDebug(int state) {
+        // DEBUG takes precedence and is never true in a user build
+        if (!DEBUG) {
+            USER_LOG = (state & EmailServiceProxy.DEBUG_BIT) != 0;
+            PARSER_LOG = (state & EmailServiceProxy.DEBUG_VERBOSE_BIT) != 0;
+            FILE_LOG = (state & EmailServiceProxy.DEBUG_FILE_BIT) != 0;
+            if (FILE_LOG || PARSER_LOG) {
+                USER_LOG = true;
+            }
+            Log.d("Eas Debug", "Logging: " + (USER_LOG ? "User " : "") +
+                    (PARSER_LOG ? "Parser " : "") + (FILE_LOG ? "File" : ""));
+        }
+    }
+
+    static public Double getProtocolVersionDouble(String version) {
+        if (SUPPORTED_PROTOCOL_EX2003.equals(version)) {
+            return SUPPORTED_PROTOCOL_EX2003_DOUBLE;
+        } else if (SUPPORTED_PROTOCOL_EX2007.equals(version)) {
+            return SUPPORTED_PROTOCOL_EX2007_DOUBLE;
+        } if (SUPPORTED_PROTOCOL_EX2007_SP1.equals(version)) {
+            return SUPPORTED_PROTOCOL_EX2007_SP1_DOUBLE;
+        } if (SUPPORTED_PROTOCOL_EX2010.equals(version)) {
+            return SUPPORTED_PROTOCOL_EX2010_DOUBLE;
+        } if (SUPPORTED_PROTOCOL_EX2010_SP1.equals(version)) {
+            return SUPPORTED_PROTOCOL_EX2010_SP1_DOUBLE;
+        }
+        throw new IllegalArgumentException("illegal protocol version");
+    }
+}
diff --git a/src/com/android/exchange/EasAccountService.java b/exchange2/src/com/android/exchange/EasAccountService.java
similarity index 100%
rename from src/com/android/exchange/EasAccountService.java
rename to exchange2/src/com/android/exchange/EasAccountService.java
diff --git a/exchange2/src/com/android/exchange/EasAuthenticationException.java b/exchange2/src/com/android/exchange/EasAuthenticationException.java
new file mode 100644
index 0000000..f5b14b9
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EasAuthenticationException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import java.io.IOException;
+
+/**
+ * Use this to be able to distinguish login (authentication) failures from other I/O
+ * exceptions during a sync, as they are handled very differently.
+ */
+public class EasAuthenticationException extends IOException {
+    private static final long serialVersionUID = 1L;
+
+    EasAuthenticationException() {
+        super();
+    }
+}
diff --git a/exchange2/src/com/android/exchange/EasCertificateRequestor.java b/exchange2/src/com/android/exchange/EasCertificateRequestor.java
new file mode 100644
index 0000000..ebafe44
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EasCertificateRequestor.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.exchange;
+
+import android.security.KeyChain;
+
+import com.android.emailcommon.utility.CertificateRequestor;
+
+/**
+ * A subclass of the {@link CertificateRequestor} so that the Exchange process
+ * can request access to a certificate.
+ *
+ * They {@link KeyChain} API works in such a way that the host
+ * activity requesting the certificate must be running in the process with the UID of who will
+ * actually use the certificate. Since the Exchange process needs to establish connections and use
+ * certificates for EAS accounts, requests for certificates must be delegated by an Activity in this
+ * process.
+ */
+public class EasCertificateRequestor extends CertificateRequestor {
+    // Intentionally blank - no behavior overridden.
+}
diff --git a/exchange2/src/com/android/exchange/EasException.java b/exchange2/src/com/android/exchange/EasException.java
new file mode 100644
index 0000000..e7613d7
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EasException.java
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+public class EasException extends Exception {
+    private static final long serialVersionUID = 5894556952470989968L;
+}
diff --git a/exchange2/src/com/android/exchange/EasOutboxService.java b/exchange2/src/com/android/exchange/EasOutboxService.java
new file mode 100644
index 0000000..9ff1ffc
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EasOutboxService.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.TrafficStats;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.text.TextUtils;
+
+import com.android.emailcommon.TrafficFlags;
+import com.android.emailcommon.internet.Rfc822Output;
+import com.android.emailcommon.mail.MessagingException;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent.Body;
+import com.android.emailcommon.provider.EmailContent.BodyColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.EmailContent.MessageColumns;
+import com.android.emailcommon.provider.EmailContent.SyncColumns;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.service.EmailServiceStatus;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.CommandStatusException.CommandStatus;
+import com.android.exchange.adapter.Parser;
+import com.android.exchange.adapter.Parser.EmptyStreamException;
+import com.android.exchange.adapter.Serializer;
+import com.android.exchange.adapter.Tags;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.InputStreamEntity;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class EasOutboxService extends EasSyncService {
+
+    public static final int SEND_FAILED = 1;
+    public static final String MAILBOX_KEY_AND_NOT_SEND_FAILED =
+        MessageColumns.MAILBOX_KEY + "=? and (" + SyncColumns.SERVER_ID + " is null or " +
+        SyncColumns.SERVER_ID + "!=" + SEND_FAILED + ')';
+    public static final String[] BODY_SOURCE_PROJECTION =
+        new String[] {BodyColumns.SOURCE_MESSAGE_KEY};
+    public static final String WHERE_MESSAGE_KEY = Body.MESSAGE_KEY + "=?";
+
+    // This is a normal email (i.e. not one of the other types)
+    public static final int MODE_NORMAL = 0;
+    // This is a smart reply email
+    public static final int MODE_SMART_REPLY = 1;
+    // This is a smart forward email
+    public static final int MODE_SMART_FORWARD = 2;
+
+    // This needs to be long enough to send the longest reasonable message, without being so long
+    // as to effectively "hang" sending of mail.  The standard 30 second timeout isn't long enough
+    // for pictures and the like.  For now, we'll use 15 minutes, in the knowledge that any socket
+    // failure would probably generate an Exception before timing out anyway
+    public static final int SEND_MAIL_TIMEOUT = 15*MINUTES;
+
+    protected EasOutboxService(Context _context, Mailbox _mailbox) {
+        super(_context, _mailbox);
+    }
+
+    /**
+     * Our own HttpEntity subclass that is able to insert opaque data (in this case the MIME
+     * representation of the message body as stored in a temporary file) into the serializer stream
+     */
+    private static class SendMailEntity extends InputStreamEntity {
+        private final Context mContext;
+        private final FileInputStream mFileStream;
+        private final long mFileLength;
+        private final int mSendTag;
+        private final Message mMessage;
+
+        private static final int[] MODE_TAGS =  new int[] {Tags.COMPOSE_SEND_MAIL,
+            Tags.COMPOSE_SMART_REPLY, Tags.COMPOSE_SMART_FORWARD};
+
+        public SendMailEntity(Context context, FileInputStream instream, long length, int tag,
+                Message message) {
+            super(instream, length);
+            mContext = context;
+            mFileStream = instream;
+            mFileLength = length;
+            mSendTag = tag;
+            mMessage = message;
+        }
+
+        /**
+         * We always return -1 because we don't know the actual length of the POST data (this
+         * causes HttpClient to send the data in "chunked" mode)
+         */
+        @Override
+        public long getContentLength() {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try {
+                // Calculate the overhead for the WBXML data
+                writeTo(baos, false);
+                // Return the actual size that will be sent
+                return baos.size() + mFileLength;
+            } catch (IOException e) {
+                // Just return -1 (unknown)
+            } finally {
+                try {
+                    baos.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+            return -1;
+        }
+
+        @Override
+        public void writeTo(OutputStream outstream) throws IOException {
+            writeTo(outstream, true);
+        }
+
+        /**
+         * Write the message to the output stream
+         * @param outstream the output stream to write
+         * @param withData whether or not the actual data is to be written; true when sending
+         *   mail; false when calculating size only
+         * @throws IOException
+         */
+        public void writeTo(OutputStream outstream, boolean withData) throws IOException {
+            // Not sure if this is possible; the check is taken from the superclass
+            if (outstream == null) {
+                throw new IllegalArgumentException("Output stream may not be null");
+            }
+
+            // We'll serialize directly into the output stream
+            Serializer s = new Serializer(outstream);
+            // Send the appropriate initial tag
+            s.start(mSendTag);
+            // The Message-Id for this message (note that we cannot use the messageId stored in
+            // the message, as EAS 14 limits the length to 40 chars and we use 70+)
+            s.data(Tags.COMPOSE_CLIENT_ID, "SendMail-" + System.nanoTime());
+            // We always save sent mail
+            s.tag(Tags.COMPOSE_SAVE_IN_SENT_ITEMS);
+
+            // If we're using smart reply/forward, we need info about the original message
+            if (mSendTag != Tags.COMPOSE_SEND_MAIL) {
+                OriginalMessageInfo info = getOriginalMessageInfo(mContext, mMessage.mId);
+                if (info != null) {
+                    s.start(Tags.COMPOSE_SOURCE);
+                    // For search results, use the long id (stored in mProtocolSearchInfo); else,
+                    // use folder id/item id combo
+                    if (mMessage.mProtocolSearchInfo != null) {
+                        s.data(Tags.COMPOSE_LONG_ID, mMessage.mProtocolSearchInfo);
+                    } else {
+                        s.data(Tags.COMPOSE_ITEM_ID, info.mItemId);
+                        s.data(Tags.COMPOSE_FOLDER_ID, info.mCollectionId);
+                    }
+                    s.end();  // Tags.COMPOSE_SOURCE
+                }
+            }
+
+            // Start the MIME tag; this is followed by "opaque" data (byte array)
+            s.start(Tags.COMPOSE_MIME);
+            // Send opaque data from the file stream
+            if (withData) {
+                s.opaque(mFileStream, (int)mFileLength);
+            } else {
+                s.opaqueWithoutData((int)mFileLength);
+            }
+            // And we're done
+            s.end().end().done();
+        }
+    }
+
+    private static class SendMailParser extends Parser {
+        private final int mStartTag;
+        private int mStatus;
+
+        public SendMailParser(InputStream in, int startTag) throws IOException {
+            super(in);
+            mStartTag = startTag;
+        }
+
+        public int getStatus() {
+            return mStatus;
+        }
+
+        /**
+         * The only useful info in the SendMail response is the status; we capture and save it
+         */
+        @Override
+        public boolean parse() throws IOException {
+            if (nextTag(START_DOCUMENT) != mStartTag) {
+                throw new IOException();
+            }
+            while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+                if (tag == Tags.COMPOSE_STATUS) {
+                    mStatus = getValueInt();
+                } else {
+                    skipTag();
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * For OriginalMessageInfo, we use the terminology of EAS for the serverId and mailboxId of the
+     * original message
+     */
+    protected static class OriginalMessageInfo {
+        final String mItemId;
+        final String mCollectionId;
+        final String mLongId;
+
+        OriginalMessageInfo(String itemId, String collectionId, String longId) {
+            mItemId = itemId;
+            mCollectionId = collectionId;
+            mLongId = longId;
+        }
+    }
+
+    private void sendCallback(long msgId, String subject, int status) {
+        try {
+            ExchangeService.callback().sendMessageStatus(msgId, subject, status, 0);
+        } catch (RemoteException e) {
+            // It's all good
+        }
+    }
+
+    /*package*/ String generateSmartSendCmd(boolean reply, OriginalMessageInfo info) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(reply ? "SmartReply" : "SmartForward");
+        if (!TextUtils.isEmpty(info.mLongId)) {
+            sb.append("&LongId=");
+            sb.append(Uri.encode(info.mLongId, ":"));
+        } else {
+            sb.append("&ItemId=");
+            sb.append(Uri.encode(info.mItemId, ":"));
+            sb.append("&CollectionId=");
+            sb.append(Uri.encode(info.mCollectionId, ":"));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Get information about the original message that is referenced by the message to be sent; this
+     * information will exist for replies and forwards
+     *
+     * @param context the caller's context
+     * @param msgId the id of the message we're sending
+     * @return a data structure with the serverId and mailboxId of the original message, or null if
+     * either or both of those pieces of information can't be found
+     */
+    private static OriginalMessageInfo getOriginalMessageInfo(Context context, long msgId) {
+        // Note: itemId and collectionId are the terms used by EAS to refer to the serverId and
+        // mailboxId of a Message
+        String itemId = null;
+        String collectionId = null;
+        String longId = null;
+
+        // First, we need to get the id of the reply/forward message
+        String[] cols = Utility.getRowColumns(context, Body.CONTENT_URI,
+                BODY_SOURCE_PROJECTION, WHERE_MESSAGE_KEY,
+                new String[] {Long.toString(msgId)});
+        if (cols != null) {
+            long refId = Long.parseLong(cols[0]);
+            // Then, we need the serverId and mailboxKey of the message
+            cols = Utility.getRowColumns(context, Message.CONTENT_URI, refId,
+                    SyncColumns.SERVER_ID, MessageColumns.MAILBOX_KEY,
+                    MessageColumns.PROTOCOL_SEARCH_INFO);
+            if (cols != null) {
+                itemId = cols[0];
+                long boxId = Long.parseLong(cols[1]);
+                // Then, we need the serverId of the mailbox
+                cols = Utility.getRowColumns(context, Mailbox.CONTENT_URI, boxId,
+                        MailboxColumns.SERVER_ID);
+                if (cols != null) {
+                    collectionId = cols[0];
+                }
+            }
+        }
+        // We need either a longId or both itemId (serverId) and collectionId (mailboxId) to process
+        // a smart reply or a smart forward
+        if (longId != null || (itemId != null && collectionId != null)){
+            return new OriginalMessageInfo(itemId, collectionId, longId);
+        }
+        return null;
+    }
+
+    private void sendFailed(long msgId, int result) {
+        ContentValues cv = new ContentValues();
+        cv.put(SyncColumns.SERVER_ID, SEND_FAILED);
+        Message.update(mContext, Message.CONTENT_URI, msgId, cv);
+        sendCallback(msgId, null, result);
+    }
+
+    /**
+     * Send a single message via EAS
+     * Note that we mark messages SEND_FAILED when there is a permanent failure, rather than an
+     * IOException, which is handled by ExchangeService with retries, backoffs, etc.
+     *
+     * @param cacheDir the cache directory for this context
+     * @param msgId the _id of the message to send
+     * @throws IOException
+     */
+    int sendMessage(File cacheDir, long msgId) throws IOException, MessagingException {
+        // We always return SUCCESS unless the sending error is account-specific (security or
+        // authentication) rather than message-specific; returning anything else will terminate
+        // the Outbox sync! Message-specific errors are marked in the messages themselves.
+        int result = EmailServiceStatus.SUCCESS;
+        // Say we're starting to send this message
+        sendCallback(msgId, null, EmailServiceStatus.IN_PROGRESS);
+        // Create a temporary file (this will hold the outgoing message in RFC822 (MIME) format)
+        File tmpFile = File.createTempFile("eas_", "tmp", cacheDir);
+        try {
+            // Get the message and fail quickly if not found
+            Message msg = Message.restoreMessageWithId(mContext, msgId);
+            if (msg == null) return EmailServiceStatus.MESSAGE_NOT_FOUND;
+
+            // See what kind of outgoing messge this is
+            int flags = msg.mFlags;
+            boolean reply = (flags & Message.FLAG_TYPE_REPLY) != 0;
+            boolean forward = (flags & Message.FLAG_TYPE_FORWARD) != 0;
+            boolean includeQuotedText = (flags & Message.FLAG_NOT_INCLUDE_QUOTED_TEXT) == 0;
+
+            // The reference message and mailbox are called item and collection in EAS
+            OriginalMessageInfo referenceInfo = null;
+            // Respect the sense of the include quoted text flag
+            if (includeQuotedText && (reply || forward)) {
+                referenceInfo = getOriginalMessageInfo(mContext, msgId);
+            }
+            // Generally, we use SmartReply/SmartForward if we've got a good reference
+            boolean smartSend = referenceInfo != null;
+            // But we won't use SmartForward if the account isn't set up for it (currently, we only
+            // use SmartForward for EAS 12.0 or later to avoid creating eml files that are
+            // potentially difficult for the recipient to handle)
+            if (forward && ((mAccount.mFlags & Account.FLAGS_SUPPORTS_SMART_FORWARD) == 0)) {
+                smartSend = false;
+            }
+
+            // Write the message to the temporary file
+            FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
+            Rfc822Output.writeTo(mContext, msgId, fileOutputStream, smartSend, true);
+            fileOutputStream.close();
+
+            // Sending via EAS14 is a whole 'nother kettle of fish
+            boolean isEas14 = (Double.parseDouble(mAccount.mProtocolVersion) >=
+                Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE);
+
+            while (true) {
+                // Get an input stream to our temporary file and create an entity with it
+                FileInputStream fileStream = new FileInputStream(tmpFile);
+                long fileLength = tmpFile.length();
+
+                // The type of entity depends on whether we're using EAS 14
+                HttpEntity inputEntity;
+                // For EAS 14, we need to save the wbxml tag we're using
+                int modeTag = 0;
+                if (isEas14) {
+                    int mode =
+                        !smartSend ? MODE_NORMAL : reply ? MODE_SMART_REPLY : MODE_SMART_FORWARD;
+                    modeTag = SendMailEntity.MODE_TAGS[mode];
+                    inputEntity =
+                        new SendMailEntity(mContext, fileStream, fileLength, modeTag, msg);
+                } else {
+                    inputEntity = new InputStreamEntity(fileStream, fileLength);
+                }
+                // Create the appropriate command and POST it to the server
+                String cmd = "SendMail";
+                if (smartSend) {
+                    // In EAS 14, we don't send itemId and collectionId in the command
+                    if (isEas14) {
+                        cmd = reply ? "SmartReply" : "SmartForward";
+                    } else {
+                        cmd = generateSmartSendCmd(reply, referenceInfo);
+                    }
+                }
+
+                // If we're not EAS 14, add our save-in-sent setting here
+                if (!isEas14) {
+                    cmd += "&SaveInSent=T";
+                }
+                userLog("Send cmd: " + cmd);
+
+                // Finally, post SendMail to the server
+                EasResponse resp = sendHttpClientPost(cmd, inputEntity, SEND_MAIL_TIMEOUT);
+                try {
+                    fileStream.close();
+                    int code = resp.getStatus();
+                    if (code == HttpStatus.SC_OK) {
+                        // HTTP OK before EAS 14 is a thumbs up; in EAS 14, we've got to parse
+                        // the reply
+                        if (isEas14) {
+                            try {
+                                // Try to parse the result
+                                SendMailParser p =
+                                    new SendMailParser(resp.getInputStream(), modeTag);
+                                // If we get here, the SendMail failed; go figure
+                                p.parse();
+                                // The parser holds the status
+                                int status = p.getStatus();
+                                userLog("SendMail error, status: " + status);
+                                if (CommandStatus.isNeedsProvisioning(status)) {
+                                    result = EmailServiceStatus.SECURITY_FAILURE;
+                                } else if (status == CommandStatus.ITEM_NOT_FOUND && smartSend) {
+                                    // This is the retry case for EAS 14; we'll send without "smart"
+                                    // commands next time
+                                    resp.close();
+                                    smartSend = false;
+                                    continue;
+                                }
+                                sendFailed(msgId, result);
+                                return result;
+                            } catch (EmptyStreamException e) {
+                                // This is actually fine; an empty stream means SendMail succeeded
+                            }
+                        }
+
+                        // If we're here, the SendMail command succeeded
+                        userLog("Deleting message...");
+                        // Delete the message from the Outbox and send callback
+                        mContentResolver.delete(
+                                ContentUris.withAppendedId(Message.CONTENT_URI, msgId), null, null);
+                        sendCallback(-1, msg.mSubject, EmailServiceStatus.SUCCESS);
+                        break;
+                    } else if (code == EasSyncService.INTERNAL_SERVER_ERROR_CODE && smartSend) {
+                        // This is the retry case for EAS 12.1 and below; we'll send without "smart"
+                        // commands next time
+                        resp.close();
+                        smartSend = false;
+                    } else {
+                        userLog("Message sending failed, code: " + code);
+                        if (EasResponse.isAuthError(code)) {
+                            result = EmailServiceStatus.LOGIN_FAILED;
+                        } else if (EasResponse.isProvisionError(code)) {
+                            result = EmailServiceStatus.SECURITY_FAILURE;
+                        }
+                        sendFailed(msgId, result);
+                        break;
+                    }
+                } finally {
+                    resp.close();
+                }
+            }
+        } catch (IOException e) {
+            // We catch this just to send the callback
+            sendCallback(msgId, null, EmailServiceStatus.CONNECTION_ERROR);
+            throw e;
+        } finally {
+            // Clean up the temporary file
+            if (tmpFile.exists()) {
+                tmpFile.delete();
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void run() {
+        setupService();
+        // Use SMTP flags for sending mail
+        TrafficStats.setThreadStatsTag(TrafficFlags.getSmtpFlags(mContext, mAccount));
+        File cacheDir = mContext.getCacheDir();
+        try {
+            mDeviceId = ExchangeService.getDeviceId(mContext);
+            // Get a cursor to Outbox messages
+            Cursor c = mContext.getContentResolver().query(Message.CONTENT_URI,
+                    Message.ID_COLUMN_PROJECTION, MAILBOX_KEY_AND_NOT_SEND_FAILED,
+                    new String[] {Long.toString(mMailbox.mId)}, null);
+            try {
+                // Loop through the messages, sending each one
+                while (c.moveToNext()) {
+                    long msgId = c.getLong(Message.ID_COLUMNS_ID_COLUMN);
+                    if (msgId != 0) {
+                        if (Utility.hasUnloadedAttachments(mContext, msgId)) {
+                            // We'll just have to wait on this...
+                            continue;
+                        }
+                        int result = sendMessage(cacheDir, msgId);
+                        // If there's an error, it should stop the service; we will distinguish
+                        // at least between login failures and everything else
+                        if (result == EmailServiceStatus.LOGIN_FAILED) {
+                            mExitStatus = EXIT_LOGIN_FAILURE;
+                            return;
+                        } else if (result == EmailServiceStatus.SECURITY_FAILURE) {
+                            mExitStatus = EXIT_SECURITY_FAILURE;
+                            return;
+                        } else if (result == EmailServiceStatus.REMOTE_EXCEPTION) {
+                            mExitStatus = EXIT_EXCEPTION;
+                            return;
+                        }
+                    }
+                }
+            } finally {
+                c.close();
+            }
+            mExitStatus = EXIT_DONE;
+        } catch (IOException e) {
+            mExitStatus = EXIT_IO_ERROR;
+        } catch (Exception e) {
+            userLog("Exception caught in EasOutboxService", e);
+            mExitStatus = EXIT_EXCEPTION;
+        } finally {
+            userLog(mMailbox.mDisplayName, ": sync finished");
+            userLog("Outbox exited with status ", mExitStatus);
+            ExchangeService.done(this);
+        }
+    }
+
+    /**
+     * Convenience method for adding a Message to an account's outbox
+     * @param context the context of the caller
+     * @param accountId the accountId for the sending account
+     * @param msg the message to send
+     */
+    public static void sendMessage(Context context, long accountId, Message msg) {
+        Mailbox mailbox = Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_OUTBOX);
+        if (mailbox != null) {
+            msg.mMailboxKey = mailbox.mId;
+            msg.mAccountKey = accountId;
+            msg.save(context);
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange2/src/com/android/exchange/EasResponse.java b/exchange2/src/com/android/exchange/EasResponse.java
new file mode 100644
index 0000000..174989e
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EasResponse.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import com.android.emailcommon.utility.EmailClientConnectionManager;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * Encapsulate a response to an HTTP POST
+ */
+public class EasResponse {
+    // MSFT's custom HTTP result code indicating the need to provision
+    static private final int HTTP_NEED_PROVISIONING = 449;
+
+    final HttpResponse mResponse;
+    private final HttpEntity mEntity;
+    private final int mLength;
+    private InputStream mInputStream;
+    private boolean mClosed;
+
+    /**
+     * Whether or not a certificate was requested by the server and missing.
+     * If this is set, it is essentially a 403 whereby the failure was due
+     */
+    private boolean mClientCertRequested = false;
+
+    private EasResponse(HttpResponse response) {
+        mResponse = response;
+        mEntity = (response == null) ? null : mResponse.getEntity();
+        if (mEntity !=  null) {
+            mLength = (int) mEntity.getContentLength();
+        } else {
+            mLength = 0;
+        }
+    }
+
+    public static EasResponse fromHttpRequest(
+            EmailClientConnectionManager connManager, HttpClient client, HttpUriRequest request)
+            throws IOException {
+
+        long reqTime = System.currentTimeMillis();
+        HttpResponse response = client.execute(request);
+        EasResponse result = new EasResponse(response);
+        if (isAuthError(response.getStatusLine().getStatusCode())
+                && connManager.hasDetectedUnsatisfiedCertReq(reqTime)) {
+            result.mClientCertRequested = true;
+            result.mClosed = true;
+        }
+
+        return result;
+    }
+
+    /**
+     * Determine whether an HTTP code represents an authentication error
+     * @param code the HTTP code returned by the server
+     * @return whether or not the code represents an authentication error
+     */
+    public static boolean isAuthError(int code) {
+        return (code == HttpStatus.SC_UNAUTHORIZED) || (code == HttpStatus.SC_FORBIDDEN);
+    }
+
+    /**
+     * Determine whether an HTTP code represents a provisioning error
+     * @param code the HTTP code returned by the server
+     * @return whether or not the code represents an provisioning error
+     */
+    public static boolean isProvisionError(int code) {
+        return (code == HTTP_NEED_PROVISIONING) || (code == HttpStatus.SC_FORBIDDEN);
+    }
+
+    /**
+     * Return an appropriate input stream for the response, either a GZIPInputStream, for
+     * compressed data, or a generic InputStream otherwise
+     * @return the input stream for the response
+     */
+    public InputStream getInputStream() {
+        if (mInputStream != null || mClosed) {
+            throw new IllegalStateException("Can't reuse stream or get closed stream");
+        } else if (mEntity == null) {
+            throw new IllegalStateException("Can't get input stream without entity");
+        }
+        InputStream is = null;
+        try {
+            // Get the default input stream for the entity
+            is = mEntity.getContent();
+            Header ceHeader = mResponse.getFirstHeader("Content-Encoding");
+            if (ceHeader != null) {
+                String encoding = ceHeader.getValue();
+                // If we're gzip encoded, wrap appropriately
+                if (encoding.toLowerCase().equals("gzip")) {
+                    is = new GZIPInputStream(is);
+                }
+            }
+        } catch (IllegalStateException e1) {
+        } catch (IOException e1) {
+        }
+        mInputStream = is;
+        return is;
+    }
+
+    public boolean isEmpty() {
+        return mLength == 0;
+    }
+
+    public int getStatus() {
+        return mClientCertRequested
+                ? HttpStatus.SC_UNAUTHORIZED
+                : mResponse.getStatusLine().getStatusCode();
+    }
+
+    public boolean isMissingCertificate() {
+        return mClientCertRequested;
+    }
+
+    public Header getHeader(String name) {
+        return (mResponse == null) ? null : mResponse.getFirstHeader(name);
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    public void close() {
+        if (!mClosed) {
+            if (mEntity != null) {
+                try {
+                    mEntity.consumeContent();
+                } catch (IOException e) {
+                    // No harm, no foul
+                }
+            }
+            if (mInputStream instanceof GZIPInputStream) {
+                try {
+                    mInputStream.close();
+                } catch (IOException e) {
+                    // We tried
+                }
+            }
+            mClosed = true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange2/src/com/android/exchange/EasSyncService.java b/exchange2/src/com/android/exchange/EasSyncService.java
new file mode 100644
index 0000000..f1e544d
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EasSyncService.java
@@ -0,0 +1,1975 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Entity;
+import android.database.Cursor;
+import android.net.TrafficStats;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.CalendarContract.Attendees;
+import android.provider.CalendarContract.Events;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.emailcommon.TrafficFlags;
+import com.android.emailcommon.mail.Address;
+import com.android.emailcommon.mail.MeetingInfo;
+import com.android.emailcommon.mail.MessagingException;
+import com.android.emailcommon.mail.PackedString;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.EmailContent.MessageColumns;
+import com.android.emailcommon.provider.EmailContent.SyncColumns;
+import com.android.emailcommon.provider.HostAuth;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.provider.Policy;
+import com.android.emailcommon.provider.ProviderUnavailableException;
+import com.android.emailcommon.service.EmailServiceConstants;
+import com.android.emailcommon.service.EmailServiceProxy;
+import com.android.emailcommon.service.EmailServiceStatus;
+import com.android.emailcommon.service.PolicyServiceProxy;
+import com.android.emailcommon.utility.EmailClientConnectionManager;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.CommandStatusException.CommandStatus;
+import com.android.exchange.adapter.AbstractSyncAdapter;
+import com.android.exchange.adapter.AccountSyncAdapter;
+import com.android.exchange.adapter.AttachmentLoader;
+import com.android.exchange.adapter.CalendarSyncAdapter;
+import com.android.exchange.adapter.ContactsSyncAdapter;
+import com.android.exchange.adapter.EmailSyncAdapter;
+import com.android.exchange.adapter.FolderSyncParser;
+import com.android.exchange.adapter.GalParser;
+import com.android.exchange.adapter.MeetingResponseParser;
+import com.android.exchange.adapter.MoveItemsParser;
+import com.android.exchange.adapter.Parser.EmptyStreamException;
+import com.android.exchange.adapter.ProvisionParser;
+import com.android.exchange.adapter.Serializer;
+import com.android.exchange.adapter.SettingsParser;
+import com.android.exchange.adapter.Tags;
+import com.android.exchange.provider.GalResult;
+import com.android.exchange.utility.CalendarUtilities;
+import com.google.common.annotations.VisibleForTesting;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.Thread.State;
+import java.net.URI;
+import java.security.cert.CertificateException;
+
+public class EasSyncService extends AbstractSyncService {
+    // DO NOT CHECK IN SET TO TRUE
+    public static final boolean DEBUG_GAL_SERVICE = false;
+
+    protected static final String PING_COMMAND = "Ping";
+    // Command timeout is the the time allowed for reading data from an open connection before an
+    // IOException is thrown.  After a small added allowance, our watchdog alarm goes off (allowing
+    // us to detect a silently dropped connection).  The allowance is defined below.
+    static public final int COMMAND_TIMEOUT = 30*SECONDS;
+    // Connection timeout is the time given to connect to the server before reporting an IOException
+    static private final int CONNECTION_TIMEOUT = 20*SECONDS;
+    // The extra time allowed beyond the COMMAND_TIMEOUT before which our watchdog alarm triggers
+    static private final int WATCHDOG_TIMEOUT_ALLOWANCE = 30*SECONDS;
+
+    static private final String AUTO_DISCOVER_SCHEMA_PREFIX =
+        "http://schemas.microsoft.com/exchange/autodiscover/mobilesync/";
+    static private final String AUTO_DISCOVER_PAGE = "/autodiscover/autodiscover.xml";
+    static protected final int EAS_REDIRECT_CODE = 451;
+
+    static public final int INTERNAL_SERVER_ERROR_CODE = 500;
+
+    static public final String EAS_12_POLICY_TYPE = "MS-EAS-Provisioning-WBXML";
+    static public final String EAS_2_POLICY_TYPE = "MS-WAP-Provisioning-XML";
+
+    static public final int MESSAGE_FLAG_MOVED_MESSAGE = 1 << Message.FLAG_SYNC_ADAPTER_SHIFT;
+    // The amount of time we allow for a thread to release its post lock after receiving an alert
+    static private final int POST_LOCK_TIMEOUT = 10*SECONDS;
+
+    // The EAS protocol Provision status for "we implement all of the policies"
+    static private final String PROVISION_STATUS_OK = "1";
+    // The EAS protocol Provision status meaning "we partially implement the policies"
+    static private final String PROVISION_STATUS_PARTIAL = "2";
+
+    static /*package*/ final String DEVICE_TYPE = "Android";
+    static final String USER_AGENT = DEVICE_TYPE + '/' + Build.VERSION.RELEASE + '-' +
+        Eas.CLIENT_VERSION;
+
+    // Maximum number of times we'll allow a sync to "loop" with MoreAvailable true before
+    // forcing it to stop.  This number has been determined empirically.
+    static private final int MAX_LOOPING_COUNT = 100;
+    // Reasonable default
+    public String mProtocolVersion = Eas.DEFAULT_PROTOCOL_VERSION;
+    public Double mProtocolVersionDouble;
+    protected String mDeviceId = null;
+    @VisibleForTesting
+    String mAuthString = null;
+    @VisibleForTesting
+    String mUserString = null;
+    @VisibleForTesting
+    String mBaseUriString = null;
+    public String mHostAddress;
+    public String mUserName;
+    public String mPassword;
+
+    // The HttpPost in progress
+    private volatile HttpPost mPendingPost = null;
+    // Whether a POST was aborted due to alarm (watchdog alarm)
+    protected boolean mPostAborted = false;
+    // Whether a POST was aborted due to reset
+    protected boolean mPostReset = false;
+
+    // The parameters for the connection must be modified through setConnectionParameters
+    private boolean mSsl = true;
+    private boolean mTrustSsl = false;
+    private String mClientCertAlias = null;
+
+    public ContentResolver mContentResolver;
+    // Whether or not the sync service is valid (usable)
+    public boolean mIsValid = true;
+
+    // Whether the most recent upsync failed (status 7)
+    public boolean mUpsyncFailed = false;
+
+    protected EasSyncService(Context _context, Mailbox _mailbox) {
+        super(_context, _mailbox);
+        mContentResolver = _context.getContentResolver();
+        if (mAccount == null) {
+            mIsValid = false;
+            return;
+        }
+        HostAuth ha = HostAuth.restoreHostAuthWithId(_context, mAccount.mHostAuthKeyRecv);
+        if (ha == null) {
+            mIsValid = false;
+            return;
+        }
+        mSsl = (ha.mFlags & HostAuth.FLAG_SSL) != 0;
+        mTrustSsl = (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0;
+    }
+
+    private EasSyncService(String prefix) {
+        super(prefix);
+    }
+
+    public EasSyncService() {
+        this("EAS Validation");
+    }
+
+    public static EasSyncService getServiceForMailbox(Context context, Mailbox m) {
+        switch(m.mType) {
+            case Mailbox.TYPE_EAS_ACCOUNT_MAILBOX:
+                return new EasAccountService(context, m);
+            case Mailbox.TYPE_OUTBOX:
+                return new EasOutboxService(context, m);
+            default:
+                return new EasSyncService(context, m);
+        }
+    }
+
+    /**
+     * Try to wake up a sync thread that is waiting on an HttpClient POST and has waited past its
+     * socket timeout without having thrown an Exception
+     *
+     * @return true if the POST was successfully stopped; false if we've failed and interrupted
+     * the thread
+     */
+    @Override
+    public boolean alarm() {
+        HttpPost post;
+        if (mThread == null) return true;
+        String threadName = mThread.getName();
+
+        // Synchronize here so that we are guaranteed to have valid mPendingPost and mPostLock
+        // executePostWithTimeout (which executes the HttpPost) also uses this lock
+        synchronized(getSynchronizer()) {
+            // Get a reference to the current post lock
+            post = mPendingPost;
+            if (post != null) {
+                if (Eas.USER_LOG) {
+                    URI uri = post.getURI();
+                    if (uri != null) {
+                        String query = uri.getQuery();
+                        if (query == null) {
+                            query = "POST";
+                        }
+                        userLog(threadName, ": Alert, aborting ", query);
+                    } else {
+                        userLog(threadName, ": Alert, no URI?");
+                    }
+                }
+                // Abort the POST
+                mPostAborted = true;
+                post.abort();
+            } else {
+                // If there's no POST, we're done
+                userLog("Alert, no pending POST");
+                return true;
+            }
+        }
+
+        // Wait for the POST to finish
+        try {
+            Thread.sleep(POST_LOCK_TIMEOUT);
+        } catch (InterruptedException e) {
+        }
+
+        State s = mThread.getState();
+        if (Eas.USER_LOG) {
+            userLog(threadName + ": State = " + s.name());
+        }
+
+        synchronized (getSynchronizer()) {
+            // If the thread is still hanging around and the same post is pending, let's try to
+            // stop the thread with an interrupt.
+            if ((s != State.TERMINATED) && (mPendingPost != null) && (mPendingPost == post)) {
+                mStop = true;
+                mThread.interrupt();
+                userLog("Interrupting...");
+                // Let the caller know we had to interrupt the thread
+                return false;
+            }
+        }
+        // Let the caller know that the alarm was handled normally
+        return true;
+    }
+
+    @Override
+    public void reset() {
+        synchronized(getSynchronizer()) {
+            if (mPendingPost != null) {
+                URI uri = mPendingPost.getURI();
+                if (uri != null) {
+                    String query = uri.getQuery();
+                    if (query.startsWith("Cmd=Ping")) {
+                        userLog("Reset, aborting Ping");
+                        mPostReset = true;
+                        mPendingPost.abort();
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void stop() {
+        mStop = true;
+        synchronized(getSynchronizer()) {
+            if (mPendingPost != null) {
+                mPendingPost.abort();
+            }
+        }
+    }
+
+    @Override
+    public void addRequest(Request request) {
+        // Don't allow duplicates of requests; just refuse them
+        if (mRequestQueue.contains(request)) return;
+        // Add the request
+        super.addRequest(request);
+    }
+
+    void setupProtocolVersion(EasSyncService service, Header versionHeader)
+            throws MessagingException {
+        // The string is a comma separated list of EAS versions in ascending order
+        // e.g. 1.0,2.0,2.5,12.0,12.1,14.0,14.1
+        String supportedVersions = versionHeader.getValue();
+        userLog("Server supports versions: ", supportedVersions);
+        String[] supportedVersionsArray = supportedVersions.split(",");
+        String ourVersion = null;
+        // Find the most recent version we support
+        for (String version: supportedVersionsArray) {
+            if (version.equals(Eas.SUPPORTED_PROTOCOL_EX2003) ||
+                    version.equals(Eas.SUPPORTED_PROTOCOL_EX2007) ||
+                    version.equals(Eas.SUPPORTED_PROTOCOL_EX2007_SP1) ||
+                    version.equals(Eas.SUPPORTED_PROTOCOL_EX2010) ||
+                    version.equals(Eas.SUPPORTED_PROTOCOL_EX2010_SP1)) {
+                ourVersion = version;
+            }
+        }
+        // If we don't support any of the servers supported versions, throw an exception here
+        // This will cause validation to fail
+        if (ourVersion == null) {
+            Log.w(TAG, "No supported EAS versions: " + supportedVersions);
+            throw new MessagingException(MessagingException.PROTOCOL_VERSION_UNSUPPORTED);
+        } else {
+            // Debug code for testing EAS 14.0; disables support for EAS 14.1
+            // "adb shell setprop log.tag.Exchange14 VERBOSE"
+            if (ourVersion.equals(Eas.SUPPORTED_PROTOCOL_EX2010_SP1) &&
+                    Log.isLoggable("Exchange14", Log.VERBOSE)) {
+                ourVersion = Eas.SUPPORTED_PROTOCOL_EX2010;
+            }
+            service.mProtocolVersion = ourVersion;
+            service.mProtocolVersionDouble = Eas.getProtocolVersionDouble(ourVersion);
+            Account account = service.mAccount;
+            if (account != null) {
+                account.mProtocolVersion = ourVersion;
+                // Fixup search flags, if they're not set
+                if (service.mProtocolVersionDouble >= 12.0 &&
+                        (account.mFlags & Account.FLAGS_SUPPORTS_SEARCH) == 0) {
+                    if (account.isSaved()) {
+                        ContentValues cv = new ContentValues();
+                        account.mFlags |=
+                            Account.FLAGS_SUPPORTS_GLOBAL_SEARCH + Account.FLAGS_SUPPORTS_SEARCH;
+                        cv.put(AccountColumns.FLAGS, account.mFlags);
+                        account.update(service.mContext, cv);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Create an EasSyncService for the specified account
+     *
+     * @param context the caller's context
+     * @param account the account
+     * @return the service, or null if the account is on hold or hasn't been initialized
+     */
+    public static EasSyncService setupServiceForAccount(Context context, Account account) {
+        // Just return null if we're on security hold
+        if ((account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0) {
+            return null;
+        }
+        // If there's no protocol version, we're not initialized
+        String protocolVersion = account.mProtocolVersion;
+        if (protocolVersion == null) {
+            return null;
+        }
+        EasSyncService svc = new EasSyncService("OutOfBand");
+        HostAuth ha = HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv);
+        svc.mProtocolVersion = protocolVersion;
+        svc.mProtocolVersionDouble = Eas.getProtocolVersionDouble(protocolVersion);
+        svc.mContext = context;
+        svc.mHostAddress = ha.mAddress;
+        svc.mUserName = ha.mLogin;
+        svc.mPassword = ha.mPassword;
+        try {
+            svc.setConnectionParameters(
+                    (ha.mFlags & HostAuth.FLAG_SSL) != 0,
+                    (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0,
+                    ha.mClientCertAlias);
+            svc.mDeviceId = ExchangeService.getDeviceId(context);
+        } catch (IOException e) {
+            return null;
+        } catch (CertificateException e) {
+            return null;
+        }
+        svc.mAccount = account;
+        return svc;
+    }
+
+    /**
+     * Get a redirect address and validate against it
+     * @param resp the EasResponse to our POST
+     * @param hostAuth the HostAuth we're using to validate
+     * @return true if we have an updated HostAuth (with redirect address); false otherwise
+     */
+    protected boolean getValidateRedirect(EasResponse resp, HostAuth hostAuth) {
+        Header locHeader = resp.getHeader("X-MS-Location");
+        if (locHeader != null) {
+            String loc;
+            try {
+                loc = locHeader.getValue();
+                // Reset our host address and uncache our base uri
+                mHostAddress = Uri.parse(loc).getHost();
+                mBaseUriString = null;
+                hostAuth.mAddress = mHostAddress;
+                userLog("Redirecting to: " + loc);
+                return true;
+            } catch (RuntimeException e) {
+                // Just don't crash if the Uri is illegal
+            }
+        }
+        return false;
+    }
+
+    private static final int MAX_REDIRECTS = 3;
+    private int mRedirectCount = 0;
+
+    @Override
+    public Bundle validateAccount(HostAuth hostAuth, Context context) {
+        Bundle bundle = new Bundle();
+        int resultCode = MessagingException.NO_ERROR;
+        try {
+            userLog("Testing EAS: ", hostAuth.mAddress, ", ", hostAuth.mLogin,
+                    ", ssl = ", hostAuth.shouldUseSsl() ? "1" : "0");
+            mContext = context;
+            mHostAddress = hostAuth.mAddress;
+            mUserName = hostAuth.mLogin;
+            mPassword = hostAuth.mPassword;
+
+            setConnectionParameters(
+                    hostAuth.shouldUseSsl(),
+                    hostAuth.shouldTrustAllServerCerts(),
+                    hostAuth.mClientCertAlias);
+            mDeviceId = ExchangeService.getDeviceId(context);
+            mAccount = new Account();
+            mAccount.mEmailAddress = hostAuth.mLogin;
+            EasResponse resp = sendHttpClientOptions();
+            try {
+                int code = resp.getStatus();
+                userLog("Validation (OPTIONS) response: " + code);
+                if (code == HttpStatus.SC_OK) {
+                    // No exception means successful validation
+                    Header commands = resp.getHeader("MS-ASProtocolCommands");
+                    Header versions = resp.getHeader("ms-asprotocolversions");
+                    // Make sure we've got the right protocol version set up
+                    try {
+                        if (commands == null || versions == null) {
+                            userLog("OPTIONS response without commands or versions");
+                            // We'll treat this as a protocol exception
+                            throw new MessagingException(0);
+                        }
+                        setupProtocolVersion(this, versions);
+                    } catch (MessagingException e) {
+                        bundle.putInt(EmailServiceProxy.VALIDATE_BUNDLE_RESULT_CODE,
+                                MessagingException.PROTOCOL_VERSION_UNSUPPORTED);
+                        return bundle;
+                    }
+
+                    // Run second test here for provisioning failures using FolderSync
+                    userLog("Try folder sync");
+                    // Send "0" as the sync key for new accounts; otherwise, use the current key
+                    String syncKey = "0";
+                    Account existingAccount = Utility.findExistingAccount(
+                            context, -1L, hostAuth.mAddress, hostAuth.mLogin);
+                    if (existingAccount != null && existingAccount.mSyncKey != null) {
+                        syncKey = existingAccount.mSyncKey;
+                    }
+                    Serializer s = new Serializer();
+                    s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY).text(syncKey)
+                        .end().end().done();
+                    resp = sendHttpClientPost("FolderSync", s.toByteArray());
+                    code = resp.getStatus();
+                    // Handle HTTP error responses accordingly
+                    if (code == HttpStatus.SC_FORBIDDEN) {
+                        // For validation only, we take 403 as ACCESS_DENIED (the account isn't
+                        // authorized, possibly due to device type)
+                        resultCode = MessagingException.ACCESS_DENIED;
+                    } else if (EasResponse.isProvisionError(code)) {
+                        // The device needs to have security policies enforced
+                        throw new CommandStatusException(CommandStatus.NEEDS_PROVISIONING);
+                    } else if (code == HttpStatus.SC_NOT_FOUND) {
+                        // We get a 404 from OWA addresses (which are NOT EAS addresses)
+                        resultCode = MessagingException.PROTOCOL_VERSION_UNSUPPORTED;
+                    } else if (code == HttpStatus.SC_UNAUTHORIZED) {
+                        resultCode = resp.isMissingCertificate()
+                                ? MessagingException.CLIENT_CERTIFICATE_REQUIRED
+                                : MessagingException.AUTHENTICATION_FAILED;
+                    } else if (code != HttpStatus.SC_OK) {
+                        if ((code == EAS_REDIRECT_CODE) && (mRedirectCount++ < MAX_REDIRECTS) &&
+                                getValidateRedirect(resp, hostAuth)) {
+                            return validateAccount(hostAuth, context);
+                        }
+                        // Fail generically with anything other than success
+                        userLog("Unexpected response for FolderSync: ", code);
+                        resultCode = MessagingException.UNSPECIFIED_EXCEPTION;
+                    } else {
+                        // We need to parse the result to see if we've got a provisioning issue
+                        // (EAS 14.0 only)
+                        if (!resp.isEmpty()) {
+                            InputStream is = resp.getInputStream();
+                            // Create the parser with statusOnly set to true; we only care about
+                            // seeing if a CommandStatusException is thrown (indicating a
+                            // provisioning failure)
+                            new FolderSyncParser(is, new AccountSyncAdapter(this), true).parse();
+                        }
+                        userLog("Validation successful");
+                    }
+                } else if (EasResponse.isAuthError(code)) {
+                    userLog("Authentication failed");
+                    resultCode = resp.isMissingCertificate()
+                            ? MessagingException.CLIENT_CERTIFICATE_REQUIRED
+                            : MessagingException.AUTHENTICATION_FAILED;
+                } else if (code == INTERNAL_SERVER_ERROR_CODE) {
+                    // For Exchange 2003, this could mean an authentication failure OR server error
+                    userLog("Internal server error");
+                    resultCode = MessagingException.AUTHENTICATION_FAILED_OR_SERVER_ERROR;
+                } else {
+                    if ((code == EAS_REDIRECT_CODE) && (mRedirectCount++ < MAX_REDIRECTS) &&
+                            getValidateRedirect(resp, hostAuth)) {
+                        return validateAccount(hostAuth, context);
+                    }
+                    // TODO Need to catch other kinds of errors (e.g. policy) For now, report code.
+                    userLog("Validation failed, reporting I/O error: ", code);
+                    resultCode = MessagingException.IOERROR;
+                }
+            } catch (CommandStatusException e) {
+                int status = e.mStatus;
+                if (CommandStatus.isNeedsProvisioning(status)) {
+                    // Get the policies and see if we are able to support them
+                    ProvisionParser pp = canProvision(this);
+                    if (pp != null && pp.hasSupportablePolicySet()) {
+                        // Set the proper result code and save the PolicySet in our Bundle
+                        resultCode = MessagingException.SECURITY_POLICIES_REQUIRED;
+                        bundle.putParcelable(EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET,
+                                pp.getPolicy());
+                        if (mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
+                            mAccount.mSecuritySyncKey = pp.getSecuritySyncKey();
+                            if (!sendSettings()) {
+                                userLog("Denied access: ", CommandStatus.toString(status));
+                                resultCode = MessagingException.ACCESS_DENIED;
+                            }
+                        }
+                    } else {
+                        // If not, set the proper code (the account will not be created)
+                        resultCode = MessagingException.SECURITY_POLICIES_UNSUPPORTED;
+                        bundle.putParcelable(EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET,
+                                pp.getPolicy());
+                    }
+                } else if (CommandStatus.isDeniedAccess(status)) {
+                    userLog("Denied access: ", CommandStatus.toString(status));
+                    resultCode = MessagingException.ACCESS_DENIED;
+                } else if (CommandStatus.isTransientError(status)) {
+                    userLog("Transient error: ", CommandStatus.toString(status));
+                    resultCode = MessagingException.IOERROR;
+                } else {
+                    userLog("Unexpected response: ", CommandStatus.toString(status));
+                    resultCode = MessagingException.UNSPECIFIED_EXCEPTION;
+                }
+            } finally {
+                resp.close();
+           }
+        } catch (IOException e) {
+            Throwable cause = e.getCause();
+            if (cause != null && cause instanceof CertificateException) {
+                // This could be because the server's certificate failed to validate.
+                userLog("CertificateException caught: ", e.getMessage());
+                resultCode = MessagingException.GENERAL_SECURITY;
+            }
+            userLog("IOException caught: ", e.getMessage());
+            resultCode = MessagingException.IOERROR;
+        } catch (CertificateException e) {
+            // This occurs if the client certificate the user specified is invalid/inaccessible.
+            userLog("CertificateException caught: ", e.getMessage());
+            resultCode = MessagingException.CLIENT_CERTIFICATE_ERROR;
+        }
+        bundle.putInt(EmailServiceProxy.VALIDATE_BUNDLE_RESULT_CODE, resultCode);
+        return bundle;
+    }
+
+    /**
+     * Gets the redirect location from the HTTP headers and uses that to modify the HttpPost so that
+     * it can be reused
+     *
+     * @param resp the HttpResponse that indicates a redirect (451)
+     * @param post the HttpPost that was originally sent to the server
+     * @return the HttpPost, updated with the redirect location
+     */
+    private HttpPost getRedirect(HttpResponse resp, HttpPost post) {
+        Header locHeader = resp.getFirstHeader("X-MS-Location");
+        if (locHeader != null) {
+            String loc = locHeader.getValue();
+            // If we've gotten one and it shows signs of looking like an address, we try
+            // sending our request there
+            if (loc != null && loc.startsWith("http")) {
+                post.setURI(URI.create(loc));
+                return post;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Send the POST command to the autodiscover server, handling a redirect, if necessary, and
+     * return the HttpResponse.  If we get a 401 (unauthorized) error and we're using the
+     * full email address, try the bare user name instead (e.g. foo instead of foo@bar.com)
+     *
+     * @param client the HttpClient to be used for the request
+     * @param post the HttpPost we're going to send
+     * @param canRetry whether we can retry using the bare name on an authentication failure (401)
+     * @return an HttpResponse from the original or redirect server
+     * @throws IOException on any IOException within the HttpClient code
+     * @throws MessagingException
+     */
+    private EasResponse postAutodiscover(HttpClient client, HttpPost post, boolean canRetry)
+            throws IOException, MessagingException {
+        userLog("Posting autodiscover to: " + post.getURI());
+        EasResponse resp = executePostWithTimeout(client, post, COMMAND_TIMEOUT);
+        int code = resp.getStatus();
+        // On a redirect, try the new location
+        if (code == EAS_REDIRECT_CODE) {
+            post = getRedirect(resp.mResponse, post);
+            if (post != null) {
+                userLog("Posting autodiscover to redirect: " + post.getURI());
+                return executePostWithTimeout(client, post, COMMAND_TIMEOUT);
+            }
+        // 401 (Unauthorized) is for true auth errors when used in Autodiscover
+        } else if (code == HttpStatus.SC_UNAUTHORIZED) {
+            if (canRetry && mUserName.contains("@")) {
+                // Try again using the bare user name
+                int atSignIndex = mUserName.indexOf('@');
+                mUserName = mUserName.substring(0, atSignIndex);
+                cacheAuthUserAndBaseUriStrings();
+                userLog("401 received; trying username: ", mUserName);
+                // Recreate the basic authentication string and reset the header
+                post.removeHeaders("Authorization");
+                post.setHeader("Authorization", mAuthString);
+                return postAutodiscover(client, post, false);
+            }
+            throw new MessagingException(MessagingException.AUTHENTICATION_FAILED);
+        // 403 (and others) we'll just punt on
+        } else if (code != HttpStatus.SC_OK) {
+            // We'll try the next address if this doesn't work
+            userLog("Code: " + code + ", throwing IOException");
+            throw new IOException();
+        }
+        return resp;
+    }
+
+    /**
+     * Convert an EAS server url to a HostAuth host address
+     * @param url a url, as provided by the Exchange server
+     * @return our equivalent host address
+     */
+    protected String autodiscoverUrlToHostAddress(String url) {
+        if (url == null) return null;
+        // We need to extract the server address from a url
+        return Uri.parse(url).getHost();
+    }
+
+    /**
+     * Use the Exchange 2007 AutoDiscover feature to try to retrieve server information using
+     * only an email address and the password
+     *
+     * @param userName the user's email address
+     * @param password the user's password
+     * @return a HostAuth ready to be saved in an Account or null (failure)
+     */
+    public Bundle tryAutodiscover(String userName, String password) throws RemoteException {
+        XmlSerializer s = Xml.newSerializer();
+        ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
+        HostAuth hostAuth = new HostAuth();
+        Bundle bundle = new Bundle();
+        bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
+                MessagingException.NO_ERROR);
+        try {
+            // Build the XML document that's sent to the autodiscover server(s)
+            s.setOutput(os, "UTF-8");
+            s.startDocument("UTF-8", false);
+            s.startTag(null, "Autodiscover");
+            s.attribute(null, "xmlns", AUTO_DISCOVER_SCHEMA_PREFIX + "requestschema/2006");
+            s.startTag(null, "Request");
+            s.startTag(null, "EMailAddress").text(userName).endTag(null, "EMailAddress");
+            s.startTag(null, "AcceptableResponseSchema");
+            s.text(AUTO_DISCOVER_SCHEMA_PREFIX + "responseschema/2006");
+            s.endTag(null, "AcceptableResponseSchema");
+            s.endTag(null, "Request");
+            s.endTag(null, "Autodiscover");
+            s.endDocument();
+            String req = os.toString();
+
+            // Initialize the user name and password
+            mUserName = userName;
+            mPassword = password;
+            // Make sure the authentication string is recreated and cached
+            cacheAuthUserAndBaseUriStrings();
+
+            // Split out the domain name
+            int amp = userName.indexOf('@');
+            // The UI ensures that userName is a valid email address
+            if (amp < 0) {
+                throw new RemoteException();
+            }
+            String domain = userName.substring(amp + 1);
+
+            // There are up to four attempts here; the two URLs that we're supposed to try per the
+            // specification, and up to one redirect for each (handled in postAutodiscover)
+            // Note: The expectation is that, of these four attempts, only a single server will
+            // actually be identified as the autodiscover server.  For the identified server,
+            // we may also try a 2nd connection with a different format (bare name).
+
+            // Try the domain first and see if we can get a response
+            HttpPost post = new HttpPost("https://" + domain + AUTO_DISCOVER_PAGE);
+            setHeaders(post, false);
+            post.setHeader("Content-Type", "text/xml");
+            post.setEntity(new StringEntity(req));
+            HttpClient client = getHttpClient(COMMAND_TIMEOUT);
+            EasResponse resp;
+            try {
+                resp = postAutodiscover(client, post, true /*canRetry*/);
+            } catch (IOException e1) {
+                userLog("IOException in autodiscover; trying alternate address");
+                // We catch the IOException here because we have an alternate address to try
+                post.setURI(URI.create("https://autodiscover." + domain + AUTO_DISCOVER_PAGE));
+                // If we fail here, we're out of options, so we let the outer try catch the
+                // IOException and return null
+                resp = postAutodiscover(client, post, true /*canRetry*/);
+            }
+
+            try {
+                // Get the "final" code; if it's not 200, just return null
+                int code = resp.getStatus();
+                userLog("Code: " + code);
+                if (code != HttpStatus.SC_OK) return null;
+
+                InputStream is = resp.getInputStream();
+                // The response to Autodiscover is regular XML (not WBXML)
+                // If we ever get an error in this process, we'll just punt and return null
+                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+                XmlPullParser parser = factory.newPullParser();
+                parser.setInput(is, "UTF-8");
+                int type = parser.getEventType();
+                if (type == XmlPullParser.START_DOCUMENT) {
+                    type = parser.next();
+                    if (type == XmlPullParser.START_TAG) {
+                        String name = parser.getName();
+                        if (name.equals("Autodiscover")) {
+                            hostAuth = new HostAuth();
+                            parseAutodiscover(parser, hostAuth);
+                            // On success, we'll have a server address and login
+                            if (hostAuth.mAddress != null) {
+                                // Fill in the rest of the HostAuth
+                                // We use the user name and password that were successful during
+                                // the autodiscover process
+                                hostAuth.mLogin = mUserName;
+                                hostAuth.mPassword = mPassword;
+                                // Note: there is no way we can auto-discover the proper client
+                                // SSL certificate to use, if one is needed.
+                                hostAuth.mPort = 443;
+                                hostAuth.mProtocol = "eas";
+                                hostAuth.mFlags =
+                                    HostAuth.FLAG_SSL | HostAuth.FLAG_AUTHENTICATE;
+                                bundle.putParcelable(
+                                        EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH, hostAuth);
+                            } else {
+                                bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
+                                        MessagingException.UNSPECIFIED_EXCEPTION);
+                            }
+                        }
+                    }
+                }
+            } catch (XmlPullParserException e1) {
+                // This would indicate an I/O error of some sort
+                // We will simply return null and user can configure manually
+            } finally {
+               resp.close();
+            }
+        // There's no reason at all for exceptions to be thrown, and it's ok if so.
+        // We just won't do auto-discover; user can configure manually
+       } catch (IllegalArgumentException e) {
+             bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
+                     MessagingException.UNSPECIFIED_EXCEPTION);
+       } catch (IllegalStateException e) {
+            bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
+                    MessagingException.UNSPECIFIED_EXCEPTION);
+       } catch (IOException e) {
+            userLog("IOException in Autodiscover", e);
+            bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
+                    MessagingException.IOERROR);
+        } catch (MessagingException e) {
+            bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
+                    MessagingException.AUTODISCOVER_AUTHENTICATION_FAILED);
+        }
+        return bundle;
+    }
+
+    void parseServer(XmlPullParser parser, HostAuth hostAuth)
+            throws XmlPullParserException, IOException {
+        boolean mobileSync = false;
+        while (true) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("Server")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (name.equals("Type")) {
+                    if (parser.nextText().equals("MobileSync")) {
+                        mobileSync = true;
+                    }
+                } else if (mobileSync && name.equals("Url")) {
+                    String hostAddress =
+                        autodiscoverUrlToHostAddress(parser.nextText());
+                    if (hostAddress != null) {
+                        hostAuth.mAddress = hostAddress;
+                        userLog("Autodiscover, server: " + hostAddress);
+                    }
+                }
+            }
+        }
+    }
+
+    void parseSettings(XmlPullParser parser, HostAuth hostAuth)
+            throws XmlPullParserException, IOException {
+        while (true) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("Settings")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (name.equals("Server")) {
+                    parseServer(parser, hostAuth);
+                }
+            }
+        }
+    }
+
+    void parseAction(XmlPullParser parser, HostAuth hostAuth)
+            throws XmlPullParserException, IOException {
+        while (true) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("Action")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (name.equals("Error")) {
+                    // Should parse the error
+                } else if (name.equals("Redirect")) {
+                    Log.d(TAG, "Redirect: " + parser.nextText());
+                } else if (name.equals("Settings")) {
+                    parseSettings(parser, hostAuth);
+                }
+            }
+        }
+    }
+
+    void parseUser(XmlPullParser parser, HostAuth hostAuth)
+            throws XmlPullParserException, IOException {
+        while (true) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("User")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (name.equals("EMailAddress")) {
+                    String addr = parser.nextText();
+                    userLog("Autodiscover, email: " + addr);
+                } else if (name.equals("DisplayName")) {
+                    String dn = parser.nextText();
+                    userLog("Autodiscover, user: " + dn);
+                }
+            }
+        }
+    }
+
+    void parseResponse(XmlPullParser parser, HostAuth hostAuth)
+            throws XmlPullParserException, IOException {
+        while (true) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("Response")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (name.equals("User")) {
+                    parseUser(parser, hostAuth);
+                } else if (name.equals("Action")) {
+                    parseAction(parser, hostAuth);
+                }
+            }
+        }
+    }
+
+    void parseAutodiscover(XmlPullParser parser, HostAuth hostAuth)
+            throws XmlPullParserException, IOException {
+        while (true) {
+            int type = parser.nextTag();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("Autodiscover")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG && parser.getName().equals("Response")) {
+                parseResponse(parser, hostAuth);
+            }
+        }
+    }
+
+    /**
+     * Contact the GAL and obtain a list of matching accounts
+     * @param context caller's context
+     * @param accountId the account Id to search
+     * @param filter the characters entered so far
+     * @return a result record or null for no data
+     *
+     * TODO: shorter timeout for interactive lookup
+     * TODO: make watchdog actually work (it doesn't understand our service w/Mailbox == 0)
+     * TODO: figure out why sendHttpClientPost() hangs - possibly pool exhaustion
+     */
+    static public GalResult searchGal(Context context, long accountId, String filter, int limit) {
+        Account acct = Account.restoreAccountWithId(context, accountId);
+        if (acct != null) {
+            EasSyncService svc = setupServiceForAccount(context, acct);
+            if (svc == null) return null;
+            try {
+                Serializer s = new Serializer();
+                s.start(Tags.SEARCH_SEARCH).start(Tags.SEARCH_STORE);
+                s.data(Tags.SEARCH_NAME, "GAL").data(Tags.SEARCH_QUERY, filter);
+                s.start(Tags.SEARCH_OPTIONS);
+                s.data(Tags.SEARCH_RANGE, "0-" + Integer.toString(limit - 1));
+                s.end().end().end().done();
+                EasResponse resp = svc.sendHttpClientPost("Search", s.toByteArray());
+                try {
+                    int code = resp.getStatus();
+                    if (code == HttpStatus.SC_OK) {
+                        InputStream is = resp.getInputStream();
+                        try {
+                            GalParser gp = new GalParser(is, svc);
+                            if (gp.parse()) {
+                                return gp.getGalResult();
+                            }
+                        } finally {
+                            is.close();
+                        }
+                    } else {
+                        svc.userLog("GAL lookup returned " + code);
+                    }
+                } finally {
+                    resp.close();
+                }
+            } catch (IOException e) {
+                // GAL is non-critical; we'll just go on
+                svc.userLog("GAL lookup exception " + e);
+            }
+        }
+        return null;
+    }
+    /**
+     * Send an email responding to a Message that has been marked as a meeting request.  The message
+     * will consist a little bit of event information and an iCalendar attachment
+     * @param msg the meeting request email
+     */
+    private void sendMeetingResponseMail(Message msg, int response) {
+        // Get the meeting information; we'd better have some...
+        if (msg.mMeetingInfo == null) return;
+        PackedString meetingInfo = new PackedString(msg.mMeetingInfo);
+
+        // This will come as "First Last" <box@server.blah>, so we use Address to
+        // parse it into parts; we only need the email address part for the ics file
+        Address[] addrs = Address.parse(meetingInfo.get(MeetingInfo.MEETING_ORGANIZER_EMAIL));
+        // It shouldn't be possible, but handle it anyway
+        if (addrs.length != 1) return;
+        String organizerEmail = addrs[0].getAddress();
+
+        String dtStamp = meetingInfo.get(MeetingInfo.MEETING_DTSTAMP);
+        String dtStart = meetingInfo.get(MeetingInfo.MEETING_DTSTART);
+        String dtEnd = meetingInfo.get(MeetingInfo.MEETING_DTEND);
+
+        // What we're doing here is to create an Entity that looks like an Event as it would be
+        // stored by CalendarProvider
+        ContentValues entityValues = new ContentValues();
+        Entity entity = new Entity(entityValues);
+
+        // Fill in times, location, title, and organizer
+        entityValues.put("DTSTAMP",
+                CalendarUtilities.convertEmailDateTimeToCalendarDateTime(dtStamp));
+        entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis(dtStart));
+        entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis(dtEnd));
+        entityValues.put(Events.EVENT_LOCATION, meetingInfo.get(MeetingInfo.MEETING_LOCATION));
+        entityValues.put(Events.TITLE, meetingInfo.get(MeetingInfo.MEETING_TITLE));
+        entityValues.put(Events.ORGANIZER, organizerEmail);
+
+        // Add ourselves as an attendee, using our account email address
+        ContentValues attendeeValues = new ContentValues();
+        attendeeValues.put(Attendees.ATTENDEE_RELATIONSHIP,
+                Attendees.RELATIONSHIP_ATTENDEE);
+        attendeeValues.put(Attendees.ATTENDEE_EMAIL, mAccount.mEmailAddress);
+        entity.addSubValue(Attendees.CONTENT_URI, attendeeValues);
+
+        // Add the organizer
+        ContentValues organizerValues = new ContentValues();
+        organizerValues.put(Attendees.ATTENDEE_RELATIONSHIP,
+                Attendees.RELATIONSHIP_ORGANIZER);
+        organizerValues.put(Attendees.ATTENDEE_EMAIL, organizerEmail);
+        entity.addSubValue(Attendees.CONTENT_URI, organizerValues);
+
+        // Create a message from the Entity we've built.  The message will have fields like
+        // to, subject, date, and text filled in.  There will also be an "inline" attachment
+        // which is in iCalendar format
+        int flag;
+        switch(response) {
+            case EmailServiceConstants.MEETING_REQUEST_ACCEPTED:
+                flag = Message.FLAG_OUTGOING_MEETING_ACCEPT;
+                break;
+            case EmailServiceConstants.MEETING_REQUEST_DECLINED:
+                flag = Message.FLAG_OUTGOING_MEETING_DECLINE;
+                break;
+            case EmailServiceConstants.MEETING_REQUEST_TENTATIVE:
+            default:
+                flag = Message.FLAG_OUTGOING_MEETING_TENTATIVE;
+                break;
+        }
+        Message outgoingMsg =
+            CalendarUtilities.createMessageForEntity(mContext, entity, flag,
+                    meetingInfo.get(MeetingInfo.MEETING_UID), mAccount);
+        // Assuming we got a message back (we might not if the event has been deleted), send it
+        if (outgoingMsg != null) {
+            EasOutboxService.sendMessage(mContext, mAccount.mId, outgoingMsg);
+        }
+    }
+
+    /**
+     * Responds to a move request.  The MessageMoveRequest is basically our
+     * wrapper for the MoveItems service call
+     * @param req the request (message id and "to" mailbox id)
+     * @throws IOException
+     */
+    protected void messageMoveRequest(MessageMoveRequest req) throws IOException {
+        // Retrieve the message and mailbox; punt if either are null
+        Message msg = Message.restoreMessageWithId(mContext, req.mMessageId);
+        if (msg == null) return;
+        Cursor c = mContentResolver.query(ContentUris.withAppendedId(Message.UPDATED_CONTENT_URI,
+                msg.mId), new String[] {MessageColumns.MAILBOX_KEY}, null, null, null);
+        if (c == null) throw new ProviderUnavailableException();
+        Mailbox srcMailbox = null;
+        try {
+            if (!c.moveToNext()) return;
+            srcMailbox = Mailbox.restoreMailboxWithId(mContext, c.getLong(0));
+        } finally {
+            c.close();
+        }
+        if (srcMailbox == null) return;
+        Mailbox dstMailbox = Mailbox.restoreMailboxWithId(mContext, req.mMailboxId);
+        if (dstMailbox == null) return;
+        Serializer s = new Serializer();
+        s.start(Tags.MOVE_MOVE_ITEMS).start(Tags.MOVE_MOVE);
+        s.data(Tags.MOVE_SRCMSGID, msg.mServerId);
+        s.data(Tags.MOVE_SRCFLDID, srcMailbox.mServerId);
+        s.data(Tags.MOVE_DSTFLDID, dstMailbox.mServerId);
+        s.end().end().done();
+        EasResponse resp = sendHttpClientPost("MoveItems", s.toByteArray());
+        try {
+            int status = resp.getStatus();
+            if (status == HttpStatus.SC_OK) {
+                if (!resp.isEmpty()) {
+                    InputStream is = resp.getInputStream();
+                    MoveItemsParser p = new MoveItemsParser(is, this);
+                    p.parse();
+                    int statusCode = p.getStatusCode();
+                    ContentValues cv = new ContentValues();
+                    if (statusCode == MoveItemsParser.STATUS_CODE_REVERT) {
+                        // Restore the old mailbox id
+                        cv.put(MessageColumns.MAILBOX_KEY, srcMailbox.mServerId);
+                        mContentResolver.update(
+                                ContentUris.withAppendedId(Message.CONTENT_URI, req.mMessageId),
+                                cv, null, null);
+                    } else if (statusCode == MoveItemsParser.STATUS_CODE_SUCCESS) {
+                        // Update with the new server id
+                        cv.put(SyncColumns.SERVER_ID, p.getNewServerId());
+                        cv.put(Message.FLAGS, msg.mFlags | MESSAGE_FLAG_MOVED_MESSAGE);
+                        mContentResolver.update(
+                                ContentUris.withAppendedId(Message.CONTENT_URI, req.mMessageId),
+                                cv, null, null);
+                    }
+                    if (statusCode == MoveItemsParser.STATUS_CODE_SUCCESS
+                            || statusCode == MoveItemsParser.STATUS_CODE_REVERT) {
+                        // If we revert or succeed, we no longer need the update information
+                        // OR the now-duplicate email (the new copy will be synced down)
+                        mContentResolver.delete(ContentUris.withAppendedId(
+                                Message.UPDATED_CONTENT_URI, req.mMessageId), null, null);
+                    } else {
+                        // In this case, we're retrying, so do nothing.  The request will be
+                        // handled next sync
+                    }
+                }
+            } else if (EasResponse.isAuthError(status)) {
+                throw new EasAuthenticationException();
+            } else {
+                userLog("Move items request failed, code: " + status);
+                throw new IOException();
+            }
+        } finally {
+            resp.close();
+        }
+    }
+
+    /**
+     * Responds to a meeting request.  The MeetingResponseRequest is basically our
+     * wrapper for the meetingResponse service call
+     * @param req the request (message id and response code)
+     * @throws IOException
+     */
+    protected void sendMeetingResponse(MeetingResponseRequest req) throws IOException {
+        // Retrieve the message and mailbox; punt if either are null
+        Message msg = Message.restoreMessageWithId(mContext, req.mMessageId);
+        if (msg == null) return;
+        Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, msg.mMailboxKey);
+        if (mailbox == null) return;
+        Serializer s = new Serializer();
+        s.start(Tags.MREQ_MEETING_RESPONSE).start(Tags.MREQ_REQUEST);
+        s.data(Tags.MREQ_USER_RESPONSE, Integer.toString(req.mResponse));
+        s.data(Tags.MREQ_COLLECTION_ID, mailbox.mServerId);
+        s.data(Tags.MREQ_REQ_ID, msg.mServerId);
+        s.end().end().done();
+        EasResponse resp = sendHttpClientPost("MeetingResponse", s.toByteArray());
+        try {
+            int status = resp.getStatus();
+            if (status == HttpStatus.SC_OK) {
+                if (!resp.isEmpty()) {
+                    InputStream is = resp.getInputStream();
+                    new MeetingResponseParser(is, this).parse();
+                    String meetingInfo = msg.mMeetingInfo;
+                    if (meetingInfo != null) {
+                        String responseRequested = new PackedString(meetingInfo).get(
+                                MeetingInfo.MEETING_RESPONSE_REQUESTED);
+                        // If there's no tag, or a non-zero tag, we send the response mail
+                        if ("0".equals(responseRequested)) {
+                            return;
+                        }
+                    }
+                    sendMeetingResponseMail(msg, req.mResponse);
+                }
+            } else if (EasResponse.isAuthError(status)) {
+                throw new EasAuthenticationException();
+            } else {
+                userLog("Meeting response request failed, code: " + status);
+                throw new IOException();
+            }
+        } finally {
+            resp.close();
+       }
+    }
+
+    /**
+     * Using mUserName and mPassword, lazily create the strings that are commonly used in our HTTP
+     * POSTs, including the authentication header string, the base URI we use to communicate with
+     * EAS, and the user information string (user, deviceId, and deviceType)
+     */
+    private void cacheAuthUserAndBaseUriStrings() {
+        if (mAuthString == null || mUserString == null || mBaseUriString == null) {
+            String safeUserName = Uri.encode(mUserName);
+            String cs = mUserName + ':' + mPassword;
+            mAuthString = "Basic " + Base64.encodeToString(cs.getBytes(), Base64.NO_WRAP);
+            mUserString = "&User=" + safeUserName + "&DeviceId=" + mDeviceId +
+                "&DeviceType=" + DEVICE_TYPE;
+            String scheme =
+                EmailClientConnectionManager.makeScheme(mSsl, mTrustSsl, mClientCertAlias);
+            mBaseUriString = scheme + "://" + mHostAddress + "/Microsoft-Server-ActiveSync";
+        }
+    }
+
+    @VisibleForTesting
+    String makeUriString(String cmd, String extra) {
+        cacheAuthUserAndBaseUriStrings();
+        String uriString = mBaseUriString;
+        if (cmd != null) {
+            uriString += "?Cmd=" + cmd + mUserString;
+        }
+        if (extra != null) {
+            uriString += extra;
+        }
+        return uriString;
+    }
+
+    /**
+     * Set standard HTTP headers, using a policy key if required
+     * @param method the method we are going to send
+     * @param usePolicyKey whether or not a policy key should be sent in the headers
+     */
+    /*package*/ void setHeaders(HttpRequestBase method, boolean usePolicyKey) {
+        method.setHeader("Authorization", mAuthString);
+        method.setHeader("MS-ASProtocolVersion", mProtocolVersion);
+        method.setHeader("User-Agent", USER_AGENT);
+        method.setHeader("Accept-Encoding", "gzip");
+        if (usePolicyKey) {
+            // If there's an account in existence, use its key; otherwise (we're creating the
+            // account), send "0".  The server will respond with code 449 if there are policies
+            // to be enforced
+            String key = "0";
+            if (mAccount != null) {
+                String accountKey = mAccount.mSecuritySyncKey;
+                if (!TextUtils.isEmpty(accountKey)) {
+                    key = accountKey;
+                }
+            }
+            method.setHeader("X-MS-PolicyKey", key);
+        }
+    }
+
+    protected void setConnectionParameters(
+            boolean useSsl, boolean trustAllServerCerts, String clientCertAlias)
+            throws CertificateException {
+
+        EmailClientConnectionManager connManager = getClientConnectionManager();
+
+        mSsl = useSsl;
+        mTrustSsl = trustAllServerCerts;
+        mClientCertAlias = clientCertAlias;
+
+        // Register the new alias, if needed.
+        if (mClientCertAlias != null) {
+            // Ensure that the connection manager knows to use the proper client certificate
+            // when establishing connections for this service.
+            connManager.registerClientCert(mContext, mClientCertAlias, mTrustSsl);
+        }
+    }
+
+    private EmailClientConnectionManager getClientConnectionManager() {
+        return ExchangeService.getClientConnectionManager();
+    }
+
+    private HttpClient getHttpClient(int timeout) {
+        HttpParams params = new BasicHttpParams();
+        HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
+        HttpConnectionParams.setSoTimeout(params, timeout);
+        HttpConnectionParams.setSocketBufferSize(params, 8192);
+        HttpClient client = new DefaultHttpClient(getClientConnectionManager(), params);
+        return client;
+    }
+
+    public EasResponse sendHttpClientPost(String cmd, byte[] bytes) throws IOException {
+        return sendHttpClientPost(cmd, new ByteArrayEntity(bytes), COMMAND_TIMEOUT);
+    }
+
+    protected EasResponse sendHttpClientPost(String cmd, HttpEntity entity) throws IOException {
+        return sendHttpClientPost(cmd, entity, COMMAND_TIMEOUT);
+    }
+
+    protected EasResponse sendPing(byte[] bytes, int heartbeat) throws IOException {
+       Thread.currentThread().setName(mAccount.mDisplayName + ": Ping");
+       return sendHttpClientPost(PING_COMMAND, new ByteArrayEntity(bytes), (heartbeat+5)*SECONDS);
+    }
+
+    /**
+     * Convenience method for executePostWithTimeout for use other than with the Ping command
+     */
+    protected EasResponse executePostWithTimeout(HttpClient client, HttpPost method, int timeout)
+            throws IOException {
+        return executePostWithTimeout(client, method, timeout, false);
+    }
+
+    /**
+     * Handle executing an HTTP POST command with proper timeout, watchdog, and ping behavior
+     * @param client the HttpClient
+     * @param method the HttpPost
+     * @param timeout the timeout before failure, in ms
+     * @param isPingCommand whether the POST is for the Ping command (requires wakelock logic)
+     * @return the HttpResponse
+     * @throws IOException
+     */
+    protected EasResponse executePostWithTimeout(HttpClient client, HttpPost method, int timeout,
+            boolean isPingCommand) throws IOException {
+        synchronized(getSynchronizer()) {
+            mPendingPost = method;
+            long alarmTime = timeout + WATCHDOG_TIMEOUT_ALLOWANCE;
+            if (isPingCommand) {
+                ExchangeService.runAsleep(mMailboxId, alarmTime);
+            } else {
+                ExchangeService.setWatchdogAlarm(mMailboxId, alarmTime);
+            }
+        }
+        try {
+            return EasResponse.fromHttpRequest(getClientConnectionManager(), client, method);
+        } finally {
+            synchronized(getSynchronizer()) {
+                if (isPingCommand) {
+                    ExchangeService.runAwake(mMailboxId);
+                } else {
+                    ExchangeService.clearWatchdogAlarm(mMailboxId);
+                }
+                mPendingPost = null;
+            }
+        }
+    }
+
+    public EasResponse sendHttpClientPost(String cmd, HttpEntity entity, int timeout)
+            throws IOException {
+        HttpClient client = getHttpClient(timeout);
+        boolean isPingCommand = cmd.equals(PING_COMMAND);
+
+        // Split the mail sending commands
+        String extra = null;
+        boolean msg = false;
+        if (cmd.startsWith("SmartForward&") || cmd.startsWith("SmartReply&")) {
+            int cmdLength = cmd.indexOf('&');
+            extra = cmd.substring(cmdLength);
+            cmd = cmd.substring(0, cmdLength);
+            msg = true;
+        } else if (cmd.startsWith("SendMail&")) {
+            msg = true;
+        }
+
+        String us = makeUriString(cmd, extra);
+        HttpPost method = new HttpPost(URI.create(us));
+        // Send the proper Content-Type header; it's always wbxml except for messages when
+        // the EAS protocol version is < 14.0
+        // If entity is null (e.g. for attachments), don't set this header
+        if (msg && (mProtocolVersionDouble < Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE)) {
+            method.setHeader("Content-Type", "message/rfc822");
+        } else if (entity != null) {
+            method.setHeader("Content-Type", "application/vnd.ms-sync.wbxml");
+        }
+        setHeaders(method, !isPingCommand);
+        // NOTE
+        // The next lines are added at the insistence of $VENDOR, who is seeing inappropriate
+        // network activity related to the Ping command on some networks with some servers.
+        // This code should be removed when the underlying issue is resolved
+        if (isPingCommand) {
+            method.setHeader("Connection", "close");
+        }
+        method.setEntity(entity);
+        return executePostWithTimeout(client, method, timeout, isPingCommand);
+    }
+
+    protected EasResponse sendHttpClientOptions() throws IOException {
+        cacheAuthUserAndBaseUriStrings();
+        // For OPTIONS, just use the base string and the single header
+        String uriString = mBaseUriString;
+        HttpOptions method = new HttpOptions(URI.create(uriString));
+        method.setHeader("Authorization", mAuthString);
+        method.setHeader("User-Agent", USER_AGENT);
+        HttpClient client = getHttpClient(COMMAND_TIMEOUT);
+        return EasResponse.fromHttpRequest(getClientConnectionManager(), client, method);
+    }
+
+    String getTargetCollectionClassFromCursor(Cursor c) {
+        int type = c.getInt(Mailbox.CONTENT_TYPE_COLUMN);
+        if (type == Mailbox.TYPE_CONTACTS) {
+            return "Contacts";
+        } else if (type == Mailbox.TYPE_CALENDAR) {
+            return "Calendar";
+        } else {
+            return "Email";
+        }
+    }
+
+    /**
+     * Negotiate provisioning with the server.  First, get policies form the server and see if
+     * the policies are supported by the device.  Then, write the policies to the account and
+     * tell SecurityPolicy that we have policies in effect.  Finally, see if those policies are
+     * active; if so, acknowledge the policies to the server and get a final policy key that we
+     * use in future EAS commands and write this key to the account.
+     * @return whether or not provisioning has been successful
+     * @throws IOException
+     */
+    public static boolean tryProvision(EasSyncService svc) throws IOException {
+        // First, see if provisioning is even possible, i.e. do we support the policies required
+        // by the server
+        ProvisionParser pp = canProvision(svc);
+        if (pp == null) return false;
+        Context context = svc.mContext;
+        Account account = svc.mAccount;
+        // Get the policies from ProvisionParser
+        Policy policy = pp.getPolicy();
+        Policy oldPolicy = null;
+        // Grab the old policy (if any)
+        if (svc.mAccount.mPolicyKey > 0) {
+            oldPolicy = Policy.restorePolicyWithId(context, account.mPolicyKey);
+        }
+        // Update the account with a null policyKey (the key we've gotten is
+        // temporary and cannot be used for syncing)
+        PolicyServiceProxy.setAccountPolicy(context, account.mId, policy, null);
+        // Make sure mAccount is current (with latest policy key)
+        account.refresh(context);
+        if (pp.getRemoteWipe()) {
+            // We've gotten a remote wipe command
+            ExchangeService.alwaysLog("!!! Remote wipe request received");
+            // Start by setting the account to security hold
+            PolicyServiceProxy.setAccountHoldFlag(context, account, true);
+            // Force a stop to any running syncs for this account (except this one)
+            ExchangeService.stopNonAccountMailboxSyncsForAccount(account.mId);
+
+            // First, we've got to acknowledge it, but wrap the wipe in try/catch so that
+            // we wipe the device regardless of any errors in acknowledgment
+            try {
+                ExchangeService.alwaysLog("!!! Acknowledging remote wipe to server");
+                acknowledgeRemoteWipe(svc, pp.getSecuritySyncKey());
+            } catch (Exception e) {
+                // Because remote wipe is such a high priority task, we don't want to
+                // circumvent it if there's an exception in acknowledgment
+            }
+            // Then, tell SecurityPolicy to wipe the device
+            ExchangeService.alwaysLog("!!! Executing remote wipe");
+            PolicyServiceProxy.remoteWipe(context);
+            return false;
+        } else if (pp.hasSupportablePolicySet() && PolicyServiceProxy.isActive(context, policy)) {
+            // See if the required policies are in force; if they are, acknowledge the policies
+            // to the server and get the final policy key
+            // NOTE: For EAS 14.0, we already have the acknowledgment in the ProvisionParser
+            String securitySyncKey;
+            if (svc.mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
+                securitySyncKey = pp.getSecuritySyncKey();
+            } else {
+                securitySyncKey = acknowledgeProvision(svc, pp.getSecuritySyncKey(),
+                        PROVISION_STATUS_OK);
+            }
+            if (securitySyncKey != null) {
+                // If attachment policies have changed, fix up any affected attachment records
+                if (oldPolicy != null) {
+                    if ((oldPolicy.mDontAllowAttachments != policy.mDontAllowAttachments) ||
+                            (oldPolicy.mMaxAttachmentSize != policy.mMaxAttachmentSize)) {
+                        Policy.setAttachmentFlagsForNewPolicy(context, account, policy);
+                    }
+                }
+                // Write the final policy key to the Account and say we've been successful
+                PolicyServiceProxy.setAccountPolicy(context, account.mId, policy, securitySyncKey);
+                // Release any mailboxes that might be in a security hold
+                ExchangeService.releaseSecurityHold(account);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static String getPolicyType(Double protocolVersion) {
+        return (protocolVersion >=
+            Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) ? EAS_12_POLICY_TYPE : EAS_2_POLICY_TYPE;
+    }
+
+    /**
+     * Obtain a set of policies from the server and determine whether those policies are supported
+     * by the device.
+     * @return the ProvisionParser (holds policies and key) if we receive policies; null otherwise
+     * @throws IOException
+     */
+    public static ProvisionParser canProvision(EasSyncService svc) throws IOException {
+        Serializer s = new Serializer();
+        Double protocolVersion = svc.mProtocolVersionDouble;
+        s.start(Tags.PROVISION_PROVISION);
+        if (svc.mProtocolVersionDouble >= Eas.SUPPORTED_PROTOCOL_EX2010_SP1_DOUBLE) {
+            // Send settings information in 14.1 and greater
+            s.start(Tags.SETTINGS_DEVICE_INFORMATION).start(Tags.SETTINGS_SET);
+            s.data(Tags.SETTINGS_MODEL, Build.MODEL);
+            //s.data(Tags.SETTINGS_IMEI, "");
+            //s.data(Tags.SETTINGS_FRIENDLY_NAME, "Friendly Name");
+            s.data(Tags.SETTINGS_OS, "Android " + Build.VERSION.RELEASE);
+            //s.data(Tags.SETTINGS_OS_LANGUAGE, "");
+            //s.data(Tags.SETTINGS_PHONE_NUMBER, "");
+            //s.data(Tags.SETTINGS_MOBILE_OPERATOR, "");
+            s.data(Tags.SETTINGS_USER_AGENT, EasSyncService.USER_AGENT);
+            s.end().end();  // SETTINGS_SET, SETTINGS_DEVICE_INFORMATION
+        }
+        s.start(Tags.PROVISION_POLICIES);
+        s.start(Tags.PROVISION_POLICY);
+        s.data(Tags.PROVISION_POLICY_TYPE, getPolicyType(protocolVersion));
+        s.end().end().end().done(); // PROVISION_POLICY, PROVISION_POLICIES, PROVISION_PROVISION
+        EasResponse resp = svc.sendHttpClientPost("Provision", s.toByteArray());
+        try {
+            int code = resp.getStatus();
+            if (code == HttpStatus.SC_OK) {
+                InputStream is = resp.getInputStream();
+                ProvisionParser pp = new ProvisionParser(is, svc);
+                if (pp.parse()) {
+                    // The PolicySet in the ProvisionParser will have the requirements for all KNOWN
+                    // policies.  If others are required, hasSupportablePolicySet will be false
+                    if (pp.hasSupportablePolicySet() &&
+                            svc.mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
+                        // In EAS 14.0, we need the final security key in order to use the settings
+                        // command
+                        String policyKey = acknowledgeProvision(svc, pp.getSecuritySyncKey(),
+                                PROVISION_STATUS_OK);
+                        if (policyKey != null) {
+                            pp.setSecuritySyncKey(policyKey);
+                        }
+                    } else if (!pp.hasSupportablePolicySet())  {
+                        // Try to acknowledge using the "partial" status (i.e. we can partially
+                        // accommodate the required policies).  The server will agree to this if the
+                        // "allow non-provisionable devices" setting is enabled on the server
+                        ExchangeService.log("PolicySet is NOT fully supportable");
+                        if (acknowledgeProvision(svc, pp.getSecuritySyncKey(),
+                                PROVISION_STATUS_PARTIAL) != null) {
+                            // The server's ok with our inability to support policies, so we'll
+                            // clear them
+                            pp.clearUnsupportablePolicies();
+                        }
+                    }
+                    return pp;
+                }
+            }
+        } finally {
+            resp.close();
+        }
+
+        // On failures, simply return null
+        return null;
+    }
+
+    /**
+     * Acknowledge that we support the policies provided by the server, and that these policies
+     * are in force.
+     * @param tempKey the initial (temporary) policy key sent by the server
+     * @return the final policy key, which can be used for syncing
+     * @throws IOException
+     */
+    private static void acknowledgeRemoteWipe(EasSyncService svc, String tempKey)
+            throws IOException {
+        acknowledgeProvisionImpl(svc, tempKey, PROVISION_STATUS_OK, true);
+    }
+
+    private static String acknowledgeProvision(EasSyncService svc, String tempKey, String result)
+            throws IOException {
+        return acknowledgeProvisionImpl(svc, tempKey, result, false);
+    }
+
+    private static String acknowledgeProvisionImpl(EasSyncService svc, String tempKey,
+            String status, boolean remoteWipe) throws IOException {
+        Serializer s = new Serializer();
+        s.start(Tags.PROVISION_PROVISION).start(Tags.PROVISION_POLICIES);
+        s.start(Tags.PROVISION_POLICY);
+
+        // Use the proper policy type, depending on EAS version
+        s.data(Tags.PROVISION_POLICY_TYPE, getPolicyType(svc.mProtocolVersionDouble));
+
+        s.data(Tags.PROVISION_POLICY_KEY, tempKey);
+        s.data(Tags.PROVISION_STATUS, status);
+        s.end().end(); // PROVISION_POLICY, PROVISION_POLICIES
+        if (remoteWipe) {
+            s.start(Tags.PROVISION_REMOTE_WIPE);
+            s.data(Tags.PROVISION_STATUS, PROVISION_STATUS_OK);
+            s.end();
+        }
+        s.end().done(); // PROVISION_PROVISION
+        EasResponse resp = svc.sendHttpClientPost("Provision", s.toByteArray());
+        try {
+            int code = resp.getStatus();
+            if (code == HttpStatus.SC_OK) {
+                InputStream is = resp.getInputStream();
+                ProvisionParser pp = new ProvisionParser(is, svc);
+                if (pp.parse()) {
+                    // Return the final policy key from the ProvisionParser
+                    String result = (pp.getSecuritySyncKey() == null) ? "failed" : "confirmed";
+                    ExchangeService.log("Provision " + result + " for " +
+                            (PROVISION_STATUS_PARTIAL.equals(status) ? "PART" : "FULL") + " set");
+                    return pp.getSecuritySyncKey();
+                }
+            }
+        } finally {
+            resp.close();
+        }
+        // On failures, log issue and return null
+        ExchangeService.log("Provisioning failed for" +
+                (PROVISION_STATUS_PARTIAL.equals(status) ? "PART" : "FULL") + " set");
+        return null;
+    }
+
+    private boolean sendSettings() throws IOException {
+        Serializer s = new Serializer();
+        s.start(Tags.SETTINGS_SETTINGS);
+        s.start(Tags.SETTINGS_DEVICE_INFORMATION).start(Tags.SETTINGS_SET);
+        s.data(Tags.SETTINGS_MODEL, Build.MODEL);
+        s.data(Tags.SETTINGS_OS, "Android " + Build.VERSION.RELEASE);
+        s.data(Tags.SETTINGS_USER_AGENT, USER_AGENT);
+        s.end().end().end().done(); // SETTINGS_SET, SETTINGS_DEVICE_INFORMATION, SETTINGS_SETTINGS
+        EasResponse resp = sendHttpClientPost("Settings", s.toByteArray());
+        try {
+            int code = resp.getStatus();
+            if (code == HttpStatus.SC_OK) {
+                InputStream is = resp.getInputStream();
+                SettingsParser sp = new SettingsParser(is, this);
+                return sp.parse();
+            }
+        } finally {
+            resp.close();
+        }
+        // On failures, simply return false
+        return false;
+    }
+
+    /**
+     * Common code to sync E+PIM data
+     * @param target an EasMailbox, EasContacts, or EasCalendar object
+     */
+    public void sync(AbstractSyncAdapter target) throws IOException {
+        Mailbox mailbox = target.mMailbox;
+
+        boolean moreAvailable = true;
+        int loopingCount = 0;
+        while (!mStop && (moreAvailable || hasPendingRequests())) {
+            // If we have no connectivity, just exit cleanly. ExchangeService will start us up again
+            // when connectivity has returned
+            if (!hasConnectivity()) {
+                userLog("No connectivity in sync; finishing sync");
+                mExitStatus = EXIT_DONE;
+                return;
+            }
+
+            // Every time through the loop we check to see if we're still syncable
+            if (!target.isSyncable()) {
+                mExitStatus = EXIT_DONE;
+                return;
+            }
+
+            // Now, handle various requests
+            while (true) {
+                Request req = null;
+
+                if (mRequestQueue.isEmpty()) {
+                    break;
+                } else {
+                    req = mRequestQueue.peek();
+                }
+
+                // Our two request types are PartRequest (loading attachment) and
+                // MeetingResponseRequest (respond to a meeting request)
+                if (req instanceof PartRequest) {
+                    TrafficStats.setThreadStatsTag(
+                            TrafficFlags.getAttachmentFlags(mContext, mAccount));
+                    new AttachmentLoader(this, (PartRequest)req).loadAttachment();
+                    TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, mAccount));
+                } else if (req instanceof MeetingResponseRequest) {
+                    sendMeetingResponse((MeetingResponseRequest)req);
+                } else if (req instanceof MessageMoveRequest) {
+                    messageMoveRequest((MessageMoveRequest)req);
+                }
+
+                // If there's an exception handling the request, we'll throw it
+                // Otherwise, we remove the request
+                mRequestQueue.remove();
+            }
+
+            // Don't sync if we've got nothing to do
+            if (!moreAvailable) {
+                continue;
+            }
+
+            Serializer s = new Serializer();
+
+            String className = target.getCollectionName();
+            String syncKey = target.getSyncKey();
+            userLog("sync, sending ", className, " syncKey: ", syncKey);
+            s.start(Tags.SYNC_SYNC)
+                .start(Tags.SYNC_COLLECTIONS)
+                .start(Tags.SYNC_COLLECTION);
+            // The "Class" element is removed in EAS 12.1 and later versions
+            if (mProtocolVersionDouble < Eas.SUPPORTED_PROTOCOL_EX2007_SP1_DOUBLE) {
+                s.data(Tags.SYNC_CLASS, className);
+            }
+            s.data(Tags.SYNC_SYNC_KEY, syncKey)
+                .data(Tags.SYNC_COLLECTION_ID, mailbox.mServerId);
+
+            // Start with the default timeout
+            int timeout = COMMAND_TIMEOUT;
+            if (!syncKey.equals("0")) {
+                // EAS doesn't allow GetChanges in an initial sync; sending other options
+                // appears to cause the server to delay its response in some cases, and this delay
+                // can be long enough to result in an IOException and total failure to sync.
+                // Therefore, we don't send any options with the initial sync.
+                // Set the truncation amount, body preference, lookback, etc.
+                target.sendSyncOptions(mProtocolVersionDouble, s);
+            } else {
+                // Use enormous timeout for initial sync, which empirically can take a while longer
+                timeout = 120*SECONDS;
+            }
+            // Send our changes up to the server
+            if (mUpsyncFailed) {
+                if (Eas.USER_LOG) {
+                    Log.d(TAG, "Inhibiting upsync this cycle");
+                }
+            } else {
+                target.sendLocalChanges(s);
+            }
+
+            s.end().end().end().done();
+            EasResponse resp = sendHttpClientPost("Sync", new ByteArrayEntity(s.toByteArray()),
+                    timeout);
+            try {
+                int code = resp.getStatus();
+                if (code == HttpStatus.SC_OK) {
+                    // In EAS 12.1, we can get "empty" sync responses, which indicate that there are
+                    // no changes in the mailbox; handle that case here
+                    // There are two cases here; if we get back a compressed stream (GZIP), we won't
+                    // know until we try to parse it (and generate an EmptyStreamException). If we
+                    // get uncompressed data, the response will be empty (i.e. have zero length)
+                    boolean emptyStream = false;
+                    if (!resp.isEmpty()) {
+                        InputStream is = resp.getInputStream();
+                        try {
+                            moreAvailable = target.parse(is);
+                            // If we inhibited upsync, we need yet another sync
+                            if (mUpsyncFailed) {
+                                moreAvailable = true;
+                            }
+
+                            if (target.isLooping()) {
+                                loopingCount++;
+                                userLog("** Looping: " + loopingCount);
+                                // After the maximum number of loops, we'll set moreAvailable to
+                                // false and allow the sync loop to terminate
+                                if (moreAvailable && (loopingCount > MAX_LOOPING_COUNT)) {
+                                    userLog("** Looping force stopped");
+                                    moreAvailable = false;
+                                }
+                            } else {
+                                loopingCount = 0;
+                            }
+
+                            // Cleanup clears out the updated/deleted tables, and we don't want to
+                            // do that if our upsync failed; clear the flag otherwise
+                            if (!mUpsyncFailed) {
+                                target.cleanup();
+                            } else {
+                                mUpsyncFailed = false;
+                            }
+                        } catch (EmptyStreamException e) {
+                            userLog("Empty stream detected in GZIP response");
+                            emptyStream = true;
+                        } catch (CommandStatusException e) {
+                            // TODO 14.1
+                            int status = e.mStatus;
+                            if (CommandStatus.isNeedsProvisioning(status)) {
+                                mExitStatus = EXIT_SECURITY_FAILURE;
+                            } else if (CommandStatus.isDeniedAccess(status)) {
+                                mExitStatus = EXIT_ACCESS_DENIED;
+                            } else if (CommandStatus.isTransientError(status)) {
+                                mExitStatus = EXIT_IO_ERROR;
+                            } else {
+                                mExitStatus = EXIT_EXCEPTION;
+                            }
+                            return;
+                        }
+                    } else {
+                        emptyStream = true;
+                    }
+
+                    if (emptyStream) {
+                        // If this happens, exit cleanly, and change the interval from push to ping
+                        // if necessary
+                        userLog("Empty sync response; finishing");
+                        if (mMailbox.mSyncInterval == Mailbox.CHECK_INTERVAL_PUSH) {
+                            userLog("Changing mailbox from push to ping");
+                            ContentValues cv = new ContentValues();
+                            cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PING);
+                            mContentResolver.update(
+                                    ContentUris.withAppendedId(Mailbox.CONTENT_URI, mMailbox.mId),
+                                    cv, null, null);
+                        }
+                        if (mRequestQueue.isEmpty()) {
+                            mExitStatus = EXIT_DONE;
+                            return;
+                        } else {
+                            continue;
+                        }
+                    }
+                } else {
+                    userLog("Sync response error: ", code);
+                    if (EasResponse.isProvisionError(code)) {
+                        mExitStatus = EXIT_SECURITY_FAILURE;
+                    } else if (EasResponse.isAuthError(code)) {
+                        mExitStatus = EXIT_LOGIN_FAILURE;
+                    } else {
+                        mExitStatus = EXIT_IO_ERROR;
+                    }
+                    return;
+                }
+            } finally {
+                resp.close();
+            }
+        }
+        mExitStatus = EXIT_DONE;
+    }
+
+    protected boolean setupService() {
+        synchronized(getSynchronizer()) {
+            mThread = Thread.currentThread();
+            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
+            TAG = mThread.getName();
+        }
+        // Make sure account and mailbox are always the latest from the database
+        mAccount = Account.restoreAccountWithId(mContext, mAccount.mId);
+        if (mAccount == null) return false;
+        mMailbox = Mailbox.restoreMailboxWithId(mContext, mMailbox.mId);
+        if (mMailbox == null) return false;
+        HostAuth ha = HostAuth.restoreHostAuthWithId(mContext, mAccount.mHostAuthKeyRecv);
+        if (ha == null) return false;
+        mHostAddress = ha.mAddress;
+        mUserName = ha.mLogin;
+        mPassword = ha.mPassword;
+
+        try {
+            setConnectionParameters(
+                    (ha.mFlags & HostAuth.FLAG_SSL) != 0,
+                    (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0,
+                    ha.mClientCertAlias);
+        } catch (CertificateException e) {
+            userLog("Couldn't retrieve certificate for connection");
+            try {
+                ExchangeService.callback().syncMailboxStatus(mMailboxId,
+                        EmailServiceStatus.CLIENT_CERTIFICATE_ERROR, 0);
+            } catch (RemoteException e1) {
+                // Don't care if this fails.
+            }
+            return false;
+        }
+
+        // Set up our protocol version from the Account
+        mProtocolVersion = mAccount.mProtocolVersion;
+        // If it hasn't been set up, start with default version
+        if (mProtocolVersion == null) {
+            mProtocolVersion = Eas.DEFAULT_PROTOCOL_VERSION;
+        }
+        mProtocolVersionDouble = Eas.getProtocolVersionDouble(mProtocolVersion);
+
+        // Do checks to address historical policy sets.
+        Policy policy = Policy.restorePolicyWithId(mContext, mAccount.mPolicyKey);
+        if ((policy != null) && policy.mRequireEncryptionExternal) {
+            // External storage encryption is not supported at this time. In a previous release,
+            // prior to the system supporting true removable storage on Honeycomb, we accepted
+            // this since we emulated external storage on partitions that could be encrypted.
+            // If that was set before, we must clear it out now that the system supports true
+            // removable storage (which can't be encrypted).
+            resetSecurityPolicies();
+        }
+        return true;
+    }
+
+    /**
+     * Clears out the security policies associated with the account, forcing a provision error
+     * and a re-sync of the policy information for the account.
+     */
+    @SuppressWarnings("deprecation")
+    void resetSecurityPolicies() {
+        ContentValues cv = new ContentValues();
+        cv.put(AccountColumns.SECURITY_FLAGS, 0);
+        cv.putNull(AccountColumns.SECURITY_SYNC_KEY);
+        long accountId = mAccount.mId;
+        mContentResolver.update(ContentUris.withAppendedId(
+                Account.CONTENT_URI, accountId), cv, null, null);
+    }
+
+    @Override
+    public void run() {
+        try {
+            // Make sure account and mailbox are still valid
+            if (!setupService()) return;
+            // If we've been stopped, we're done
+            if (mStop) return;
+
+            // Whether or not we're the account mailbox
+            try {
+                mDeviceId = ExchangeService.getDeviceId(mContext);
+                int trafficFlags = TrafficFlags.getSyncFlags(mContext, mAccount);
+                if ((mMailbox == null) || (mAccount == null)) {
+                    return;
+                } else {
+                    AbstractSyncAdapter target;
+                    if (mMailbox.mType == Mailbox.TYPE_CONTACTS) {
+                        TrafficStats.setThreadStatsTag(trafficFlags | TrafficFlags.DATA_CONTACTS);
+                        target = new ContactsSyncAdapter( this);
+                    } else if (mMailbox.mType == Mailbox.TYPE_CALENDAR) {
+                        TrafficStats.setThreadStatsTag(trafficFlags | TrafficFlags.DATA_CALENDAR);
+                        target = new CalendarSyncAdapter(this);
+                    } else {
+                        TrafficStats.setThreadStatsTag(trafficFlags | TrafficFlags.DATA_EMAIL);
+                        target = new EmailSyncAdapter(this);
+                    }
+                    // We loop because someone might have put a request in while we were syncing
+                    // and we've missed that opportunity...
+                    do {
+                        if (mRequestTime != 0) {
+                            userLog("Looping for user request...");
+                            mRequestTime = 0;
+                        }
+                        String syncKey = target.getSyncKey();
+                        if (mSyncReason >= ExchangeService.SYNC_CALLBACK_START ||
+                                "0".equals(syncKey)) {
+                            try {
+                                ExchangeService.callback().syncMailboxStatus(mMailboxId,
+                                        EmailServiceStatus.IN_PROGRESS, 0);
+                            } catch (RemoteException e1) {
+                                // Don't care if this fails
+                            }
+                        }
+                        sync(target);
+                    } while (mRequestTime != 0);
+                }
+            } catch (EasAuthenticationException e) {
+                userLog("Caught authentication error");
+                mExitStatus = EXIT_LOGIN_FAILURE;
+            } catch (IOException e) {
+                String message = e.getMessage();
+                userLog("Caught IOException: ", (message == null) ? "No message" : message);
+                mExitStatus = EXIT_IO_ERROR;
+            } catch (Exception e) {
+                userLog("Uncaught exception in EasSyncService", e);
+            } finally {
+                int status;
+                ExchangeService.done(this);
+                if (!mStop) {
+                    userLog("Sync finished");
+                    switch (mExitStatus) {
+                        case EXIT_IO_ERROR:
+                            status = EmailServiceStatus.CONNECTION_ERROR;
+                            break;
+                        case EXIT_DONE:
+                            status = EmailServiceStatus.SUCCESS;
+                            ContentValues cv = new ContentValues();
+                            cv.put(Mailbox.SYNC_TIME, System.currentTimeMillis());
+                            String s = "S" + mSyncReason + ':' + status + ':' + mChangeCount;
+                            cv.put(Mailbox.SYNC_STATUS, s);
+                            mContentResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI,
+                                    mMailboxId), cv, null, null);
+                            break;
+                        case EXIT_LOGIN_FAILURE:
+                            status = EmailServiceStatus.LOGIN_FAILED;
+                            break;
+                        case EXIT_SECURITY_FAILURE:
+                            status = EmailServiceStatus.SECURITY_FAILURE;
+                            // Ask for a new folder list. This should wake up the account mailbox; a
+                            // security error in account mailbox should start provisioning
+                            ExchangeService.reloadFolderList(mContext, mAccount.mId, true);
+                            break;
+                        case EXIT_ACCESS_DENIED:
+                            status = EmailServiceStatus.ACCESS_DENIED;
+                            break;
+                        default:
+                            status = EmailServiceStatus.REMOTE_EXCEPTION;
+                            errorLog("Sync ended due to an exception.");
+                            break;
+                    }
+                } else {
+                    userLog("Stopped sync finished.");
+                    status = EmailServiceStatus.SUCCESS;
+                }
+
+                // Send a callback (doesn't matter how the sync was started)
+                try {
+                    // Unless the user specifically asked for a sync, we don't want to report
+                    // connection issues, as they are likely to be transient.  In this case, we
+                    // simply report success, so that the progress indicator terminates without
+                    // putting up an error banner
+                    if (mSyncReason != ExchangeService.SYNC_UI_REQUEST &&
+                            status == EmailServiceStatus.CONNECTION_ERROR) {
+                        status = EmailServiceStatus.SUCCESS;
+                    }
+                    ExchangeService.callback().syncMailboxStatus(mMailboxId, status, 0);
+                } catch (RemoteException e1) {
+                    // Don't care if this fails
+                }
+
+                // Make sure ExchangeService knows about this
+                ExchangeService.kick("sync finished");
+            }
+        } catch (ProviderUnavailableException e) {
+            Log.e(TAG, "EmailProvider unavailable; sync ended prematurely");
+        }
+    }
+}
diff --git a/exchange2/src/com/android/exchange/EmailSyncAdapterService.java b/exchange2/src/com/android/exchange/EmailSyncAdapterService.java
new file mode 100644
index 0000000..f91ee13
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EmailSyncAdapterService.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.Mailbox;
+
+import android.accounts.Account;
+import android.accounts.OperationCanceledException;
+import android.app.Service;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
+
+public class EmailSyncAdapterService extends Service {
+    private static final String TAG = "EAS EmailSyncAdapterService";
+    private static SyncAdapterImpl sSyncAdapter = null;
+    private static final Object sSyncAdapterLock = new Object();
+
+    private static final String[] ID_PROJECTION = new String[] {EmailContent.RECORD_ID};
+    private static final String ACCOUNT_AND_TYPE_INBOX =
+        MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_INBOX;
+
+    public EmailSyncAdapterService() {
+        super();
+    }
+
+    private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
+        private Context mContext;
+
+        public SyncAdapterImpl(Context context) {
+            super(context, true /* autoInitialize */);
+            mContext = context;
+        }
+
+        @Override
+        public void onPerformSync(Account account, Bundle extras,
+                String authority, ContentProviderClient provider, SyncResult syncResult) {
+            try {
+                EmailSyncAdapterService.performSync(mContext, account, extras,
+                        authority, provider, syncResult);
+            } catch (OperationCanceledException e) {
+            }
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        synchronized (sSyncAdapterLock) {
+            if (sSyncAdapter == null) {
+                sSyncAdapter = new SyncAdapterImpl(getApplicationContext());
+            }
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return sSyncAdapter.getSyncAdapterBinder();
+    }
+
+    /**
+     * Partial integration with system SyncManager; we tell our EAS ExchangeService to start an
+     * inbox sync when we get the signal from the system SyncManager.
+     */
+    private static void performSync(Context context, Account account, Bundle extras,
+            String authority, ContentProviderClient provider, SyncResult syncResult)
+            throws OperationCanceledException {
+        ContentResolver cr = context.getContentResolver();
+        Log.i(TAG, "performSync");
+
+        // Find the (EmailProvider) account associated with this email address
+        Cursor accountCursor =
+            cr.query(com.android.emailcommon.provider.Account.CONTENT_URI,
+                    ID_PROJECTION, AccountColumns.EMAIL_ADDRESS + "=?", new String[] {account.name},
+                    null);
+        try {
+            if (accountCursor.moveToFirst()) {
+                long accountId = accountCursor.getLong(0);
+                // Now, find the inbox associated with the account
+                Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, ID_PROJECTION,
+                        ACCOUNT_AND_TYPE_INBOX, new String[] {Long.toString(accountId)}, null);
+                try {
+                     if (mailboxCursor.moveToFirst()) {
+                        Log.i(TAG, "Mail sync requested for " + account.name);
+                        // Ask for a sync from our sync manager
+                        ExchangeService.serviceRequest(mailboxCursor.getLong(0),
+                                ExchangeService.SYNC_KICK);
+                    }
+                } finally {
+                    mailboxCursor.close();
+                }
+            }
+        } finally {
+            accountCursor.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange2/src/com/android/exchange/EmailSyncAlarmReceiver.java b/exchange2/src/com/android/exchange/EmailSyncAlarmReceiver.java
new file mode 100644
index 0000000..8006016
--- /dev/null
+++ b/exchange2/src/com/android/exchange/EmailSyncAlarmReceiver.java
@@ -0,0 +1,114 @@
+/*
+ *  Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.util.Log;
+
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.EmailContent.MessageColumns;
+import com.android.emailcommon.provider.ProviderUnavailableException;
+
+import java.util.ArrayList;
+
+/**
+ * EmailSyncAlarmReceiver (USAR) is used by the SyncManager to start up-syncs of user-modified data
+ * back to the Exchange server.
+ *
+ * Here's how this works for Email, for example:
+ *
+ * 1) User modifies or deletes an email from the UI.
+ * 2) SyncManager, which has a ContentObserver watching the Message class, is alerted to a change
+ * 3) SyncManager sets an alarm (to be received by USAR) for a few seconds in the
+ * future (currently 15), the delay preventing excess syncing (think of it as a debounce mechanism).
+ * 4) ESAR Receiver's onReceive method is called
+ * 5) ESAR goes through all change and deletion records and compiles a list of mailboxes which have
+ * changes to be uploaded.
+ * 6) ESAR calls SyncManager to start syncs of those mailboxes
+ *
+ * If EmailProvider isn't available, the upsyncs will happen the next time ExchangeService starts
+ *
+ */
+public class EmailSyncAlarmReceiver extends BroadcastReceiver {
+    final String[] MAILBOX_DATA_PROJECTION = {MessageColumns.MAILBOX_KEY};
+
+    @Override
+    public void onReceive(final Context context, Intent intent) {
+        new Thread(new Runnable() {
+            public void run() {
+                handleReceive(context);
+            }
+        }).start();
+    }
+
+    private void handleReceive(Context context) {
+        ArrayList<Long> mailboxesToNotify = new ArrayList<Long>();
+        ContentResolver cr = context.getContentResolver();
+        int messageCount = 0;
+        
+        // Get a selector for EAS accounts (we don't want to sync on changes to POP/IMAP messages)
+        String selector = ExchangeService.getEasAccountSelector();
+        
+        try {
+            // Find all of the deletions
+            Cursor c = cr.query(Message.DELETED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector,
+                   null, null);
+            if (c == null) throw new ProviderUnavailableException();
+            try {
+                // Keep track of which mailboxes to notify; we'll only notify each one once
+                while (c.moveToNext()) {
+                    messageCount++;
+                    long mailboxId = c.getLong(0);
+                    if (!mailboxesToNotify.contains(mailboxId)) {
+                        mailboxesToNotify.add(mailboxId);
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            // Now, find changed messages
+            c = cr.query(Message.UPDATED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector,
+                    null, null);
+            if (c == null) throw new ProviderUnavailableException();
+            try {
+                // Keep track of which mailboxes to notify; we'll only notify each one once
+                while (c.moveToNext()) {
+                    messageCount++;
+                    long mailboxId = c.getLong(0);
+                    if (!mailboxesToNotify.contains(mailboxId)) {
+                        mailboxesToNotify.add(mailboxId);
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            // Request service from the mailbox
+            for (Long mailboxId: mailboxesToNotify) {
+                ExchangeService.serviceRequest(mailboxId, ExchangeService.SYNC_UPSYNC);
+            }
+        } catch (ProviderUnavailableException e) {
+            Log.e("EmailSyncAlarmReceiver", "EmailProvider unavailable; aborting alarm receiver");
+        }
+    }
+}
diff --git a/exchange2/src/com/android/exchange/Exchange.java b/exchange2/src/com/android/exchange/Exchange.java
new file mode 100644
index 0000000..496e1f5
--- /dev/null
+++ b/exchange2/src/com/android/exchange/Exchange.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import android.app.Application;
+
+public class Exchange extends Application {
+    // TODO Investigate whether this class is needed
+}
diff --git a/exchange2/src/com/android/exchange/ExchangeService.java b/exchange2/src/com/android/exchange/ExchangeService.java
new file mode 100644
index 0000000..0107d55
--- /dev/null
+++ b/exchange2/src/com/android/exchange/ExchangeService.java
@@ -0,0 +1,2685 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.provider.CalendarContract;
+import android.provider.CalendarContract.Calendars;
+import android.provider.CalendarContract.Events;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+import com.android.emailcommon.Api;
+import com.android.emailcommon.TempDirectory;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.Attachment;
+import com.android.emailcommon.provider.EmailContent.Body;
+import com.android.emailcommon.provider.EmailContent.BodyColumns;
+import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.EmailContent.SyncColumns;
+import com.android.emailcommon.provider.HostAuth;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.provider.Policy;
+import com.android.emailcommon.provider.ProviderUnavailableException;
+import com.android.emailcommon.service.AccountServiceProxy;
+import com.android.emailcommon.service.EmailServiceProxy;
+import com.android.emailcommon.service.EmailServiceStatus;
+import com.android.emailcommon.service.IEmailService;
+import com.android.emailcommon.service.IEmailServiceCallback;
+import com.android.emailcommon.service.PolicyServiceProxy;
+import com.android.emailcommon.service.SearchParams;
+import com.android.emailcommon.utility.EmailAsyncTask;
+import com.android.emailcommon.utility.EmailClientConnectionManager;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.adapter.CalendarSyncAdapter;
+import com.android.exchange.adapter.ContactsSyncAdapter;
+import com.android.exchange.adapter.Search;
+import com.android.exchange.provider.MailboxUtilities;
+import com.android.exchange.utility.FileLogger;
+
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRoute;
+import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * The ExchangeService handles all aspects of starting, maintaining, and stopping the various sync
+ * adapters used by Exchange.  However, it is capable of handing any kind of email sync, and it
+ * would be appropriate to use for IMAP push, when that functionality is added to the Email
+ * application.
+ *
+ * The Email application communicates with EAS sync adapters via ExchangeService's binder interface,
+ * which exposes UI-related functionality to the application (see the definitions below)
+ *
+ * ExchangeService uses ContentObservers to detect changes to accounts, mailboxes, and messages in
+ * order to maintain proper 2-way syncing of data.  (More documentation to follow)
+ *
+ */
+public class ExchangeService extends Service implements Runnable {
+
+    private static final String TAG = "ExchangeService";
+
+    // The ExchangeService's mailbox "id"
+    public static final int EXTRA_MAILBOX_ID = -1;
+    public static final int EXCHANGE_SERVICE_MAILBOX_ID = 0;
+
+    private static final int SECONDS = 1000;
+    private static final int MINUTES = 60*SECONDS;
+    private static final int ONE_DAY_MINUTES = 1440;
+
+    private static final int EXCHANGE_SERVICE_HEARTBEAT_TIME = 15*MINUTES;
+    private static final int CONNECTIVITY_WAIT_TIME = 10*MINUTES;
+
+    // Sync hold constants for services with transient errors
+    private static final int HOLD_DELAY_MAXIMUM = 4*MINUTES;
+
+    // Reason codes when ExchangeService.kick is called (mainly for debugging)
+    // UI has changed data, requiring an upsync of changes
+    public static final int SYNC_UPSYNC = 0;
+    // A scheduled sync (when not using push)
+    public static final int SYNC_SCHEDULED = 1;
+    // Mailbox was marked push
+    public static final int SYNC_PUSH = 2;
+    // A ping (EAS push signal) was received
+    public static final int SYNC_PING = 3;
+    // Misc.
+    public static final int SYNC_KICK = 4;
+    // A part request (attachment load, for now) was sent to ExchangeService
+    public static final int SYNC_SERVICE_PART_REQUEST = 5;
+
+    // Requests >= SYNC_CALLBACK_START generate callbacks to the UI
+    public static final int SYNC_CALLBACK_START = 6;
+    // startSync was requested of ExchangeService (other than due to user request)
+    public static final int SYNC_SERVICE_START_SYNC = SYNC_CALLBACK_START + 0;
+    // startSync was requested of ExchangeService (due to user request)
+    public static final int SYNC_UI_REQUEST = SYNC_CALLBACK_START + 1;
+
+    private static final String WHERE_PUSH_OR_PING_NOT_ACCOUNT_MAILBOX =
+        MailboxColumns.ACCOUNT_KEY + "=? and " + MailboxColumns.TYPE + "!=" +
+        Mailbox.TYPE_EAS_ACCOUNT_MAILBOX + " and " + MailboxColumns.SYNC_INTERVAL +
+        " IN (" + Mailbox.CHECK_INTERVAL_PING + ',' + Mailbox.CHECK_INTERVAL_PUSH + ')';
+    protected static final String WHERE_IN_ACCOUNT_AND_PUSHABLE =
+        MailboxColumns.ACCOUNT_KEY + "=? and type in (" + Mailbox.TYPE_INBOX + ','
+        + Mailbox.TYPE_EAS_ACCOUNT_MAILBOX + ',' + Mailbox.TYPE_CONTACTS + ','
+        + Mailbox.TYPE_CALENDAR + ')';
+    protected static final String WHERE_IN_ACCOUNT_AND_TYPE_INBOX =
+        MailboxColumns.ACCOUNT_KEY + "=? and type = " + Mailbox.TYPE_INBOX ;
+    private static final String WHERE_MAILBOX_KEY = Message.MAILBOX_KEY + "=?";
+    private static final String WHERE_PROTOCOL_EAS = HostAuthColumns.PROTOCOL + "=\"" +
+        AbstractSyncService.EAS_PROTOCOL + "\"";
+    private static final String WHERE_NOT_INTERVAL_NEVER_AND_ACCOUNT_KEY_IN =
+        "(" + MailboxColumns.TYPE + '=' + Mailbox.TYPE_OUTBOX
+        + " or " + MailboxColumns.SYNC_INTERVAL + "!=" + Mailbox.CHECK_INTERVAL_NEVER + ')'
+        + " and " + MailboxColumns.ACCOUNT_KEY + " in (";
+    private static final String ACCOUNT_KEY_IN = MailboxColumns.ACCOUNT_KEY + " in (";
+    private static final String WHERE_CALENDAR_ID = Events.CALENDAR_ID + "=?";
+
+    // Offsets into the syncStatus data for EAS that indicate type, exit status, and change count
+    // The format is S<type_char>:<exit_char>:<change_count>
+    public static final int STATUS_TYPE_CHAR = 1;
+    public static final int STATUS_EXIT_CHAR = 3;
+    public static final int STATUS_CHANGE_COUNT_OFFSET = 5;
+
+    // Ready for ping
+    public static final int PING_STATUS_OK = 0;
+    // Service already running (can't ping)
+    public static final int PING_STATUS_RUNNING = 1;
+    // Service waiting after I/O error (can't ping)
+    public static final int PING_STATUS_WAITING = 2;
+    // Service had a fatal error; can't run
+    public static final int PING_STATUS_UNABLE = 3;
+    // Service is disabled by user (checkbox)
+    public static final int PING_STATUS_DISABLED = 4;
+
+    private static final int MAX_CLIENT_CONNECTION_MANAGER_SHUTDOWNS = 1;
+
+    // We synchronize on this for all actions affecting the service and error maps
+    private static final Object sSyncLock = new Object();
+    // All threads can use this lock to wait for connectivity
+    public static final Object sConnectivityLock = new Object();
+    public static boolean sConnectivityHold = false;
+
+    // Keeps track of running services (by mailbox id)
+    private final HashMap<Long, AbstractSyncService> mServiceMap =
+        new HashMap<Long, AbstractSyncService>();
+    // Keeps track of services whose last sync ended with an error (by mailbox id)
+    /*package*/ ConcurrentHashMap<Long, SyncError> mSyncErrorMap =
+        new ConcurrentHashMap<Long, SyncError>();
+    // Keeps track of which services require a wake lock (by mailbox id)
+    private final HashMap<Long, Boolean> mWakeLocks = new HashMap<Long, Boolean>();
+    // Keeps track of PendingIntents for mailbox alarms (by mailbox id)
+    private final HashMap<Long, PendingIntent> mPendingIntents = new HashMap<Long, PendingIntent>();
+    // The actual WakeLock obtained by ExchangeService
+    private WakeLock mWakeLock = null;
+    // Keep our cached list of active Accounts here
+    public final AccountList mAccountList = new AccountList();
+
+    // Observers that we use to look for changed mail-related data
+    private final Handler mHandler = new Handler();
+    private AccountObserver mAccountObserver;
+    private MailboxObserver mMailboxObserver;
+    private SyncedMessageObserver mSyncedMessageObserver;
+
+    // Concurrent because CalendarSyncAdapter can modify the map during a wipe
+    private final ConcurrentHashMap<Long, CalendarObserver> mCalendarObservers =
+        new ConcurrentHashMap<Long, CalendarObserver>();
+
+    private ContentResolver mResolver;
+
+    // The singleton ExchangeService object, with its thread and stop flag
+    protected static ExchangeService INSTANCE;
+    private static Thread sServiceThread = null;
+    // Cached unique device id
+    private static String sDeviceId = null;
+    // ConnectionManager that all EAS threads can use
+    private static EmailClientConnectionManager sClientConnectionManager = null;
+    // Count of ClientConnectionManager shutdowns
+    private static volatile int sClientConnectionManagerShutdownCount = 0;
+
+    private static volatile boolean sStartingUp = false;
+    private static volatile boolean sStop = false;
+
+    // The reason for ExchangeService's next wakeup call
+    private String mNextWaitReason;
+    // Whether we have an unsatisfied "kick" pending
+    private boolean mKicked = false;
+
+    // Receiver of connectivity broadcasts
+    private ConnectivityReceiver mConnectivityReceiver = null;
+    private ConnectivityReceiver mBackgroundDataSettingReceiver = null;
+    private volatile boolean mBackgroundData = true;
+    // The most current NetworkInfo (from ConnectivityManager)
+    private NetworkInfo mNetworkInfo;
+
+    // Callbacks as set up via setCallback
+    private final RemoteCallbackList<IEmailServiceCallback> mCallbackList =
+        new RemoteCallbackList<IEmailServiceCallback>();
+
+    private interface ServiceCallbackWrapper {
+        public void call(IEmailServiceCallback cb) throws RemoteException;
+    }
+
+    /**
+     * Proxy that can be used by various sync adapters to tie into ExchangeService's callback system
+     * Used this way:  ExchangeService.callback().callbackMethod(args...);
+     * The proxy wraps checking for existence of a ExchangeService instance
+     * Failures of these callbacks can be safely ignored.
+     */
+    static private final IEmailServiceCallback.Stub sCallbackProxy =
+        new IEmailServiceCallback.Stub() {
+
+        /**
+         * Broadcast a callback to the everyone that's registered
+         *
+         * @param wrapper the ServiceCallbackWrapper used in the broadcast
+         */
+        private synchronized void broadcastCallback(ServiceCallbackWrapper wrapper) {
+            RemoteCallbackList<IEmailServiceCallback> callbackList =
+                (INSTANCE == null) ? null: INSTANCE.mCallbackList;
+            if (callbackList != null) {
+                // Call everyone on our callback list
+                int count = callbackList.beginBroadcast();
+                try {
+                    for (int i = 0; i < count; i++) {
+                        try {
+                            wrapper.call(callbackList.getBroadcastItem(i));
+                        } catch (RemoteException e) {
+                            // Safe to ignore
+                        } catch (RuntimeException e) {
+                            // We don't want an exception in one call to prevent other calls, so
+                            // we'll just log this and continue
+                            Log.e(TAG, "Caught RuntimeException in broadcast", e);
+                        }
+                    }
+                } finally {
+                    // No matter what, we need to finish the broadcast
+                    callbackList.finishBroadcast();
+                }
+            }
+        }
+
+        @Override
+        public void loadAttachmentStatus(final long messageId, final long attachmentId,
+                final int status, final int progress) {
+            broadcastCallback(new ServiceCallbackWrapper() {
+                @Override
+                public void call(IEmailServiceCallback cb) throws RemoteException {
+                    cb.loadAttachmentStatus(messageId, attachmentId, status, progress);
+                }
+            });
+        }
+
+        @Override
+        public void sendMessageStatus(final long messageId, final String subject, final int status,
+                final int progress) {
+            broadcastCallback(new ServiceCallbackWrapper() {
+                @Override
+                public void call(IEmailServiceCallback cb) throws RemoteException {
+                    cb.sendMessageStatus(messageId, subject, status, progress);
+                }
+            });
+        }
+
+        @Override
+        public void syncMailboxListStatus(final long accountId, final int status,
+                final int progress) {
+            broadcastCallback(new ServiceCallbackWrapper() {
+                @Override
+                public void call(IEmailServiceCallback cb) throws RemoteException {
+                    cb.syncMailboxListStatus(accountId, status, progress);
+                }
+            });
+        }
+
+        @Override
+        public void syncMailboxStatus(final long mailboxId, final int status,
+                final int progress) {
+            broadcastCallback(new ServiceCallbackWrapper() {
+                @Override
+                public void call(IEmailServiceCallback cb) throws RemoteException {
+                    cb.syncMailboxStatus(mailboxId, status, progress);
+                }
+            });
+        }
+
+        @Override
+        public void loadMessageStatus(long messageId, int statusCode, int progress)
+                throws RemoteException {
+        }
+    };
+
+    /**
+     * Create our EmailService implementation here.
+     */
+    private final IEmailService.Stub mBinder = new IEmailService.Stub() {
+
+        @Override
+        public int getApiLevel() {
+            return Api.LEVEL;
+        }
+
+        @Override
+        public Bundle validate(HostAuth hostAuth) throws RemoteException {
+            return AbstractSyncService.validate(EasSyncService.class,
+                    hostAuth, ExchangeService.this);
+        }
+
+        @Override
+        public Bundle autoDiscover(String userName, String password) throws RemoteException {
+            return new EasSyncService().tryAutodiscover(userName, password);
+        }
+
+        @Override
+        public void startSync(long mailboxId, boolean userRequest) throws RemoteException {
+            ExchangeService exchangeService = INSTANCE;
+            if (exchangeService == null) return;
+            checkExchangeServiceServiceRunning();
+            Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+            if (m == null) return;
+            Account acct = Account.restoreAccountWithId(exchangeService, m.mAccountKey);
+            if (acct == null) return;
+            // If this is a user request and we're being held, release the hold; this allows us to
+            // try again (the hold might have been specific to this account and released already)
+            if (userRequest) {
+                if (onSyncDisabledHold(acct)) {
+                    releaseSyncHolds(exchangeService, AbstractSyncService.EXIT_ACCESS_DENIED, acct);
+                    log("User requested sync of account in sync disabled hold; releasing");
+                } else if (onSecurityHold(acct)) {
+                    releaseSyncHolds(exchangeService, AbstractSyncService.EXIT_SECURITY_FAILURE,
+                            acct);
+                    log("User requested sync of account in security hold; releasing");
+                }
+                if (sConnectivityHold) {
+                    try {
+                        // UI is expecting the callbacks....
+                        sCallbackProxy.syncMailboxStatus(mailboxId, EmailServiceStatus.IN_PROGRESS,
+                                0);
+                        sCallbackProxy.syncMailboxStatus(mailboxId,
+                                EmailServiceStatus.CONNECTION_ERROR, 0);
+                    } catch (RemoteException ignore) {
+                    }
+                    return;
+                }
+            }
+            if (m.mType == Mailbox.TYPE_OUTBOX) {
+                // We're using SERVER_ID to indicate an error condition (it has no other use for
+                // sent mail)  Upon request to sync the Outbox, we clear this so that all messages
+                // are candidates for sending.
+                ContentValues cv = new ContentValues();
+                cv.put(SyncColumns.SERVER_ID, 0);
+                exchangeService.getContentResolver().update(Message.CONTENT_URI,
+                    cv, WHERE_MAILBOX_KEY, new String[] {Long.toString(mailboxId)});
+                // Clear the error state; the Outbox sync will be started from checkMailboxes
+                exchangeService.mSyncErrorMap.remove(mailboxId);
+                kick("start outbox");
+                // Outbox can't be synced in EAS
+                return;
+            } else if (!isSyncable(m)) {
+                try {
+                    // UI may be expecting the callbacks, so send them
+                    sCallbackProxy.syncMailboxStatus(mailboxId, EmailServiceStatus.IN_PROGRESS, 0);
+                    sCallbackProxy.syncMailboxStatus(mailboxId, EmailServiceStatus.SUCCESS, 0);
+                } catch (RemoteException ignore) {
+                    // We tried
+                }
+                return;
+            }
+            startManualSync(mailboxId, userRequest ? ExchangeService.SYNC_UI_REQUEST :
+                ExchangeService.SYNC_SERVICE_START_SYNC, null);
+        }
+
+        @Override
+        public void stopSync(long mailboxId) throws RemoteException {
+            stopManualSync(mailboxId);
+        }
+
+        @Override
+        public void loadAttachment(long attachmentId, boolean background) throws RemoteException {
+            Attachment att = Attachment.restoreAttachmentWithId(ExchangeService.this, attachmentId);
+            log("loadAttachment " + attachmentId + ": " + att.mFileName);
+            sendMessageRequest(new PartRequest(att, null, null));
+        }
+
+        @Override
+        public void updateFolderList(long accountId) throws RemoteException {
+            reloadFolderList(ExchangeService.this, accountId, false);
+        }
+
+        @Override
+        public void hostChanged(long accountId) throws RemoteException {
+            ExchangeService exchangeService = INSTANCE;
+            if (exchangeService == null) return;
+            ConcurrentHashMap<Long, SyncError> syncErrorMap = exchangeService.mSyncErrorMap;
+            // Go through the various error mailboxes
+            for (long mailboxId: syncErrorMap.keySet()) {
+                SyncError error = syncErrorMap.get(mailboxId);
+                // If it's a login failure, look a little harder
+                Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+                // If it's for the account whose host has changed, clear the error
+                // If the mailbox is no longer around, remove the entry in the map
+                if (m == null) {
+                    syncErrorMap.remove(mailboxId);
+                } else if (error != null && m.mAccountKey == accountId) {
+                    error.fatal = false;
+                    error.holdEndTime = 0;
+                }
+            }
+            // Stop any running syncs
+            exchangeService.stopAccountSyncs(accountId, true);
+            // Kick ExchangeService
+            kick("host changed");
+        }
+
+        @Override
+        public void setLogging(int flags) throws RemoteException {
+            Eas.setUserDebug(flags);
+        }
+
+        @Override
+        public void sendMeetingResponse(long messageId, int response) throws RemoteException {
+            sendMessageRequest(new MeetingResponseRequest(messageId, response));
+        }
+
+        @Override
+        public void loadMore(long messageId) throws RemoteException {
+        }
+
+        // The following three methods are not implemented in this version
+        @Override
+        public boolean createFolder(long accountId, String name) throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public boolean deleteFolder(long accountId, String name) throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public boolean renameFolder(long accountId, String oldName, String newName)
+                throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public void setCallback(IEmailServiceCallback cb) throws RemoteException {
+            mCallbackList.register(cb);
+        }
+
+        /**
+         * Delete PIM (calendar, contacts) data for the specified account
+         *
+         * @param accountId the account whose data should be deleted
+         * @throws RemoteException
+         */
+        @Override
+        public void deleteAccountPIMData(long accountId) throws RemoteException {
+            ExchangeService exchangeService = INSTANCE;
+            if (exchangeService == null) return;
+            // Stop any running syncs
+            ExchangeService.stopAccountSyncs(accountId);
+            // Delete the data
+            ExchangeService.deleteAccountPIMData(accountId);
+            long accountMailboxId = Mailbox.findMailboxOfType(exchangeService, accountId,
+                    Mailbox.TYPE_EAS_ACCOUNT_MAILBOX);
+            if (accountMailboxId != Mailbox.NO_MAILBOX) {
+                // Make sure the account mailbox is held due to security
+                synchronized(sSyncLock) {
+                    mSyncErrorMap.put(accountMailboxId, exchangeService.new SyncError(
+                            AbstractSyncService.EXIT_SECURITY_FAILURE, false));
+
+                }
+            }
+            // Make sure the reconciler runs
+            runAccountReconcilerSync(ExchangeService.this);
+        }
+
+        @Override
+        public int searchMessages(long accountId, SearchParams searchParams, long destMailboxId) {
+            ExchangeService exchangeService = INSTANCE;
+            if (exchangeService == null) return 0;
+            return Search.searchMessages(exchangeService, accountId, searchParams,
+                    destMailboxId);
+        }
+
+        @Override
+        public void sendMail(long accountId) throws RemoteException {
+        }
+    };
+
+    /**
+     * Return a list of all Accounts in EmailProvider.  Because the result of this call may be used
+     * in account reconciliation, an exception is thrown if the result cannot be guaranteed accurate
+     * @param context the caller's context
+     * @param accounts a list that Accounts will be added into
+     * @return the list of Accounts
+     * @throws ProviderUnavailableException if the list of Accounts cannot be guaranteed valid
+     */
+    private static AccountList collectEasAccounts(Context context, AccountList accounts) {
+        ContentResolver resolver = context.getContentResolver();
+        Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION, null, null,
+                null);
+        // We must throw here; callers might use the information we provide for reconciliation, etc.
+        if (c == null) throw new ProviderUnavailableException();
+        try {
+            ContentValues cv = new ContentValues();
+            while (c.moveToNext()) {
+                long hostAuthId = c.getLong(Account.CONTENT_HOST_AUTH_KEY_RECV_COLUMN);
+                if (hostAuthId > 0) {
+                    HostAuth ha = HostAuth.restoreHostAuthWithId(context, hostAuthId);
+                    if (ha != null && ha.mProtocol.equals("eas")) {
+                        Account account = new Account();
+                        account.restore(c);
+                        // Cache the HostAuth
+                        account.mHostAuthRecv = ha;
+                        accounts.add(account);
+                        // Fixup flags for inbox (should accept moved mail)
+                        Mailbox inbox = Mailbox.restoreMailboxOfType(context, account.mId,
+                                Mailbox.TYPE_INBOX);
+                        if (inbox != null &&
+                                ((inbox.mFlags & Mailbox.FLAG_ACCEPTS_MOVED_MAIL) == 0)) {
+                            cv.put(MailboxColumns.FLAGS,
+                                    inbox.mFlags | Mailbox.FLAG_ACCEPTS_MOVED_MAIL);
+                            resolver.update(
+                                    ContentUris.withAppendedId(Mailbox.CONTENT_URI, inbox.mId), cv,
+                                    null, null);
+                        }
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+        return accounts;
+    }
+
+    static class AccountList extends ArrayList<Account> {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public boolean add(Account account) {
+            // Cache the account manager account
+            account.mAmAccount = new android.accounts.Account(account.mEmailAddress,
+                    Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+            super.add(account);
+            return true;
+        }
+
+        public boolean contains(long id) {
+            for (Account account : this) {
+                if (account.mId == id) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public Account getById(long id) {
+            for (Account account : this) {
+                if (account.mId == id) {
+                    return account;
+                }
+            }
+            return null;
+        }
+
+        public Account getByName(String accountName) {
+            for (Account account : this) {
+                if (account.mEmailAddress.equalsIgnoreCase(accountName)) {
+                    return account;
+                }
+            }
+            return null;
+        }
+    }
+
+    public static void deleteAccountPIMData(long accountId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        Mailbox mailbox =
+            Mailbox.restoreMailboxOfType(exchangeService, accountId, Mailbox.TYPE_CONTACTS);
+        if (mailbox != null) {
+            EasSyncService service = EasSyncService.getServiceForMailbox(exchangeService, mailbox);
+            ContactsSyncAdapter adapter = new ContactsSyncAdapter(service);
+            adapter.wipe();
+        }
+        mailbox =
+            Mailbox.restoreMailboxOfType(exchangeService, accountId, Mailbox.TYPE_CALENDAR);
+        if (mailbox != null) {
+            EasSyncService service = EasSyncService.getServiceForMailbox(exchangeService, mailbox);
+            CalendarSyncAdapter adapter = new CalendarSyncAdapter(service);
+            adapter.wipe();
+        }
+    }
+
+    private boolean onSecurityHold(Account account) {
+        return (account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0;
+    }
+
+    private boolean onSyncDisabledHold(Account account) {
+        return (account.mFlags & Account.FLAGS_SYNC_DISABLED) != 0;
+    }
+
+    class AccountObserver extends ContentObserver {
+        String mSyncableEasMailboxSelector = null;
+        String mEasAccountSelector = null;
+
+        // Runs when ExchangeService first starts
+        public AccountObserver(Handler handler) {
+            super(handler);
+            // At startup, we want to see what EAS accounts exist and cache them
+            // TODO: Move database work out of UI thread
+            Context context = getContext();
+            synchronized (mAccountList) {
+                try {
+                    collectEasAccounts(context, mAccountList);
+                } catch (ProviderUnavailableException e) {
+                    // Just leave if EmailProvider is unavailable
+                    return;
+                }
+                // Create an account mailbox for any account without one
+                for (Account account : mAccountList) {
+                    int cnt = Mailbox.count(context, Mailbox.CONTENT_URI, "accountKey="
+                            + account.mId, null);
+                    if (cnt == 0) {
+                        // This case handles a newly created account
+                        addAccountMailbox(account.mId);
+                    }
+                }
+            }
+            // Run through accounts and update account hold information
+            Utility.runAsync(new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (mAccountList) {
+                        for (Account account : mAccountList) {
+                            if (onSecurityHold(account)) {
+                                // If we're in a security hold, and our policies are active, release
+                                // the hold
+                                if (PolicyServiceProxy.isActive(ExchangeService.this, null)) {
+                                    PolicyServiceProxy.setAccountHoldFlag(ExchangeService.this,
+                                            account, false);
+                                    log("isActive true; release hold for " + account.mDisplayName);
+                                }
+                            }
+                        }
+                    }
+                }});
+        }
+
+        /**
+         * Returns a String suitable for appending to a where clause that selects for all syncable
+         * mailboxes in all eas accounts
+         * @return a complex selection string that is not to be cached
+         */
+        public String getSyncableEasMailboxWhere() {
+            if (mSyncableEasMailboxSelector == null) {
+                StringBuilder sb = new StringBuilder(WHERE_NOT_INTERVAL_NEVER_AND_ACCOUNT_KEY_IN);
+                boolean first = true;
+                synchronized (mAccountList) {
+                    for (Account account : mAccountList) {
+                        if (!first) {
+                            sb.append(',');
+                        } else {
+                            first = false;
+                        }
+                        sb.append(account.mId);
+                    }
+                }
+                sb.append(')');
+                mSyncableEasMailboxSelector = sb.toString();
+            }
+            return mSyncableEasMailboxSelector;
+        }
+
+        /**
+         * Returns a String suitable for appending to a where clause that selects for all eas
+         * accounts.
+         * @return a String in the form "accountKey in (a, b, c...)" that is not to be cached
+         */
+        public String getAccountKeyWhere() {
+            if (mEasAccountSelector == null) {
+                StringBuilder sb = new StringBuilder(ACCOUNT_KEY_IN);
+                boolean first = true;
+                synchronized (mAccountList) {
+                    for (Account account : mAccountList) {
+                        if (!first) {
+                            sb.append(',');
+                        } else {
+                            first = false;
+                        }
+                        sb.append(account.mId);
+                    }
+                }
+                sb.append(')');
+                mEasAccountSelector = sb.toString();
+            }
+            return mEasAccountSelector;
+        }
+
+        private void onAccountChanged() {
+            try {
+                maybeStartExchangeServiceThread();
+                Context context = getContext();
+
+                // A change to the list requires us to scan for deletions (stop running syncs)
+                // At startup, we want to see what accounts exist and cache them
+                AccountList currentAccounts = new AccountList();
+                try {
+                    collectEasAccounts(context, currentAccounts);
+                } catch (ProviderUnavailableException e) {
+                    // Just leave if EmailProvider is unavailable
+                    return;
+                }
+                synchronized (mAccountList) {
+                    for (Account account : mAccountList) {
+                        boolean accountIncomplete =
+                            (account.mFlags & Account.FLAGS_INCOMPLETE) != 0;
+                        // If the current list doesn't include this account and the account wasn't
+                        // incomplete, then this is a deletion
+                        if (!currentAccounts.contains(account.mId) && !accountIncomplete) {
+                            // The implication is that the account has been deleted; let's find out
+                            alwaysLog("Observer found deleted account: " + account.mDisplayName);
+                            // Run the reconciler (the reconciliation itself runs in the Email app)
+                            runAccountReconcilerSync(ExchangeService.this);
+                            // See if the account is still around
+                            Account deletedAccount =
+                                Account.restoreAccountWithId(context, account.mId);
+                            if (deletedAccount != null) {
+                                // It is; add it to our account list
+                                alwaysLog("Account still in provider: " + account.mDisplayName);
+                                currentAccounts.add(account);
+                            } else {
+                                // It isn't; stop syncs and clear our selectors
+                                alwaysLog("Account deletion confirmed: " + account.mDisplayName);
+                                stopAccountSyncs(account.mId, true);
+                                mSyncableEasMailboxSelector = null;
+                                mEasAccountSelector = null;
+                            }
+                        } else {
+                            // Get the newest version of this account
+                            Account updatedAccount =
+                                Account.restoreAccountWithId(context, account.mId);
+                            if (updatedAccount == null) continue;
+                            if (account.mSyncInterval != updatedAccount.mSyncInterval
+                                    || account.mSyncLookback != updatedAccount.mSyncLookback) {
+                                // Set the inbox interval to the interval of the Account
+                                // This setting should NOT affect other boxes
+                                ContentValues cv = new ContentValues();
+                                cv.put(MailboxColumns.SYNC_INTERVAL, updatedAccount.mSyncInterval);
+                                getContentResolver().update(Mailbox.CONTENT_URI, cv,
+                                        WHERE_IN_ACCOUNT_AND_TYPE_INBOX, new String[] {
+                                        Long.toString(account.mId)
+                                });
+                                // Stop all current syncs; the appropriate ones will restart
+                                log("Account " + account.mDisplayName + " changed; stop syncs");
+                                stopAccountSyncs(account.mId, true);
+                            }
+
+                            // See if this account is no longer on security hold
+                            if (onSecurityHold(account) && !onSecurityHold(updatedAccount)) {
+                                releaseSyncHolds(ExchangeService.this,
+                                        AbstractSyncService.EXIT_SECURITY_FAILURE, account);
+                            }
+
+                            // Put current values into our cached account
+                            account.mSyncInterval = updatedAccount.mSyncInterval;
+                            account.mSyncLookback = updatedAccount.mSyncLookback;
+                            account.mFlags = updatedAccount.mFlags;
+                        }
+                    }
+                    // Look for new accounts
+                    for (Account account : currentAccounts) {
+                        if (!mAccountList.contains(account.mId)) {
+                            // Don't forget to cache the HostAuth
+                            HostAuth ha = HostAuth.restoreHostAuthWithId(getContext(),
+                                    account.mHostAuthKeyRecv);
+                            if (ha == null) continue;
+                            account.mHostAuthRecv = ha;
+                            // This is an addition; create our magic hidden mailbox...
+                            log("Account observer found new account: " + account.mDisplayName);
+                            addAccountMailbox(account.mId);
+                            mAccountList.add(account);
+                            mSyncableEasMailboxSelector = null;
+                            mEasAccountSelector = null;
+                        }
+                    }
+                    // Finally, make sure our account list is up to date
+                    mAccountList.clear();
+                    mAccountList.addAll(currentAccounts);
+                }
+
+                // See if there's anything to do...
+                kick("account changed");
+            } catch (ProviderUnavailableException e) {
+                alwaysLog("Observer failed; provider unavailable");
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            new Thread(new Runnable() {
+               @Override
+            public void run() {
+                   onAccountChanged();
+                }}, "Account Observer").start();
+        }
+
+        private void addAccountMailbox(long acctId) {
+            Account acct = Account.restoreAccountWithId(getContext(), acctId);
+            Mailbox main = new Mailbox();
+            main.mDisplayName = Eas.ACCOUNT_MAILBOX_PREFIX;
+            main.mServerId = Eas.ACCOUNT_MAILBOX_PREFIX + System.nanoTime();
+            main.mAccountKey = acct.mId;
+            main.mType = Mailbox.TYPE_EAS_ACCOUNT_MAILBOX;
+            main.mSyncInterval = Mailbox.CHECK_INTERVAL_PUSH;
+            main.mFlagVisible = false;
+            main.save(getContext());
+            log("Initializing account: " + acct.mDisplayName);
+        }
+
+    }
+
+    /**
+     * Register a specific Calendar's data observer; we need to recognize when the SYNC_EVENTS
+     * column has changed (when sync has turned off or on)
+     * @param account the Account whose Calendar we're observing
+     */
+    private void registerCalendarObserver(Account account) {
+        // Get a new observer
+        CalendarObserver observer = new CalendarObserver(mHandler, account);
+        if (observer.mCalendarId != 0) {
+            // If we find the Calendar (and we'd better) register it and store it in the map
+            mCalendarObservers.put(account.mId, observer);
+            mResolver.registerContentObserver(
+                    ContentUris.withAppendedId(Calendars.CONTENT_URI, observer.mCalendarId), false,
+                    observer);
+        }
+    }
+
+    /**
+     * Unregister all CalendarObserver's
+     */
+    static public void unregisterCalendarObservers() {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        ContentResolver resolver = exchangeService.mResolver;
+        for (CalendarObserver observer: exchangeService.mCalendarObservers.values()) {
+            resolver.unregisterContentObserver(observer);
+        }
+        exchangeService.mCalendarObservers.clear();
+    }
+
+    /**
+     * Return the syncable state of an account's calendar, as determined by the sync_events column
+     * of our Calendar (from CalendarProvider2)
+     * Note that the current state of sync_events is cached in our CalendarObserver
+     * @param accountId the id of the account whose calendar we are checking
+     * @return whether or not syncing of events is enabled
+     */
+    private boolean isCalendarEnabled(long accountId) {
+        CalendarObserver observer = mCalendarObservers.get(accountId);
+        if (observer != null) {
+            return (observer.mSyncEvents == 1);
+        }
+        // If there's no observer, there's no Calendar in CalendarProvider2, so we return true
+        // to allow Calendar creation
+        return true;
+    }
+
+    private class CalendarObserver extends ContentObserver {
+        long mAccountId;
+        long mCalendarId;
+        long mSyncEvents;
+        String mAccountName;
+
+        public CalendarObserver(Handler handler, Account account) {
+            super(handler);
+            mAccountId = account.mId;
+            mAccountName = account.mEmailAddress;
+
+            // Find the Calendar for this account
+            Cursor c = mResolver.query(Calendars.CONTENT_URI,
+                    new String[] {Calendars._ID, Calendars.SYNC_EVENTS},
+                    CalendarSyncAdapter.CALENDAR_SELECTION,
+                    new String[] {account.mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE},
+                    null);
+            if (c != null) {
+                // Save its id and its sync events status
+                try {
+                    if (c.moveToFirst()) {
+                        mCalendarId = c.getLong(0);
+                        mSyncEvents = c.getLong(1);
+                    }
+                } finally {
+                    c.close();
+                }
+            }
+        }
+
+        @Override
+        public synchronized void onChange(boolean selfChange) {
+            // See if the user has changed syncing of our calendar
+            if (!selfChange) {
+                new Thread(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            Cursor c = mResolver.query(Calendars.CONTENT_URI,
+                                    new String[] {Calendars.SYNC_EVENTS}, Calendars._ID + "=?",
+                                    new String[] {Long.toString(mCalendarId)}, null);
+                            if (c == null) return;
+                            // Get its sync events; if it's changed, we've got work to do
+                            try {
+                                if (c.moveToFirst()) {
+                                    long newSyncEvents = c.getLong(0);
+                                    if (newSyncEvents != mSyncEvents) {
+                                        log("_sync_events changed for calendar in " + mAccountName);
+                                        Mailbox mailbox = Mailbox.restoreMailboxOfType(INSTANCE,
+                                                mAccountId, Mailbox.TYPE_CALENDAR);
+                                        // Sanity check for mailbox deletion
+                                        if (mailbox == null) return;
+                                        ContentValues cv = new ContentValues();
+                                        if (newSyncEvents == 0) {
+                                            // When sync is disabled, we're supposed to delete
+                                            // all events in the calendar
+                                            log("Deleting events and setting syncKey to 0 for " +
+                                                    mAccountName);
+                                            // First, stop any sync that's ongoing
+                                            stopManualSync(mailbox.mId);
+                                            // Set the syncKey to 0 (reset)
+                                            EasSyncService service =
+                                                EasSyncService.getServiceForMailbox(
+                                                        INSTANCE, mailbox);
+                                            CalendarSyncAdapter adapter =
+                                                new CalendarSyncAdapter(service);
+                                            try {
+                                                adapter.setSyncKey("0", false);
+                                            } catch (IOException e) {
+                                                // The provider can't be reached; nothing to be done
+                                            }
+                                            // Reset the sync key locally and stop syncing
+                                            cv.put(Mailbox.SYNC_KEY, "0");
+                                            cv.put(Mailbox.SYNC_INTERVAL,
+                                                    Mailbox.CHECK_INTERVAL_NEVER);
+                                            mResolver.update(ContentUris.withAppendedId(
+                                                    Mailbox.CONTENT_URI, mailbox.mId), cv, null,
+                                                    null);
+                                            // Delete all events using the sync adapter
+                                            // parameter so that the deletion is only local
+                                            Uri eventsAsSyncAdapter =
+                                                CalendarSyncAdapter.asSyncAdapter(
+                                                    Events.CONTENT_URI,
+                                                    mAccountName,
+                                                    Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+                                            mResolver.delete(eventsAsSyncAdapter, WHERE_CALENDAR_ID,
+                                                    new String[] {Long.toString(mCalendarId)});
+                                        } else {
+                                            // Make this a push mailbox and kick; this will start
+                                            // a resync of the Calendar; the account mailbox will
+                                            // ping on this during the next cycle of the ping loop
+                                            cv.put(Mailbox.SYNC_INTERVAL,
+                                                    Mailbox.CHECK_INTERVAL_PUSH);
+                                            mResolver.update(ContentUris.withAppendedId(
+                                                    Mailbox.CONTENT_URI, mailbox.mId), cv, null,
+                                                    null);
+                                            kick("calendar sync changed");
+                                        }
+
+                                        // Save away the new value
+                                        mSyncEvents = newSyncEvents;
+                                    }
+                                }
+                            } finally {
+                                c.close();
+                            }
+                        } catch (ProviderUnavailableException e) {
+                            Log.w(TAG, "Observer failed; provider unavailable");
+                        }
+                    }}, "Calendar Observer").start();
+            }
+        }
+    }
+
+    private class MailboxObserver extends ContentObserver {
+        public MailboxObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            // See if there's anything to do...
+            if (!selfChange) {
+                kick("mailbox changed");
+            }
+        }
+    }
+
+    private class SyncedMessageObserver extends ContentObserver {
+        Intent syncAlarmIntent = new Intent(INSTANCE, EmailSyncAlarmReceiver.class);
+        PendingIntent syncAlarmPendingIntent =
+            PendingIntent.getBroadcast(INSTANCE, 0, syncAlarmIntent, 0);
+        AlarmManager alarmManager = (AlarmManager)INSTANCE.getSystemService(Context.ALARM_SERVICE);
+
+        public SyncedMessageObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            alarmManager.set(AlarmManager.RTC_WAKEUP,
+                    System.currentTimeMillis() + 10*SECONDS, syncAlarmPendingIntent);
+        }
+    }
+
+    static public IEmailServiceCallback callback() {
+        return sCallbackProxy;
+    }
+
+    static public Account getAccountById(long accountId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            AccountList accountList = exchangeService.mAccountList;
+            synchronized (accountList) {
+                return accountList.getById(accountId);
+            }
+        }
+        return null;
+    }
+
+    static public Account getAccountByName(String accountName) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            AccountList accountList = exchangeService.mAccountList;
+            synchronized (accountList) {
+                return accountList.getByName(accountName);
+            }
+        }
+        return null;
+    }
+
+    static public String getEasAccountSelector() {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null && exchangeService.mAccountObserver != null) {
+            return exchangeService.mAccountObserver.getAccountKeyWhere();
+        }
+        return null;
+    }
+
+    public class SyncStatus {
+        static public final int NOT_RUNNING = 0;
+        static public final int DIED = 1;
+        static public final int SYNC = 2;
+        static public final int IDLE = 3;
+    }
+
+    /*package*/ class SyncError {
+        int reason;
+        boolean fatal = false;
+        long holdDelay = 15*SECONDS;
+        long holdEndTime = System.currentTimeMillis() + holdDelay;
+
+        SyncError(int _reason, boolean _fatal) {
+            reason = _reason;
+            fatal = _fatal;
+        }
+
+        /**
+         * We double the holdDelay from 15 seconds through 4 mins
+         */
+        void escalate() {
+            if (holdDelay < HOLD_DELAY_MAXIMUM) {
+                holdDelay *= 2;
+            }
+            holdEndTime = System.currentTimeMillis() + holdDelay;
+        }
+    }
+
+    private void logSyncHolds() {
+        if (Eas.USER_LOG) {
+            log("Sync holds:");
+            long time = System.currentTimeMillis();
+            for (long mailboxId : mSyncErrorMap.keySet()) {
+                Mailbox m = Mailbox.restoreMailboxWithId(this, mailboxId);
+                if (m == null) {
+                    log("Mailbox " + mailboxId + " no longer exists");
+                } else {
+                    SyncError error = mSyncErrorMap.get(mailboxId);
+                    if (error != null) {
+                        log("Mailbox " + m.mDisplayName + ", error = " + error.reason
+                                + ", fatal = " + error.fatal);
+                        if (error.holdEndTime > 0) {
+                            log("Hold ends in " + ((error.holdEndTime - time) / 1000) + "s");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Release security holds for the specified account
+     * @param account the account whose Mailboxes should be released from security hold
+     */
+    static public void releaseSecurityHold(Account account) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.releaseSyncHolds(INSTANCE, AbstractSyncService.EXIT_SECURITY_FAILURE,
+                    account);
+        }
+    }
+
+    /**
+     * Release a specific type of hold (the reason) for the specified Account; if the account
+     * is null, mailboxes from all accounts with the specified hold will be released
+     * @param reason the reason for the SyncError (AbstractSyncService.EXIT_XXX)
+     * @param account an Account whose mailboxes should be released (or all if null)
+     * @return whether or not any mailboxes were released
+     */
+    /*package*/ boolean releaseSyncHolds(Context context, int reason, Account account) {
+        boolean holdWasReleased = releaseSyncHoldsImpl(context, reason, account);
+        kick("security release");
+        return holdWasReleased;
+    }
+
+    private boolean releaseSyncHoldsImpl(Context context, int reason, Account account) {
+        boolean holdWasReleased = false;
+        for (long mailboxId: mSyncErrorMap.keySet()) {
+            if (account != null) {
+                Mailbox m = Mailbox.restoreMailboxWithId(context, mailboxId);
+                if (m == null) {
+                    mSyncErrorMap.remove(mailboxId);
+                } else if (m.mAccountKey != account.mId) {
+                    continue;
+                }
+            }
+            SyncError error = mSyncErrorMap.get(mailboxId);
+            if (error != null && error.reason == reason) {
+                mSyncErrorMap.remove(mailboxId);
+                holdWasReleased = true;
+            }
+        }
+        return holdWasReleased;
+    }
+
+    /**
+     * Reconcile Exchange accounts with AccountManager (asynchronous)
+     * @param context the caller's Context
+     */
+    public static void reconcileAccounts(final Context context) {
+        Utility.runAsync(new Runnable() {
+            @Override
+            public void run() {
+                ExchangeService exchangeService = INSTANCE;
+                if (exchangeService != null) {
+                    exchangeService.runAccountReconcilerSync(context);
+                }
+            }});
+    }
+
+    /**
+     * Blocking call to the account reconciler
+     */
+    public static void runAccountReconcilerSync(Context context) {
+        alwaysLog("Reconciling accounts...");
+        new AccountServiceProxy(context).reconcileAccounts(
+                HostAuth.SCHEME_EAS, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+    }
+
+    public static void log(String str) {
+        log(TAG, str);
+    }
+
+    public static void log(String tag, String str) {
+        if (Eas.USER_LOG) {
+            Log.d(tag, str);
+            if (Eas.FILE_LOG) {
+                FileLogger.log(tag, str);
+            }
+        }
+    }
+
+    public static void alwaysLog(String str) {
+        if (!Eas.USER_LOG) {
+            Log.d(TAG, str);
+        } else {
+            log(str);
+        }
+    }
+
+    /**
+     * EAS requires a unique device id, so that sync is possible from a variety of different
+     * devices (e.g. the syncKey is specific to a device)  If we're on an emulator or some other
+     * device that doesn't provide one, we can create it as "device".
+     * This would work on a real device as well, but it would be better to use the "real" id if
+     * it's available
+     */
+    static public String getDeviceId(Context context) throws IOException {
+        if (sDeviceId == null) {
+            sDeviceId = new AccountServiceProxy(context).getDeviceId();
+            alwaysLog("Received deviceId from Email app: " + sDeviceId);
+        }
+        return sDeviceId;
+    }
+
+    @Override
+    public IBinder onBind(Intent arg0) {
+        return mBinder;
+    }
+
+    static public ConnPerRoute sConnPerRoute = new ConnPerRoute() {
+        @Override
+        public int getMaxForRoute(HttpRoute route) {
+            return 8;
+        }
+    };
+
+    static public synchronized EmailClientConnectionManager getClientConnectionManager() {
+        if (sClientConnectionManager == null) {
+            // After two tries, kill the process.  Most likely, this will happen in the background
+            // The service will restart itself after about 5 seconds
+            if (sClientConnectionManagerShutdownCount > MAX_CLIENT_CONNECTION_MANAGER_SHUTDOWNS) {
+                alwaysLog("Shutting down process to unblock threads");
+                Process.killProcess(Process.myPid());
+            }
+            HttpParams params = new BasicHttpParams();
+            params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 25);
+            params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, sConnPerRoute);
+            sClientConnectionManager = EmailClientConnectionManager.newInstance(params);
+        }
+        // Null is a valid return result if we get an exception
+        return sClientConnectionManager;
+    }
+
+    static private synchronized void shutdownConnectionManager() {
+        if (sClientConnectionManager != null) {
+            log("Shutting down ClientConnectionManager");
+            sClientConnectionManager.shutdown();
+            sClientConnectionManagerShutdownCount++;
+            sClientConnectionManager = null;
+        }
+    }
+
+    public static void stopAccountSyncs(long acctId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.stopAccountSyncs(acctId, true);
+        }
+    }
+
+    private void stopAccountSyncs(long acctId, boolean includeAccountMailbox) {
+        synchronized (sSyncLock) {
+            List<Long> deletedBoxes = new ArrayList<Long>();
+            for (Long mid : mServiceMap.keySet()) {
+                Mailbox box = Mailbox.restoreMailboxWithId(this, mid);
+                if (box != null) {
+                    if (box.mAccountKey == acctId) {
+                        if (!includeAccountMailbox &&
+                                box.mType == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+                            AbstractSyncService svc = mServiceMap.get(mid);
+                            if (svc != null) {
+                                svc.stop();
+                            }
+                            continue;
+                        }
+                        AbstractSyncService svc = mServiceMap.get(mid);
+                        if (svc != null) {
+                            svc.stop();
+                            Thread t = svc.mThread;
+                            if (t != null) {
+                                t.interrupt();
+                            }
+                        }
+                        deletedBoxes.add(mid);
+                    }
+                }
+            }
+            for (Long mid : deletedBoxes) {
+                releaseMailbox(mid);
+            }
+        }
+    }
+
+    static private void reloadFolderListFailed(long accountId) {
+        try {
+            callback().syncMailboxListStatus(accountId,
+                    EmailServiceStatus.ACCOUNT_UNINITIALIZED, 0);
+        } catch (RemoteException e1) {
+            // Don't care if this fails
+        }
+    }
+
+    static public void reloadFolderList(Context context, long accountId, boolean force) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        Cursor c = context.getContentResolver().query(Mailbox.CONTENT_URI,
+                Mailbox.CONTENT_PROJECTION, MailboxColumns.ACCOUNT_KEY + "=? AND " +
+                MailboxColumns.TYPE + "=?",
+                new String[] {Long.toString(accountId),
+                    Long.toString(Mailbox.TYPE_EAS_ACCOUNT_MAILBOX)}, null);
+        try {
+            if (c.moveToFirst()) {
+                synchronized(sSyncLock) {
+                    Mailbox mailbox = new Mailbox();
+                    mailbox.restore(c);
+                    Account acct = Account.restoreAccountWithId(context, accountId);
+                    if (acct == null) {
+                        reloadFolderListFailed(accountId);
+                        return;
+                    }
+                    String syncKey = acct.mSyncKey;
+                    // No need to reload the list if we don't have one
+                    if (!force && (syncKey == null || syncKey.equals("0"))) {
+                        reloadFolderListFailed(accountId);
+                        return;
+                    }
+
+                    // Change all ping/push boxes to push/hold
+                    ContentValues cv = new ContentValues();
+                    cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH_HOLD);
+                    context.getContentResolver().update(Mailbox.CONTENT_URI, cv,
+                            WHERE_PUSH_OR_PING_NOT_ACCOUNT_MAILBOX,
+                            new String[] {Long.toString(accountId)});
+                    log("Set push/ping boxes to push/hold");
+
+                    long id = mailbox.mId;
+                    AbstractSyncService svc = exchangeService.mServiceMap.get(id);
+                    // Tell the service we're done
+                    if (svc != null) {
+                        synchronized (svc.getSynchronizer()) {
+                            svc.stop();
+                            // Interrupt the thread so that it can stop
+                            Thread thread = svc.mThread;
+                            if (thread != null) {
+                                thread.setName(thread.getName() + " (Stopped)");
+                                thread.interrupt();
+                            }
+                        }
+                        // Abandon the service
+                        exchangeService.releaseMailbox(id);
+                        // And have it start naturally
+                        kick("reload folder list");
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Informs ExchangeService that an account has a new folder list; as a result, any existing
+     * folder might have become invalid.  Therefore, we act as if the account has been deleted, and
+     * then we reinitialize it.
+     *
+     * @param acctId
+     */
+    static public void stopNonAccountMailboxSyncsForAccount(long acctId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.stopAccountSyncs(acctId, false);
+            kick("reload folder list");
+        }
+    }
+
+    private void acquireWakeLock(long id) {
+        synchronized (mWakeLocks) {
+            Boolean lock = mWakeLocks.get(id);
+            if (lock == null) {
+                if (mWakeLock == null) {
+                    PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+                    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MAIL_SERVICE");
+                    mWakeLock.acquire();
+                    //log("+WAKE LOCK ACQUIRED");
+                }
+                mWakeLocks.put(id, true);
+             }
+        }
+    }
+
+    private void releaseWakeLock(long id) {
+        synchronized (mWakeLocks) {
+            Boolean lock = mWakeLocks.get(id);
+            if (lock != null) {
+                mWakeLocks.remove(id);
+                if (mWakeLocks.isEmpty()) {
+                    if (mWakeLock != null) {
+                        mWakeLock.release();
+                    }
+                    mWakeLock = null;
+                    //log("+WAKE LOCK RELEASED");
+                } else {
+                }
+            }
+        }
+    }
+
+    static public String alarmOwner(long id) {
+        if (id == EXTRA_MAILBOX_ID) {
+            return "ExchangeService";
+        } else {
+            String name = Long.toString(id);
+            if (Eas.USER_LOG && INSTANCE != null) {
+                Mailbox m = Mailbox.restoreMailboxWithId(INSTANCE, id);
+                if (m != null) {
+                    name = m.mDisplayName + '(' + m.mAccountKey + ')';
+                }
+            }
+            return "Mailbox " + name;
+        }
+    }
+
+    private void clearAlarm(long id) {
+        synchronized (mPendingIntents) {
+            PendingIntent pi = mPendingIntents.get(id);
+            if (pi != null) {
+                AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+                alarmManager.cancel(pi);
+                //log("+Alarm cleared for " + alarmOwner(id));
+                mPendingIntents.remove(id);
+            }
+        }
+    }
+
+    private void setAlarm(long id, long millis) {
+        synchronized (mPendingIntents) {
+            PendingIntent pi = mPendingIntents.get(id);
+            if (pi == null) {
+                Intent i = new Intent(this, MailboxAlarmReceiver.class);
+                i.putExtra("mailbox", id);
+                i.setData(Uri.parse("Box" + id));
+                pi = PendingIntent.getBroadcast(this, 0, i, 0);
+                mPendingIntents.put(id, pi);
+
+                AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+                alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + millis, pi);
+                //log("+Alarm set for " + alarmOwner(id) + ", " + millis/1000 + "s");
+            }
+        }
+    }
+
+    private void clearAlarms() {
+        AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+        synchronized (mPendingIntents) {
+            for (PendingIntent pi : mPendingIntents.values()) {
+                alarmManager.cancel(pi);
+            }
+            mPendingIntents.clear();
+        }
+    }
+
+    static public void runAwake(long id) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.acquireWakeLock(id);
+            exchangeService.clearAlarm(id);
+        }
+    }
+
+    static public void runAsleep(long id, long millis) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.setAlarm(id, millis);
+            exchangeService.releaseWakeLock(id);
+        }
+    }
+
+    static public void clearWatchdogAlarm(long id) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.clearAlarm(id);
+        }
+    }
+
+    static public void setWatchdogAlarm(long id, long millis) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.setAlarm(id, millis);
+        }
+    }
+
+    static public void alert(Context context, final long id) {
+        final ExchangeService exchangeService = INSTANCE;
+        checkExchangeServiceServiceRunning();
+        if (id < 0) {
+            log("ExchangeService alert");
+            kick("ping ExchangeService");
+        } else if (exchangeService == null) {
+            context.startService(new Intent(context, ExchangeService.class));
+        } else {
+            final AbstractSyncService service = exchangeService.mServiceMap.get(id);
+            if (service != null) {
+                // Handle alerts in a background thread, as we are typically called from a
+                // broadcast receiver, and are therefore running in the UI thread
+                String threadName = "ExchangeService Alert: ";
+                if (service.mMailbox != null) {
+                    threadName += service.mMailbox.mDisplayName;
+                }
+                new Thread(new Runnable() {
+                   @Override
+                public void run() {
+                       Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, id);
+                       if (m != null) {
+                           // We ignore drafts completely (doesn't sync).  Changes in Outbox are
+                           // handled in the checkMailboxes loop, so we can ignore these pings.
+                           if (Eas.USER_LOG) {
+                               Log.d(TAG, "Alert for mailbox " + id + " (" + m.mDisplayName + ")");
+                           }
+                           if (m.mType == Mailbox.TYPE_DRAFTS || m.mType == Mailbox.TYPE_OUTBOX) {
+                               String[] args = new String[] {Long.toString(m.mId)};
+                               ContentResolver resolver = INSTANCE.mResolver;
+                               resolver.delete(Message.DELETED_CONTENT_URI, WHERE_MAILBOX_KEY,
+                                       args);
+                               resolver.delete(Message.UPDATED_CONTENT_URI, WHERE_MAILBOX_KEY,
+                                       args);
+                               return;
+                           }
+                           service.mAccount = Account.restoreAccountWithId(INSTANCE, m.mAccountKey);
+                           service.mMailbox = m;
+                           // Send the alarm to the sync service
+                           if (!service.alarm()) {
+                               // A false return means that we were forced to interrupt the thread
+                               // In this case, we release the mailbox so that we can start another
+                               // thread to do the work
+                               log("Alarm failed; releasing mailbox");
+                               synchronized(sSyncLock) {
+                                   exchangeService.releaseMailbox(id);
+                               }
+                               // Shutdown the connection manager; this should close all of our
+                               // sockets and generate IOExceptions all around.
+                               ExchangeService.shutdownConnectionManager();
+                           }
+                       }
+                    }}, threadName).start();
+            }
+        }
+    }
+
+    public class ConnectivityReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+                Bundle b = intent.getExtras();
+                if (b != null) {
+                    NetworkInfo a = (NetworkInfo)b.get(ConnectivityManager.EXTRA_NETWORK_INFO);
+                    String info = "Connectivity alert for " + a.getTypeName();
+                    State state = a.getState();
+                    if (state == State.CONNECTED) {
+                        info += " CONNECTED";
+                        log(info);
+                        synchronized (sConnectivityLock) {
+                            sConnectivityLock.notifyAll();
+                        }
+                        kick("connected");
+                    } else if (state == State.DISCONNECTED) {
+                        info += " DISCONNECTED";
+                        log(info);
+                        kick("disconnected");
+                    }
+                }
+            } else if (intent.getAction().equals(
+                    ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED)) {
+                ConnectivityManager cm =
+                        (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+                mBackgroundData = cm.getBackgroundDataSetting();
+                // If background data is now on, we want to kick ExchangeService
+                if (mBackgroundData) {
+                    kick("background data on");
+                    log("Background data on; restart syncs");
+                // Otherwise, stop all syncs
+                } else {
+                    log("Background data off: stop all syncs");
+                    EmailAsyncTask.runAsyncParallel(new Runnable() {
+                        @Override
+                        public void run() {
+                            synchronized (mAccountList) {
+                                for (Account account : mAccountList)
+                                    ExchangeService.stopAccountSyncs(account.mId);
+                            }
+                        }});
+                }
+            }
+        }
+    }
+
+    /**
+     * Starts a service thread and enters it into the service map
+     * This is the point of instantiation of all sync threads
+     * @param service the service to start
+     * @param m the Mailbox on which the service will operate
+     */
+    private void startServiceThread(AbstractSyncService service) {
+        synchronized (sSyncLock) {
+            Mailbox mailbox = service.mMailbox;
+            String mailboxName = mailbox.mDisplayName;
+            String accountName = service.mAccount.mDisplayName;
+            Thread thread = new Thread(service, mailboxName + "[" + accountName + "]");
+            log("Starting thread for " + mailboxName + " in account " + accountName);
+            thread.start();
+            mServiceMap.put(mailbox.mId, service);
+            runAwake(mailbox.mId);
+            if (mailbox.mServerId != null && mailbox.mType != Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+                stopPing(mailbox.mAccountKey);
+            }
+        }
+    }
+
+    /**
+     * Stop any ping in progress for the given account
+     * @param accountId
+     */
+    private void stopPing(long accountId) {
+        // Go through our active mailboxes looking for the right one
+        synchronized (sSyncLock) {
+            for (long mailboxId: mServiceMap.keySet()) {
+                Mailbox m = Mailbox.restoreMailboxWithId(this, mailboxId);
+                if (m != null) {
+                    String serverId = m.mServerId;
+                    if (m.mAccountKey == accountId && serverId != null &&
+                          m.mType == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+                        // Here's our account mailbox; reset him (stopping pings)
+                        AbstractSyncService svc = mServiceMap.get(mailboxId);
+                        svc.reset();
+                    }
+                }
+            }
+        }
+    }
+
+    private void requestSync(Mailbox m, int reason, Request req) {
+        int syncStatus = EmailContent.SYNC_STATUS_BACKGROUND;
+        // Don't sync if there's no connectivity
+        if (sConnectivityHold || (m == null) || sStop) {
+            if (reason >= SYNC_CALLBACK_START) {
+                try {
+                    sCallbackProxy.syncMailboxStatus(m.mId, EmailServiceStatus.CONNECTION_ERROR, 0);
+                } catch (RemoteException e) {
+                    // We tried...
+                }
+            }
+            return;
+        }
+        synchronized (sSyncLock) {
+            Account acct = Account.restoreAccountWithId(this, m.mAccountKey);
+            if (acct != null) {
+                // Always make sure there's not a running instance of this service
+                AbstractSyncService service = mServiceMap.get(m.mId);
+                if (service == null) {
+                    service = EasSyncService.getServiceForMailbox(this, m);
+                    if (!((EasSyncService)service).mIsValid) return;
+                    service.mSyncReason = reason;
+                    if (req != null) {
+                        service.addRequest(req);
+                    }
+                    startServiceThread(service);
+                    if (reason >= SYNC_CALLBACK_START) {
+                        syncStatus = EmailContent.SYNC_STATUS_USER;
+                    }
+                    setMailboxSyncStatus(m.mId, syncStatus);
+                }
+            }
+        }
+    }
+
+    private void setMailboxSyncStatus(long id, int status) {
+        ContentValues values = new ContentValues();
+        values.put(Mailbox.UI_SYNC_STATUS, status);
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, id), values, null, null);
+    }
+
+    private void setMailboxLastSyncResult(long id, int result) {
+        ContentValues values = new ContentValues();
+        values.put(Mailbox.UI_LAST_SYNC_RESULT, result);
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, id), values, null, null);
+    }
+
+    private void stopServiceThreads() {
+        synchronized (sSyncLock) {
+            ArrayList<Long> toStop = new ArrayList<Long>();
+
+            // Keep track of which services to stop
+            for (Long mailboxId : mServiceMap.keySet()) {
+                toStop.add(mailboxId);
+            }
+
+            // Shut down all of those running services
+            for (Long mailboxId : toStop) {
+                AbstractSyncService svc = mServiceMap.get(mailboxId);
+                if (svc != null) {
+                    log("Stopping " + svc.mAccount.mDisplayName + '/' + svc.mMailbox.mDisplayName);
+                    svc.stop();
+                    if (svc.mThread != null) {
+                        svc.mThread.interrupt();
+                    }
+                }
+                releaseWakeLock(mailboxId);
+            }
+        }
+    }
+
+    private void waitForConnectivity() {
+        boolean waiting = false;
+        ConnectivityManager cm =
+            (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+        while (!sStop) {
+            NetworkInfo info = cm.getActiveNetworkInfo();
+            if (info != null) {
+                mNetworkInfo = info;
+                // We're done if there's an active network
+                if (waiting) {
+                    // If we've been waiting, release any I/O error holds
+                    releaseSyncHolds(this, AbstractSyncService.EXIT_IO_ERROR, null);
+                    // And log what's still being held
+                    logSyncHolds();
+                }
+                return;
+            } else {
+                // If this is our first time through the loop, shut down running service threads
+                if (!waiting) {
+                    waiting = true;
+                    stopServiceThreads();
+                }
+                // Wait until a network is connected (or 10 mins), but let the device sleep
+                // We'll set an alarm just in case we don't get notified (bugs happen)
+                synchronized (sConnectivityLock) {
+                    runAsleep(EXTRA_MAILBOX_ID, CONNECTIVITY_WAIT_TIME+5*SECONDS);
+                    try {
+                        log("Connectivity lock...");
+                        sConnectivityHold = true;
+                        sConnectivityLock.wait(CONNECTIVITY_WAIT_TIME);
+                        log("Connectivity lock released...");
+                    } catch (InterruptedException e) {
+                        // This is fine; we just go around the loop again
+                    } finally {
+                        sConnectivityHold = false;
+                    }
+                    runAwake(EXTRA_MAILBOX_ID);
+                }
+            }
+        }
+    }
+
+    /**
+     * Note that there are two ways the EAS ExchangeService service can be created:
+     *
+     * 1) as a background service instantiated via startService (which happens on boot, when the
+     * first EAS account is created, etc), in which case the service thread is spun up, mailboxes
+     * sync, etc. and
+     * 2) to execute an RPC call from the UI, in which case the background service will already be
+     * running most of the time (unless we're creating a first EAS account)
+     *
+     * If the running background service detects that there are no EAS accounts (on boot, if none
+     * were created, or afterward if the last remaining EAS account is deleted), it will call
+     * stopSelf() to terminate operation.
+     *
+     * The goal is to ensure that the background service is running at all times when there is at
+     * least one EAS account in existence
+     *
+     * Because there are edge cases in which our process can crash (typically, this has been seen
+     * in UI crashes, ANR's, etc.), it's possible for the UI to start up again without the
+     * background service having been started.  We explicitly try to start the service in Welcome
+     * (to handle the case of the app having been reloaded).  We also start the service on any
+     * startSync call (if it isn't already running)
+     */
+    @Override
+    public void onCreate() {
+        Utility.runAsync(new Runnable() {
+            @Override
+            public void run() {
+                // Quick checks first, before getting the lock
+                if (sStartingUp) return;
+                synchronized (sSyncLock) {
+                    alwaysLog("!!! EAS ExchangeService, onCreate");
+                    // Try to start up properly; we might be coming back from a crash that the Email
+                    // application isn't aware of.
+                    startService(new Intent(EmailServiceProxy.EXCHANGE_INTENT));
+                    if (sStop) {
+                        return;
+                    }
+                }
+            }});
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        alwaysLog("!!! EAS ExchangeService, onStartCommand, startingUp = " + sStartingUp +
+                ", running = " + (INSTANCE != null));
+        if (!sStartingUp && INSTANCE == null) {
+            sStartingUp = true;
+            Utility.runAsync(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        synchronized (sSyncLock) {
+                            // ExchangeService cannot start unless we can connect to AccountService
+                            if (!new AccountServiceProxy(ExchangeService.this).test()) {
+                                alwaysLog("!!! Email application not found; stopping self");
+                                stopSelf();
+                            }
+                            if (sDeviceId == null) {
+                                try {
+                                    String deviceId = getDeviceId(ExchangeService.this);
+                                    if (deviceId != null) {
+                                        sDeviceId = deviceId;
+                                    }
+                                } catch (IOException e) {
+                                }
+                                if (sDeviceId == null) {
+                                    alwaysLog("!!! deviceId unknown; stopping self and retrying");
+                                    stopSelf();
+                                    // Try to restart ourselves in a few seconds
+                                    Utility.runAsync(new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            try {
+                                                Thread.sleep(5000);
+                                            } catch (InterruptedException e) {
+                                            }
+                                            startService(new Intent(
+                                                    EmailServiceProxy.EXCHANGE_INTENT));
+                                        }});
+                                    return;
+                                }
+                            }
+                            // Run the reconciler and clean up mismatched accounts - if we weren't
+                            // running when accounts were deleted, it won't have been called.
+                            runAccountReconcilerSync(ExchangeService.this);
+                            // Update other services depending on final account configuration
+                            maybeStartExchangeServiceThread();
+                            if (sServiceThread == null) {
+                                log("!!! EAS ExchangeService, stopping self");
+                                stopSelf();
+                            } else if (sStop) {
+                                // If we were trying to stop, attempt a restart in 5 secs
+                                setAlarm(EXCHANGE_SERVICE_MAILBOX_ID, 5*SECONDS);
+                            }
+                        }
+                    } finally {
+                        sStartingUp = false;
+                    }
+                }});
+        }
+        return Service.START_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        log("!!! EAS ExchangeService, onDestroy");
+        // Handle shutting down off the UI thread
+        Utility.runAsync(new Runnable() {
+            @Override
+            public void run() {
+                // Quick checks first, before getting the lock
+                if (INSTANCE == null || sServiceThread == null) return;
+                synchronized(sSyncLock) {
+                    // Stop the sync manager thread and return
+                    if (sServiceThread != null) {
+                        sStop = true;
+                        sServiceThread.interrupt();
+                    }
+                }
+            }});
+    }
+
+    void maybeStartExchangeServiceThread() {
+        // Start our thread...
+        // See if there are any EAS accounts; otherwise, just go away
+        if (sServiceThread == null || !sServiceThread.isAlive()) {
+            if (EmailContent.count(this, HostAuth.CONTENT_URI, WHERE_PROTOCOL_EAS, null) > 0) {
+                log(sServiceThread == null ? "Starting thread..." : "Restarting thread...");
+                sServiceThread = new Thread(this, "ExchangeService");
+                INSTANCE = this;
+                sServiceThread.start();
+            }
+        }
+    }
+
+    /**
+     * Start up the ExchangeService service if it's not already running
+     * This is a stopgap for cases in which ExchangeService died (due to a crash somewhere in
+     * com.android.email) and hasn't been restarted. See the comment for onCreate for details
+     */
+    static void checkExchangeServiceServiceRunning() {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        if (sServiceThread == null) {
+            log("!!! checkExchangeServiceServiceRunning; starting service...");
+            exchangeService.startService(new Intent(exchangeService, ExchangeService.class));
+        }
+    }
+
+    @Override
+    public void run() {
+        sStop = false;
+        alwaysLog("ExchangeService thread running");
+        // If we're really debugging, turn on all logging
+        if (Eas.DEBUG) {
+            Eas.USER_LOG = true;
+            Eas.PARSER_LOG = true;
+            Eas.FILE_LOG = true;
+        }
+
+        TempDirectory.setTempDirectory(this);
+
+        // If we need to wait for the debugger, do so
+        if (Eas.WAIT_DEBUG) {
+            Debug.waitForDebugger();
+        }
+
+        // Synchronize here to prevent a shutdown from happening while we initialize our observers
+        // and receivers
+        synchronized (sSyncLock) {
+            if (INSTANCE != null) {
+                mResolver = getContentResolver();
+
+                // Set up our observers; we need them to know when to start/stop various syncs based
+                // on the insert/delete/update of mailboxes and accounts
+                // We also observe synced messages to trigger upsyncs at the appropriate time
+                mAccountObserver = new AccountObserver(mHandler);
+                mResolver.registerContentObserver(Account.NOTIFIER_URI, true, mAccountObserver);
+                mMailboxObserver = new MailboxObserver(mHandler);
+                mResolver.registerContentObserver(Mailbox.CONTENT_URI, false, mMailboxObserver);
+                mSyncedMessageObserver = new SyncedMessageObserver(mHandler);
+                mResolver.registerContentObserver(Message.SYNCED_CONTENT_URI, true,
+                        mSyncedMessageObserver);
+
+                // Set up receivers for connectivity and background data setting
+                mConnectivityReceiver = new ConnectivityReceiver();
+                registerReceiver(mConnectivityReceiver, new IntentFilter(
+                        ConnectivityManager.CONNECTIVITY_ACTION));
+
+                mBackgroundDataSettingReceiver = new ConnectivityReceiver();
+                registerReceiver(mBackgroundDataSettingReceiver, new IntentFilter(
+                        ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED));
+                // Save away the current background data setting; we'll keep track of it with the
+                // receiver we just registered
+                ConnectivityManager cm = (ConnectivityManager)getSystemService(
+                        Context.CONNECTIVITY_SERVICE);
+                mBackgroundData = cm.getBackgroundDataSetting();
+
+                // Do any required work to clean up our Mailboxes (this serves to upgrade
+                // mailboxes that existed prior to EmailProvider database version 17)
+                MailboxUtilities.fixupUninitializedParentKeys(this, getEasAccountSelector());
+            }
+        }
+
+        try {
+            // Loop indefinitely until we're shut down
+            while (!sStop) {
+                runAwake(EXTRA_MAILBOX_ID);
+                waitForConnectivity();
+                mNextWaitReason = null;
+                long nextWait = checkMailboxes();
+                try {
+                    synchronized (this) {
+                        if (!mKicked) {
+                            if (nextWait < 0) {
+                                log("Negative wait? Setting to 1s");
+                                nextWait = 1*SECONDS;
+                            }
+                            if (nextWait > 10*SECONDS) {
+                                if (mNextWaitReason != null) {
+                                    log("Next awake " + nextWait / 1000 + "s: " + mNextWaitReason);
+                                }
+                                runAsleep(EXTRA_MAILBOX_ID, nextWait + (3*SECONDS));
+                            }
+                            wait(nextWait);
+                        }
+                    }
+                } catch (InterruptedException e) {
+                    // Needs to be caught, but causes no problem
+                    log("ExchangeService interrupted");
+                } finally {
+                    synchronized (this) {
+                        if (mKicked) {
+                            //log("Wait deferred due to kick");
+                            mKicked = false;
+                        }
+                    }
+                }
+            }
+            log("Shutdown requested");
+        } catch (ProviderUnavailableException pue) {
+            // Shutdown cleanly in this case
+            // NOTE: Sync adapters will also crash with this error, but that is already handled
+            // in the adapters themselves, i.e. they return cleanly via done().  When the Email
+            // process starts running again, the Exchange process will be started again in due
+            // course, assuming there is at least one existing EAS account.
+            Log.e(TAG, "EmailProvider unavailable; shutting down");
+            // Ask for our service to be restarted; this should kick-start the Email process as well
+            startService(new Intent(this, ExchangeService.class));
+        } catch (RuntimeException e) {
+            // Crash; this is a completely unexpected runtime error
+            Log.e(TAG, "RuntimeException in ExchangeService", e);
+            throw e;
+        } finally {
+            shutdown();
+        }
+    }
+
+    private void shutdown() {
+        synchronized (sSyncLock) {
+            // If INSTANCE is null, we've already been shut down
+            if (INSTANCE != null) {
+                log("ExchangeService shutting down...");
+
+                // Stop our running syncs
+                stopServiceThreads();
+
+                // Stop receivers
+                if (mConnectivityReceiver != null) {
+                    unregisterReceiver(mConnectivityReceiver);
+                }
+                if (mBackgroundDataSettingReceiver != null) {
+                    unregisterReceiver(mBackgroundDataSettingReceiver);
+                }
+
+                // Unregister observers
+                ContentResolver resolver = getContentResolver();
+                if (mSyncedMessageObserver != null) {
+                    resolver.unregisterContentObserver(mSyncedMessageObserver);
+                    mSyncedMessageObserver = null;
+                }
+                if (mAccountObserver != null) {
+                    resolver.unregisterContentObserver(mAccountObserver);
+                    mAccountObserver = null;
+                }
+                if (mMailboxObserver != null) {
+                    resolver.unregisterContentObserver(mMailboxObserver);
+                    mMailboxObserver = null;
+                }
+                unregisterCalendarObservers();
+
+                // Clear pending alarms and associated Intents
+                clearAlarms();
+
+                // Release our wake lock, if we have one
+                synchronized (mWakeLocks) {
+                    if (mWakeLock != null) {
+                        mWakeLock.release();
+                        mWakeLock = null;
+                    }
+                }
+
+                INSTANCE = null;
+                sServiceThread = null;
+                sStop = false;
+                log("Goodbye");
+            }
+        }
+    }
+
+    /**
+     * Release a mailbox from the service map and release its wake lock.
+     * NOTE: This method MUST be called while holding sSyncLock!
+     *
+     * @param mailboxId the id of the mailbox to be released
+     */
+    private void releaseMailbox(long mailboxId) {
+        mServiceMap.remove(mailboxId);
+        releaseWakeLock(mailboxId);
+    }
+
+    /**
+     * Check whether an Outbox (referenced by a Cursor) has any messages that can be sent
+     * @param c the cursor to an Outbox
+     * @return true if there is mail to be sent
+     */
+    private boolean hasSendableMessages(Cursor outboxCursor) {
+        Cursor c = mResolver.query(Message.CONTENT_URI, Message.ID_COLUMN_PROJECTION,
+                EasOutboxService.MAILBOX_KEY_AND_NOT_SEND_FAILED,
+                new String[] {Long.toString(outboxCursor.getLong(Mailbox.CONTENT_ID_COLUMN))},
+                null);
+        try {
+            while (c.moveToNext()) {
+                if (!Utility.hasUnloadedAttachments(this, c.getLong(Message.CONTENT_ID_COLUMN))) {
+                    return true;
+                }
+            }
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determine whether the account is allowed to sync automatically, as opposed to manually, based
+     * on whether the "require manual sync when roaming" policy is in force and applicable
+     * @param account the account
+     * @return whether or not the account can sync automatically
+     */
+    /*package*/ static boolean canAutoSync(Account account) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) {
+            return false;
+        }
+        NetworkInfo networkInfo = exchangeService.mNetworkInfo;
+
+        // Enforce manual sync only while roaming here
+        long policyKey = account.mPolicyKey;
+        // Quick exit from this check
+        if ((policyKey != 0) && (networkInfo != null) &&
+                (ConnectivityManager.isNetworkTypeMobile(networkInfo.getType()))) {
+            // We'll cache the Policy data here
+            Policy policy = account.mPolicy;
+            if (policy == null) {
+                policy = Policy.restorePolicyWithId(INSTANCE, policyKey);
+                account.mPolicy = policy;
+                if (!PolicyServiceProxy.isActive(exchangeService, policy)) return false;
+            }
+            if (policy != null && policy.mRequireManualSyncWhenRoaming && networkInfo.isRoaming()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Convenience method to determine whether Email sync is enabled for a given account
+     * @param account the Account in question
+     * @return whether Email sync is enabled
+     */
+    private boolean canSyncEmail(android.accounts.Account account) {
+        return ContentResolver.getSyncAutomatically(account, EmailContent.AUTHORITY);
+    }
+
+    /**
+     * Determine whether a mailbox of a given type in a given account can be synced automatically
+     * by ExchangeService.  This is an increasingly complex determination, taking into account
+     * security policies and user settings (both within the Email application and in the Settings
+     * application)
+     *
+     * @param account the Account that the mailbox is in
+     * @param type the type of the Mailbox
+     * @return whether or not to start a sync
+     */
+    private boolean isMailboxSyncable(Account account, int type) {
+        // This 'if' statement performs checks to see whether or not a mailbox is a
+        // candidate for syncing based on policies, user settings, & other restrictions
+        if (type == Mailbox.TYPE_OUTBOX) {
+            // Outbox is always syncable
+            return true;
+        } else if (type == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+            // Always sync EAS mailbox unless master sync is off
+            return ContentResolver.getMasterSyncAutomatically();
+        } else if (type == Mailbox.TYPE_CONTACTS || type == Mailbox.TYPE_CALENDAR) {
+            // Contacts/Calendar obey this setting from ContentResolver
+            if (!ContentResolver.getMasterSyncAutomatically()) {
+                return false;
+            }
+            // Get the right authority for the mailbox
+            String authority;
+            if (type == Mailbox.TYPE_CONTACTS) {
+                authority = ContactsContract.AUTHORITY;
+            } else {
+                authority = CalendarContract.AUTHORITY;
+                if (!mCalendarObservers.containsKey(account.mId)){
+                    // Make sure we have an observer for this Calendar, as
+                    // we need to be able to detect sync state changes, sigh
+                    registerCalendarObserver(account);
+                }
+            }
+            // See if "sync automatically" is set; if not, punt
+            if (!ContentResolver.getSyncAutomatically(account.mAmAccount, authority)) {
+                return false;
+            // See if the calendar is enabled from the Calendar app UI; if not, punt
+            } else if ((type == Mailbox.TYPE_CALENDAR) && !isCalendarEnabled(account.mId)) {
+                return false;
+            }
+        // Never automatically sync trash
+        } else if (type == Mailbox.TYPE_TRASH) {
+            return false;
+        // For non-outbox, non-account mail, we do three checks:
+        // 1) are we restricted by policy (i.e. manual sync only),
+        // 2) has the user checked the "Sync Email" box in Account Settings, and
+        // 3) does the user have the master "background data" box checked in Settings
+        } else if (!canAutoSync(account) || !canSyncEmail(account.mAmAccount) || !mBackgroundData) {
+            return false;
+        }
+        return true;
+    }
+
+    private long checkMailboxes () {
+        // First, see if any running mailboxes have been deleted
+        ArrayList<Long> deletedMailboxes = new ArrayList<Long>();
+        synchronized (sSyncLock) {
+            for (long mailboxId: mServiceMap.keySet()) {
+                Mailbox m = Mailbox.restoreMailboxWithId(this, mailboxId);
+                if (m == null) {
+                    deletedMailboxes.add(mailboxId);
+                }
+            }
+            // If so, stop them or remove them from the map
+            for (Long mailboxId: deletedMailboxes) {
+                AbstractSyncService svc = mServiceMap.get(mailboxId);
+                if (svc == null || svc.mThread == null) {
+                    releaseMailbox(mailboxId);
+                    continue;
+                } else {
+                    boolean alive = svc.mThread.isAlive();
+                    log("Deleted mailbox: " + svc.mMailboxName);
+                    if (alive) {
+                        stopManualSync(mailboxId);
+                    } else {
+                        log("Removing from serviceMap");
+                        releaseMailbox(mailboxId);
+                    }
+                }
+            }
+        }
+
+        long nextWait = EXCHANGE_SERVICE_HEARTBEAT_TIME;
+        long now = System.currentTimeMillis();
+
+        // Start up threads that need it; use a query which finds eas mailboxes where the
+        // the sync interval is not "never".  This is the set of mailboxes that we control
+        if (mAccountObserver == null) {
+            log("mAccountObserver null; service died??");
+            return nextWait;
+        }
+
+        Cursor c = getContentResolver().query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
+                mAccountObserver.getSyncableEasMailboxWhere(), null, null);
+        if (c == null) throw new ProviderUnavailableException();
+        try {
+            while (c.moveToNext()) {
+                long mailboxId = c.getLong(Mailbox.CONTENT_ID_COLUMN);
+                AbstractSyncService service = null;
+                synchronized (sSyncLock) {
+                    service = mServiceMap.get(mailboxId);
+                }
+                if (service == null) {
+                    // Get the cached account
+                    Account account = getAccountById(c.getInt(Mailbox.CONTENT_ACCOUNT_KEY_COLUMN));
+                    if (account == null) continue;
+
+                    // We handle a few types of mailboxes specially
+                    int mailboxType = c.getInt(Mailbox.CONTENT_TYPE_COLUMN);
+                    if (!isMailboxSyncable(account, mailboxType)) {
+                        continue;
+                    }
+
+                    // Check whether we're in a hold (temporary or permanent)
+                    SyncError syncError = mSyncErrorMap.get(mailboxId);
+                    if (syncError != null) {
+                        // Nothing we can do about fatal errors
+                        if (syncError.fatal) continue;
+                        if (now < syncError.holdEndTime) {
+                            // If release time is earlier than next wait time,
+                            // move next wait time up to the release time
+                            if (syncError.holdEndTime < now + nextWait) {
+                                nextWait = syncError.holdEndTime - now;
+                                mNextWaitReason = "Release hold";
+                            }
+                            continue;
+                        } else {
+                            // Keep the error around, but clear the end time
+                            syncError.holdEndTime = 0;
+                        }
+                    }
+
+                    // Otherwise, we use the sync interval
+                    long syncInterval = c.getInt(Mailbox.CONTENT_SYNC_INTERVAL_COLUMN);
+                    if (syncInterval == Mailbox.CHECK_INTERVAL_PUSH) {
+                        Mailbox m = EmailContent.getContent(c, Mailbox.class);
+                        requestSync(m, SYNC_PUSH, null);
+                    } else if (mailboxType == Mailbox.TYPE_OUTBOX) {
+                        if (hasSendableMessages(c)) {
+                            Mailbox m = EmailContent.getContent(c, Mailbox.class);
+                            startServiceThread(EasSyncService.getServiceForMailbox(this, m));
+                        }
+                    } else if (syncInterval > 0 && syncInterval <= ONE_DAY_MINUTES) {
+                        long lastSync = c.getLong(Mailbox.CONTENT_SYNC_TIME_COLUMN);
+                        long sinceLastSync = now - lastSync;
+                        long toNextSync = syncInterval*MINUTES - sinceLastSync;
+                        String name = c.getString(Mailbox.CONTENT_DISPLAY_NAME_COLUMN);
+                        if (toNextSync <= 0) {
+                            Mailbox m = EmailContent.getContent(c, Mailbox.class);
+                            requestSync(m, SYNC_SCHEDULED, null);
+                        } else if (toNextSync < nextWait) {
+                            nextWait = toNextSync;
+                            if (Eas.USER_LOG) {
+                                log("Next sync for " + name + " in " + nextWait/1000 + "s");
+                            }
+                            mNextWaitReason = "Scheduled sync, " + name;
+                        } else if (Eas.USER_LOG) {
+                            log("Next sync for " + name + " in " + toNextSync/1000 + "s");
+                        }
+                    }
+                } else {
+                    Thread thread = service.mThread;
+                    // Look for threads that have died and remove them from the map
+                    if (thread != null && !thread.isAlive()) {
+                        if (Eas.USER_LOG) {
+                            log("Dead thread, mailbox released: " +
+                                    c.getString(Mailbox.CONTENT_DISPLAY_NAME_COLUMN));
+                        }
+                        releaseMailbox(mailboxId);
+                        // Restart this if necessary
+                        if (nextWait > 3*SECONDS) {
+                            nextWait = 3*SECONDS;
+                            mNextWaitReason = "Clean up dead thread(s)";
+                        }
+                    } else {
+                        long requestTime = service.mRequestTime;
+                        if (requestTime > 0) {
+                            long timeToRequest = requestTime - now;
+                            if (timeToRequest <= 0) {
+                                service.mRequestTime = 0;
+                                service.alarm();
+                            } else if (requestTime > 0 && timeToRequest < nextWait) {
+                                if (timeToRequest < 11*MINUTES) {
+                                    nextWait = timeToRequest < 250 ? 250 : timeToRequest;
+                                    mNextWaitReason = "Sync data change";
+                                } else {
+                                    log("Illegal timeToRequest: " + timeToRequest);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+        return nextWait;
+    }
+
+    static public void serviceRequest(long mailboxId, int reason) {
+        serviceRequest(mailboxId, 5*SECONDS, reason);
+    }
+
+    /**
+     * Return a boolean indicating whether the mailbox can be synced
+     * @param m the mailbox
+     * @return whether or not the mailbox can be synced
+     */
+    public static boolean isSyncable(Mailbox m) {
+        return m.loadsFromServer(HostAuth.SCHEME_EAS);
+    }
+
+    static public void serviceRequest(long mailboxId, long ms, int reason) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+        if (m == null || !isSyncable(m)) return;
+        try {
+            AbstractSyncService service = exchangeService.mServiceMap.get(mailboxId);
+            if (service != null) {
+                service.mRequestTime = System.currentTimeMillis() + ms;
+                kick("service request");
+            } else {
+                startManualSync(mailboxId, reason, null);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    static public void serviceRequestImmediate(long mailboxId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        AbstractSyncService service = exchangeService.mServiceMap.get(mailboxId);
+        if (service != null) {
+            service.mRequestTime = System.currentTimeMillis();
+            Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+            if (m != null) {
+                service.mAccount = Account.restoreAccountWithId(exchangeService, m.mAccountKey);
+                service.mMailbox = m;
+                kick("service request immediate");
+            }
+        }
+    }
+
+    static public void sendMessageRequest(Request req) {
+        ExchangeService exchangeService = INSTANCE;
+        Message msg = Message.restoreMessageWithId(exchangeService, req.mMessageId);
+        if (msg == null) return;
+        long mailboxId = msg.mMailboxKey;
+        Mailbox mailbox = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+        if (mailbox == null) return;
+
+        // If we're loading an attachment for Outbox, we want to look at the source message
+        // to find the loading mailbox
+        if (mailbox.mType == Mailbox.TYPE_OUTBOX) {
+            long sourceId = Utility.getFirstRowLong(exchangeService, Body.CONTENT_URI,
+                    new String[] {BodyColumns.SOURCE_MESSAGE_KEY},
+                    BodyColumns.MESSAGE_KEY + "=?",
+                    new String[] {Long.toString(msg.mId)}, null, 0, -1L);
+            if (sourceId != -1L) {
+                EmailContent.Message sourceMsg =
+                        EmailContent.Message.restoreMessageWithId(exchangeService, sourceId);
+                if (sourceMsg != null) {
+                    mailboxId = sourceMsg.mMailboxKey;
+                }
+            }
+        }
+
+        AbstractSyncService service = exchangeService.mServiceMap.get(mailboxId);
+        if (service == null) {
+            startManualSync(mailboxId, SYNC_SERVICE_PART_REQUEST, req);
+            kick("part request");
+        } else {
+            service.addRequest(req);
+        }
+    }
+
+    /**
+     * Determine whether a given Mailbox can be synced, i.e. is not already syncing and is not in
+     * an error state
+     *
+     * @param mailboxId
+     * @return whether or not the Mailbox is available for syncing (i.e. is a valid push target)
+     */
+    static public int pingStatus(long mailboxId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return PING_STATUS_OK;
+        // Already syncing...
+        if (exchangeService.mServiceMap.get(mailboxId) != null) {
+            return PING_STATUS_RUNNING;
+        }
+        // No errors or a transient error, don't ping...
+        SyncError error = exchangeService.mSyncErrorMap.get(mailboxId);
+        if (error != null) {
+            if (error.fatal) {
+                return PING_STATUS_UNABLE;
+            } else if (error.holdEndTime > 0) {
+                return PING_STATUS_WAITING;
+            }
+        }
+        return PING_STATUS_OK;
+    }
+
+    static public void startManualSync(long mailboxId, int reason, Request req) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        synchronized (sSyncLock) {
+            AbstractSyncService svc = exchangeService.mServiceMap.get(mailboxId);
+            if (svc == null) {
+                exchangeService.mSyncErrorMap.remove(mailboxId);
+                Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+                if (m != null) {
+                    log("Starting sync for " + m.mDisplayName);
+                    exchangeService.requestSync(m, reason, req);
+                }
+            } else {
+                // If this is a ui request, set the sync reason for the service
+                if (reason >= SYNC_CALLBACK_START) {
+                    svc.mSyncReason = reason;
+                }
+            }
+        }
+    }
+
+    // DO NOT CALL THIS IN A LOOP ON THE SERVICEMAP
+    static public void stopManualSync(long mailboxId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        synchronized (sSyncLock) {
+            AbstractSyncService svc = exchangeService.mServiceMap.get(mailboxId);
+            if (svc != null) {
+                log("Stopping sync for " + svc.mMailboxName);
+                svc.stop();
+                svc.mThread.interrupt();
+                exchangeService.releaseWakeLock(mailboxId);
+            }
+        }
+    }
+
+    /**
+     * Wake up ExchangeService to check for mailboxes needing service
+     */
+    static public void kick(String reason) {
+       ExchangeService exchangeService = INSTANCE;
+       if (exchangeService != null) {
+            synchronized (exchangeService) {
+                //INSTANCE.log("Kick: " + reason);
+                exchangeService.mKicked = true;
+                exchangeService.notify();
+            }
+        }
+        if (sConnectivityLock != null) {
+            synchronized (sConnectivityLock) {
+                sConnectivityLock.notify();
+            }
+        }
+    }
+
+    static public void accountUpdated(long acctId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        synchronized (sSyncLock) {
+            for (AbstractSyncService svc : exchangeService.mServiceMap.values()) {
+                if (svc.mAccount.mId == acctId) {
+                    svc.mAccount = Account.restoreAccountWithId(exchangeService, acctId);
+                }
+            }
+        }
+    }
+
+    /**
+     * Tell ExchangeService to remove the mailbox from the map of mailboxes with sync errors
+     * @param mailboxId the id of the mailbox
+     */
+    static public void removeFromSyncErrorMap(long mailboxId) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService != null) {
+            exchangeService.mSyncErrorMap.remove(mailboxId);
+        }
+    }
+
+    private boolean isRunningInServiceThread(long mailboxId) {
+        AbstractSyncService syncService = mServiceMap.get(mailboxId);
+        Thread thisThread = Thread.currentThread();
+        return syncService != null && syncService.mThread != null &&
+            thisThread == syncService.mThread;
+    }
+
+    /**
+     * Sent by services indicating that their thread is finished; action depends on the exitStatus
+     * of the service.
+     *
+     * @param svc the service that is finished
+     */
+    static public void done(AbstractSyncService svc) {
+        ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
+        synchronized(sSyncLock) {
+            long mailboxId = svc.mMailboxId;
+            // If we're no longer the syncing thread for the mailbox, just return
+            if (!exchangeService.isRunningInServiceThread(mailboxId)) {
+                return;
+            }
+            exchangeService.releaseMailbox(mailboxId);
+            exchangeService.setMailboxSyncStatus(mailboxId, EmailContent.SYNC_STATUS_NONE);
+
+            ConcurrentHashMap<Long, SyncError> errorMap = exchangeService.mSyncErrorMap;
+            SyncError syncError = errorMap.get(mailboxId);
+
+            int exitStatus = svc.mExitStatus;
+            Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
+            if (m == null) return;
+
+            if (exitStatus != AbstractSyncService.EXIT_LOGIN_FAILURE) {
+                long accountId = m.mAccountKey;
+                Account account = Account.restoreAccountWithId(exchangeService, accountId);
+                if (account == null) return;
+                if (exchangeService.releaseSyncHolds(exchangeService,
+                        AbstractSyncService.EXIT_LOGIN_FAILURE, account)) {
+                    new AccountServiceProxy(exchangeService).notifyLoginSucceeded(accountId);
+                }
+            }
+
+            int lastResult = EmailContent.LAST_SYNC_RESULT_SUCCESS;
+            // For error states, whether the error is fatal (won't automatically be retried)
+            boolean errorIsFatal = true;
+            try {
+                switch (exitStatus) {
+                    case AbstractSyncService.EXIT_DONE:
+                        if (svc.hasPendingRequests()) {
+                            // TODO Handle this case
+                        }
+                        errorMap.remove(mailboxId);
+                        // If we've had a successful sync, clear the shutdown count
+                        synchronized (ExchangeService.class) {
+                            sClientConnectionManagerShutdownCount = 0;
+                        }
+                        // Leave now; other statuses are errors
+                        return;
+                    // I/O errors get retried at increasing intervals
+                    case AbstractSyncService.EXIT_IO_ERROR:
+                        if (syncError != null) {
+                            syncError.escalate();
+                            log(m.mDisplayName + " held for " + syncError.holdDelay + "ms");
+                        } else {
+                            log(m.mDisplayName + " added to syncErrorMap, hold for 15s");
+                        }
+                        lastResult = EmailContent.LAST_SYNC_RESULT_CONNECTION_ERROR;
+                        errorIsFatal = false;
+                        break;
+                    // These errors are not retried automatically
+                    case AbstractSyncService.EXIT_LOGIN_FAILURE:
+                        new AccountServiceProxy(exchangeService).notifyLoginFailed(m.mAccountKey);
+                        lastResult = EmailContent.LAST_SYNC_RESULT_AUTH_ERROR;
+                        break;
+                    case AbstractSyncService.EXIT_SECURITY_FAILURE:
+                    case AbstractSyncService.EXIT_ACCESS_DENIED:
+                        lastResult = EmailContent.LAST_SYNC_RESULT_SECURITY_ERROR;
+                        break;
+                    case AbstractSyncService.EXIT_EXCEPTION:
+                        lastResult = EmailContent.LAST_SYNC_RESULT_INTERNAL_ERROR;
+                        break;
+                }
+                // Add this box to the error map
+                errorMap.put(mailboxId, exchangeService.new SyncError(exitStatus, errorIsFatal));
+            } finally {
+                // Always set the last result
+                exchangeService.setMailboxLastSyncResult(mailboxId, lastResult);
+                kick("sync completed");
+            }
+        }
+    }
+
+    /**
+     * Given the status string from a Mailbox, return the type code for the last sync
+     * @param status the syncStatus column of a Mailbox
+     * @return
+     */
+    static public int getStatusType(String status) {
+        if (status == null) {
+            return -1;
+        } else {
+            return status.charAt(STATUS_TYPE_CHAR) - '0';
+        }
+    }
+
+    /**
+     * Given the status string from a Mailbox, return the change count for the last sync
+     * The change count is the number of adds + deletes + changes in the last sync
+     * @param status the syncStatus column of a Mailbox
+     * @return
+     */
+    static public int getStatusChangeCount(String status) {
+        try {
+            String s = status.substring(STATUS_CHANGE_COUNT_OFFSET);
+            return Integer.parseInt(s);
+        } catch (RuntimeException e) {
+            return -1;
+        }
+    }
+
+    static public Context getContext() {
+        return INSTANCE;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/IllegalHeartbeatException.java b/exchange2/src/com/android/exchange/IllegalHeartbeatException.java
new file mode 100644
index 0000000..e480aa7
--- /dev/null
+++ b/exchange2/src/com/android/exchange/IllegalHeartbeatException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+public class IllegalHeartbeatException extends EasException {
+    private static final long serialVersionUID = 1L;
+    public final int mLegalHeartbeat;
+
+    public IllegalHeartbeatException(int legalHeartbeat) {
+        mLegalHeartbeat = legalHeartbeat;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/MailboxAlarmReceiver.java b/exchange2/src/com/android/exchange/MailboxAlarmReceiver.java
new file mode 100644
index 0000000..7958c03
--- /dev/null
+++ b/exchange2/src/com/android/exchange/MailboxAlarmReceiver.java
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * MailboxAlarmReceiver is used to "wake up" the ExchangeService at the appropriate time(s).  It may
+ * also be used for individual sync adapters, but this isn't implemented at the present time.
+ *
+ */
+public class MailboxAlarmReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        long mailboxId = intent.getLongExtra("mailbox", ExchangeService.EXTRA_MAILBOX_ID);
+        // EXCHANGE_SERVICE_MAILBOX_ID tells us that the service is asking to be started
+        if (mailboxId == ExchangeService.EXCHANGE_SERVICE_MAILBOX_ID) {
+            context.startService(new Intent(context, ExchangeService.class));
+        } else {
+            ExchangeService.alert(context, mailboxId);
+        }
+    }
+}
+
diff --git a/exchange2/src/com/android/exchange/MeetingResponseRequest.java b/exchange2/src/com/android/exchange/MeetingResponseRequest.java
new file mode 100644
index 0000000..ea769e2
--- /dev/null
+++ b/exchange2/src/com/android/exchange/MeetingResponseRequest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+/**
+ * MeetingResponseRequest is the EAS wrapper for responding to meeting requests.
+ */
+public class MeetingResponseRequest extends Request {
+    public final int mResponse;
+
+    MeetingResponseRequest(long messageId, int response) {
+        super(messageId);
+        mResponse = response;
+    }
+
+    // MeetingResponseRequests are unique by their message id (i.e. there's only one response to
+    // a given message)
+    public boolean equals(Object o) {
+        if (!(o instanceof MeetingResponseRequest)) return false;
+        return ((MeetingResponseRequest)o).mMessageId == mMessageId;
+    }
+
+    public int hashCode() {
+        return (int)mMessageId;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/MessageMoveRequest.java b/exchange2/src/com/android/exchange/MessageMoveRequest.java
new file mode 100644
index 0000000..a884bda
--- /dev/null
+++ b/exchange2/src/com/android/exchange/MessageMoveRequest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+/**
+ * MessageMoveRequest is the EAS wrapper for requesting a "move to folder"
+ */
+public class MessageMoveRequest extends Request {
+    public final long mMailboxId;
+
+    public MessageMoveRequest(long messageId, long mailboxId) {
+        super(messageId);
+        mMailboxId = mailboxId;
+    }
+
+    // MessageMoveRequests are unique by their message id (i.e. it's meaningless to have two
+    // separate message moves queued at the same time)
+    public boolean equals(Object o) {
+        if (!(o instanceof MessageMoveRequest)) return false;
+        return ((MessageMoveRequest)o).mMessageId == mMessageId;
+    }
+
+    public int hashCode() {
+        return (int)mMessageId;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/MockParserStream.java b/exchange2/src/com/android/exchange/MockParserStream.java
new file mode 100644
index 0000000..a518667
--- /dev/null
+++ b/exchange2/src/com/android/exchange/MockParserStream.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * MockParserStream is an InputStream that feeds pre-generated data into various EasParser
+ * subclasses.
+ * 
+ * After parsing is done, the result can be obtained with getResult
+ *
+ */
+public class MockParserStream extends InputStream {
+    int[] array;
+    int pos = 0;
+    Object value;
+
+    MockParserStream (int[] _array) {
+        array = _array;
+    }
+
+    @Override
+    public int read() throws IOException {
+        try {
+            return array[pos++];
+        } catch (IndexOutOfBoundsException e) {
+            throw new IOException("End of stream");
+        }
+    }
+
+    public void setResult(Object _value) {
+        value = _value;
+    }
+
+    public Object getResult() {
+        return value;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/PartRequest.java b/exchange2/src/com/android/exchange/PartRequest.java
new file mode 100644
index 0000000..23b4add
--- /dev/null
+++ b/exchange2/src/com/android/exchange/PartRequest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import com.android.emailcommon.provider.EmailContent.Attachment;
+
+/**
+ * PartRequest is the EAS wrapper for attachment loading requests.  In addition to information about
+ * the attachment to be loaded, it also contains the callback to be used for status/progress
+ * updates to the UI.
+ */
+public class PartRequest extends Request {
+    public final Attachment mAttachment;
+    public final String mDestination;
+    public final String mContentUriString;
+    public final String mLocation;
+
+    public PartRequest(Attachment _att, String _destination, String _contentUriString) {
+        super(_att.mMessageKey);
+        mAttachment = _att;
+        mLocation = mAttachment.mLocation;
+        mDestination = _destination;
+        mContentUriString = _contentUriString;
+    }
+
+    // PartRequests are unique by their attachment id (i.e. multiple attachments might be queued
+    // for a particular message, but any individual attachment can only be loaded once)
+    public boolean equals(Object o) {
+        if (!(o instanceof PartRequest)) return false;
+        return ((PartRequest)o).mAttachment.mId == mAttachment.mId;
+    }
+
+    public int hashCode() {
+        return (int)mAttachment.mId;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/Request.java b/exchange2/src/com/android/exchange/Request.java
new file mode 100644
index 0000000..280a084
--- /dev/null
+++ b/exchange2/src/com/android/exchange/Request.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+/**
+ * Requests for mailbox actions are handled by subclasses of this abstract class.
+ * Three subclasses are now defined: PartRequest (attachment load), MeetingResponseRequest
+ * (respond to a meeting invitation), and MessageMoveRequest (move a message to another folder)
+ */
+public abstract class Request {
+    public final long mTimeStamp = System.currentTimeMillis();
+    public final long mMessageId;
+
+    public Request(long messageId) {
+        mMessageId = messageId;
+    }
+
+    // Subclasses of Request may have different semantics regarding equality; therefore,
+    // we force them to implement the equals method
+    public abstract boolean equals(Object o);
+    public abstract int hashCode();
+}
diff --git a/exchange2/src/com/android/exchange/SettingsRedirector.java b/exchange2/src/com/android/exchange/SettingsRedirector.java
new file mode 100644
index 0000000..5a50825
--- /dev/null
+++ b/exchange2/src/com/android/exchange/SettingsRedirector.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.exchange;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.emailcommon.utility.IntentUtilities;
+
+/**
+ * An empty {@link Activity} that simply redirects to the proper settings editor for the Email
+ * application.
+ * This is needed since the Exchange service runs as a separate UID and is therefore tracked as
+ * a separate entity in the framework for things such as data usage. Links from those places to
+ * Exchange should really go to Email where the real settings are.
+ */
+public class SettingsRedirector extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+        Intent redirect = new Intent(
+                Intent.ACTION_EDIT,
+                IntentUtilities.createActivityIntentUrlBuilder("settings").build());
+        redirect.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+        startActivity(redirect);
+        finish();
+    }
+}
diff --git a/exchange2/src/com/android/exchange/StaleFolderListException.java b/exchange2/src/com/android/exchange/StaleFolderListException.java
new file mode 100644
index 0000000..70ac032
--- /dev/null
+++ b/exchange2/src/com/android/exchange/StaleFolderListException.java
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+public class StaleFolderListException extends EasException {
+    private static final long serialVersionUID = 1L;
+}
diff --git a/exchange2/src/com/android/exchange/adapter/AbstractSyncAdapter.java b/exchange2/src/com/android/exchange/adapter/AbstractSyncAdapter.java
new file mode 100644
index 0000000..52400c4
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/AbstractSyncAdapter.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.Eas;
+import com.android.exchange.EasSyncService;
+import com.google.common.annotations.VisibleForTesting;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.os.TransactionTooLargeException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Parent class of all sync adapters (EasMailbox, EasCalendar, and EasContacts)
+ *
+ */
+public abstract class AbstractSyncAdapter {
+
+    public static final int SECONDS = 1000;
+    public static final int MINUTES = SECONDS*60;
+    public static final int HOURS = MINUTES*60;
+    public static final int DAYS = HOURS*24;
+    public static final int WEEKS = DAYS*7;
+
+    protected static final String PIM_WINDOW_SIZE = "4";
+
+    private static final long SEPARATOR_ID = Long.MAX_VALUE;
+
+    public Mailbox mMailbox;
+    public EasSyncService mService;
+    public Context mContext;
+    public Account mAccount;
+    public final ContentResolver mContentResolver;
+    public final android.accounts.Account mAccountManagerAccount;
+
+    // Create the data for local changes that need to be sent up to the server
+    public abstract boolean sendLocalChanges(Serializer s) throws IOException;
+    // Parse incoming data from the EAS server, creating, modifying, and deleting objects as
+    // required through the EmailProvider
+    public abstract boolean parse(InputStream is) throws IOException, CommandStatusException;
+    // The name used to specify the collection type of the target (Email, Calendar, or Contacts)
+    public abstract String getCollectionName();
+    public abstract void cleanup();
+    public abstract boolean isSyncable();
+    // Add sync options (filter, body type - html vs plain, and truncation)
+    public abstract void sendSyncOptions(Double protocolVersion, Serializer s) throws IOException;
+    /**
+     * Delete all records of this class in this account
+     */
+    public abstract void wipe();
+
+    public boolean isLooping() {
+        return false;
+    }
+
+    public AbstractSyncAdapter(EasSyncService service) {
+        mService = service;
+        mMailbox = service.mMailbox;
+        mContext = service.mContext;
+        mAccount = service.mAccount;
+        mAccountManagerAccount = new android.accounts.Account(mAccount.mEmailAddress,
+                Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+        mContentResolver = mContext.getContentResolver();
+    }
+
+    public void userLog(String ...strings) {
+        mService.userLog(strings);
+    }
+
+    public void incrementChangeCount() {
+        mService.mChangeCount++;
+    }
+
+    /**
+     * Set sync options common to PIM's (contacts and calendar)
+     * @param protocolVersion the protocol version under which we're syncing
+     * @param the filter to use (or null)
+     * @param s the Serializer
+     * @throws IOException
+     */
+    protected void setPimSyncOptions(Double protocolVersion, String filter, Serializer s)
+            throws IOException {
+        s.tag(Tags.SYNC_DELETES_AS_MOVES);
+        s.tag(Tags.SYNC_GET_CHANGES);
+        s.data(Tags.SYNC_WINDOW_SIZE, PIM_WINDOW_SIZE);
+        s.start(Tags.SYNC_OPTIONS);
+        // Set the filter (lookback), if provided
+        if (filter != null) {
+            s.data(Tags.SYNC_FILTER_TYPE, filter);
+        }
+        // Set the truncation amount and body type
+        if (protocolVersion >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+            s.start(Tags.BASE_BODY_PREFERENCE);
+            // Plain text
+            s.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_TEXT);
+            s.data(Tags.BASE_TRUNCATION_SIZE, Eas.EAS12_TRUNCATION_SIZE);
+            s.end();
+        } else {
+            s.data(Tags.SYNC_TRUNCATION, Eas.EAS2_5_TRUNCATION_SIZE);
+        }
+        s.end();
+    }
+
+    /**
+     * Returns the current SyncKey; override if the SyncKey is stored elsewhere (as for Contacts)
+     * @return the current SyncKey for the Mailbox
+     * @throws IOException
+     */
+    public String getSyncKey() throws IOException {
+        if (mMailbox.mSyncKey == null) {
+            userLog("Reset SyncKey to 0");
+            mMailbox.mSyncKey = "0";
+        }
+        return mMailbox.mSyncKey;
+    }
+
+    public void setSyncKey(String syncKey, boolean inCommands) throws IOException {
+        mMailbox.mSyncKey = syncKey;
+    }
+
+    /**
+     * Operation is our binder-safe ContentProviderOperation (CPO) construct; an Operation can
+     * be created from a CPO, a CPO Builder, or a CPO Builder with a "back reference" column name
+     * and offset (that might be used in Builder.withValueBackReference).  The CPO is not actually
+     * built until it is ready to be executed (with applyBatch); this allows us to recalculate
+     * back reference offsets if we are required to re-send a large batch in smaller chunks.
+     *
+     * NOTE: A failed binder transaction is something of an emergency case, and shouldn't happen
+     * with any frequency.  When it does, and we are forced to re-send the data to the content
+     * provider in smaller chunks, we DO lose the sync-window atomicity, and thereby add another
+     * small risk to the data.  Of course, this is far, far better than dropping the data on the
+     * floor, as was done before the framework implemented TransactionTooLargeException
+     */
+    protected static class Operation {
+        final ContentProviderOperation mOp;
+        final ContentProviderOperation.Builder mBuilder;
+        final String mColumnName;
+        final int mOffset;
+        // Is this Operation a separator? (a good place to break up a large transaction)
+        boolean mSeparator = false;
+
+        // For toString()
+        final String[] TYPES = new String[] {"???", "Ins", "Upd", "Del", "Assert"};
+
+        Operation(ContentProviderOperation.Builder builder, String columnName, int offset) {
+            mOp = null;
+            mBuilder = builder;
+            mColumnName = columnName;
+            mOffset = offset;
+        }
+
+        Operation(ContentProviderOperation.Builder builder) {
+            mOp = null;
+            mBuilder = builder;
+            mColumnName = null;
+            mOffset = 0;
+        }
+
+        Operation(ContentProviderOperation op) {
+            mOp = op;
+            mBuilder = null;
+            mColumnName = null;
+            mOffset = 0;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder("Op: ");
+            ContentProviderOperation op = operationToContentProviderOperation(this, 0);
+            int type = 0;
+            //DO NOT SHIP WITH THE FOLLOWING LINE (the API is hidden!)
+            //type = op.getType();
+            sb.append(TYPES[type]);
+            Uri uri = op.getUri();
+            sb.append(' ');
+            sb.append(uri.getPath());
+            if (mColumnName != null) {
+                sb.append(" Back value of " + mColumnName + ": " + mOffset);
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * We apply the batch of CPO's here.  We synchronize on the service to avoid thread-nasties,
+     * and we just return quickly if the service has already been stopped.
+     */
+    private ContentProviderResult[] execute(String authority,
+            ArrayList<ContentProviderOperation> ops)
+            throws RemoteException, OperationApplicationException {
+        synchronized (mService.getSynchronizer()) {
+            if (!mService.isStopped()) {
+                if (!ops.isEmpty()) {
+                    ContentProviderResult[] result = mContentResolver.applyBatch(authority, ops);
+                    mService.userLog("Results: " + result.length);
+                    return result;
+                }
+            }
+        }
+        return new ContentProviderResult[0];
+    }
+
+    /**
+     * Convert an Operation to a CPO; if the Operation has a back reference, apply it with the
+     * passed-in offset
+     */
+    @VisibleForTesting
+    static ContentProviderOperation operationToContentProviderOperation(Operation op, int offset) {
+        if (op.mOp != null) {
+            return op.mOp;
+        } else if (op.mBuilder == null) {
+            throw new IllegalArgumentException("Operation must have CPO.Builder");
+        }
+        ContentProviderOperation.Builder builder = op.mBuilder;
+        if (op.mColumnName != null) {
+            builder.withValueBackReference(op.mColumnName, op.mOffset - offset);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Create a list of CPOs from a list of Operations, and then apply them in a batch
+     */
+    private ContentProviderResult[] applyBatch(String authority, ArrayList<Operation> ops,
+            int offset) throws RemoteException, OperationApplicationException {
+        // Handle the empty case
+        if (ops.isEmpty()) {
+            return new ContentProviderResult[0];
+        }
+        ArrayList<ContentProviderOperation> cpos = new ArrayList<ContentProviderOperation>();
+        for (Operation op: ops) {
+            cpos.add(operationToContentProviderOperation(op, offset));
+        }
+        return execute(authority, cpos);
+    }
+
+    /**
+     * Apply the list of CPO's in the provider and copy the "mini" result into our full result array
+     */
+    private void applyAndCopyResults(String authority, ArrayList<Operation> mini,
+            ContentProviderResult[] result, int offset) throws RemoteException {
+        // Empty lists are ok; we just ignore them
+        if (mini.isEmpty()) return;
+        try {
+            ContentProviderResult[] miniResult = applyBatch(authority, mini, offset);
+            // Copy the results from this mini-batch into our results array
+            System.arraycopy(miniResult, 0, result, offset, miniResult.length);
+        } catch (OperationApplicationException e) {
+            // Not possible since we're building the ops ourselves
+        }
+    }
+
+    /**
+     * Called by a sync adapter to execute a list of Operations in the ContentProvider handling
+     * the passed-in authority.  If the attempt to apply the batch fails due to a too-large
+     * binder transaction, we split the Operations as directed by separators.  If any of the
+     * "mini" batches fails due to a too-large transaction, we're screwed, but this would be
+     * vanishingly rare.  Other, possibly transient, errors are handled by throwing a
+     * RemoteException, which the caller will likely re-throw as an IOException so that the sync
+     * can be attempted again.
+     *
+     * Callers MAY leave a dangling separator at the end of the list; note that the separators
+     * themselves are only markers and are not sent to the provider.
+     */
+    protected ContentProviderResult[] safeExecute(String authority, ArrayList<Operation> ops)
+            throws RemoteException {
+        mService.userLog("Try to execute ", ops.size(), " CPO's for " + authority);
+        ContentProviderResult[] result = null;
+        try {
+            // Try to execute the whole thing
+            return applyBatch(authority, ops, 0);
+        } catch (TransactionTooLargeException e) {
+            // Nope; split into smaller chunks, demarcated by the separator operation
+            mService.userLog("Transaction too large; spliting!");
+            ArrayList<Operation> mini = new ArrayList<Operation>();
+            // Build a result array with the total size we're sending
+            result = new ContentProviderResult[ops.size()];
+            int count = 0;
+            int offset = 0;
+            for (Operation op: ops) {
+                if (op.mSeparator) {
+                    try {
+                        mService.userLog("Try mini-batch of ", mini.size(), " CPO's");
+                        applyAndCopyResults(authority, mini, result, offset);
+                        mini.clear();
+                        // Save away the offset here; this will need to be subtracted out of the
+                        // value originally set by the adapter
+                        offset = count + 1; // Remember to add 1 for the separator!
+                    } catch (TransactionTooLargeException e1) {
+                        throw new RuntimeException("Can't send transaction; sync stopped.");
+                    } catch (RemoteException e1) {
+                        throw e1;
+                    }
+                } else {
+                    mini.add(op);
+                }
+                count++;
+            }
+            // Check out what's left; if it's more than just a separator, apply the batch
+            int miniSize = mini.size();
+            if ((miniSize > 0) && !(miniSize == 1 && mini.get(0).mSeparator)) {
+                applyAndCopyResults(authority, mini, result, offset);
+            }
+        } catch (RemoteException e) {
+            throw e;
+        } catch (OperationApplicationException e) {
+            // Not possible since we're building the ops ourselves
+        }
+        return result;
+    }
+
+    /**
+     * Called by a sync adapter to indicate a relatively safe place to split a batch of CPO's
+     */
+    protected void addSeparatorOperation(ArrayList<Operation> ops, Uri uri) {
+        Operation op = new Operation(
+                ContentProviderOperation.newDelete(ContentUris.withAppendedId(uri, SEPARATOR_ID)));
+        op.mSeparator = true;
+        ops.add(op);
+    }
+}
+
diff --git a/exchange2/src/com/android/exchange/adapter/AbstractSyncParser.java b/exchange2/src/com/android/exchange/adapter/AbstractSyncParser.java
new file mode 100644
index 0000000..1162b66
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/AbstractSyncParser.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.CommandStatusException.CommandStatus;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.ExchangeService;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Base class for the Email and PIM sync parsers
+ * Handles the basic flow of syncKeys, looping to get more data, handling errors, etc.
+ * Each subclass must implement a handful of methods that relate specifically to the data type
+ *
+ */
+public abstract class AbstractSyncParser extends Parser {
+
+    protected EasSyncService mService;
+    protected Mailbox mMailbox;
+    protected Account mAccount;
+    protected Context mContext;
+    protected ContentResolver mContentResolver;
+    protected AbstractSyncAdapter mAdapter;
+
+    private boolean mLooping;
+
+    public AbstractSyncParser(InputStream in, AbstractSyncAdapter adapter) throws IOException {
+        super(in);
+        init(adapter);
+    }
+
+    public AbstractSyncParser(Parser p, AbstractSyncAdapter adapter) throws IOException {
+        super(p);
+        init(adapter);
+    }
+
+    private void init(AbstractSyncAdapter adapter) {
+        mAdapter = adapter;
+        mService = adapter.mService;
+        mContext = mService.mContext;
+        mContentResolver = mContext.getContentResolver();
+        mMailbox = mService.mMailbox;
+        mAccount = mService.mAccount;
+    }
+
+    /**
+     * Read, parse, and act on incoming commands from the Exchange server
+     * @throws IOException if the connection is broken
+     * @throws CommandStatusException
+     */
+    public abstract void commandsParser() throws IOException, CommandStatusException;
+
+    /**
+     * Read, parse, and act on server responses
+     * @throws IOException
+     */
+    public abstract void responsesParser() throws IOException;
+
+    /**
+     * Commit any changes found during parsing
+     * @throws IOException
+     */
+    public abstract void commit() throws IOException;
+
+    public boolean isLooping() {
+        return mLooping;
+    }
+
+    /**
+     * Skip through tags until we reach the specified end tag
+     * @param endTag the tag we end with
+     * @throws IOException
+     */
+    public void skipParser(int endTag) throws IOException {
+        while (nextTag(endTag) != END) {
+            skipTag();
+        }
+    }
+
+    /**
+     * Loop through the top-level structure coming from the Exchange server
+     * Sync keys and the more available flag are handled here, whereas specific data parsing
+     * is handled by abstract methods implemented for each data class (e.g. Email, Contacts, etc.)
+     * @throws CommandStatusException
+     */
+    @Override
+    public boolean parse() throws IOException, CommandStatusException {
+        int status;
+        boolean moreAvailable = false;
+        boolean newSyncKey = false;
+        int interval = mMailbox.mSyncInterval;
+        mLooping = false;
+        // If we're not at the top of the xml tree, throw an exception
+        if (nextTag(START_DOCUMENT) != Tags.SYNC_SYNC) {
+            throw new EasParserException();
+        }
+
+        boolean mailboxUpdated = false;
+        ContentValues cv = new ContentValues();
+
+        // Loop here through the remaining xml
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.SYNC_COLLECTION || tag == Tags.SYNC_COLLECTIONS) {
+                // Ignore these tags, since we've only got one collection syncing in this loop
+            } else if (tag == Tags.SYNC_STATUS) {
+                // Status = 1 is success; everything else is a failure
+                status = getValueInt();
+                if (status != 1) {
+                    mService.errorLog("Sync failed: " + CommandStatus.toString(status));
+                    if (status == 3 || CommandStatus.isBadSyncKey(status)) {
+                        // Must delete all of the data and start over with syncKey of "0"
+                        mAdapter.setSyncKey("0", false);
+                        // Make this a push box through the first sync
+                        // TODO Make frequency conditional on user settings!
+                        mMailbox.mSyncInterval = Mailbox.CHECK_INTERVAL_PUSH;
+                        mService.errorLog("Bad sync key; RESET and delete data");
+                        mAdapter.wipe();
+                        // Indicate there's more so that we'll start syncing again
+                        moreAvailable = true;
+                    } else if (status == 16 || status == 5) {
+                        // Status 16 indicates a transient server error (indeterminate state)
+                        // Status 5 indicates "server error"; this tends to loop for a while so
+                        // throwing IOException will at least provide backoff behavior
+                        throw new IOException();
+                    } else if (status == 8 || status == 12) {
+                        // Status 8 is Bad; it means the server doesn't recognize the serverId it
+                        // sent us.  12 means that we're being asked to refresh the folder list.
+                        // We'll do that with 8 also...
+                        ExchangeService.reloadFolderList(mContext, mAccount.mId, true);
+                        // We don't have any provision for telling the user "wait a minute while
+                        // we sync folders"...
+                        throw new IOException();
+                    } else if (status == 7) {
+                        mService.mUpsyncFailed = true;
+                        moreAvailable = true;
+                    } else {
+                        // Access, provisioning, transient, etc.
+                        throw new CommandStatusException(status);
+                    }
+                }
+            } else if (tag == Tags.SYNC_COMMANDS) {
+                commandsParser();
+            } else if (tag == Tags.SYNC_RESPONSES) {
+                responsesParser();
+            } else if (tag == Tags.SYNC_MORE_AVAILABLE) {
+                moreAvailable = true;
+            } else if (tag == Tags.SYNC_SYNC_KEY) {
+                if (mAdapter.getSyncKey().equals("0")) {
+                    moreAvailable = true;
+                }
+                String newKey = getValue();
+                userLog("Parsed key for ", mMailbox.mDisplayName, ": ", newKey);
+                if (!newKey.equals(mMailbox.mSyncKey)) {
+                    mAdapter.setSyncKey(newKey, true);
+                    cv.put(MailboxColumns.SYNC_KEY, newKey);
+                    mailboxUpdated = true;
+                    newSyncKey = true;
+                }
+                // If we were pushing (i.e. auto-start), now we'll become ping-triggered
+                if (mMailbox.mSyncInterval == Mailbox.CHECK_INTERVAL_PUSH) {
+                    mMailbox.mSyncInterval = Mailbox.CHECK_INTERVAL_PING;
+                }
+           } else {
+                skipTag();
+           }
+        }
+
+        // If we don't have a new sync key, ignore moreAvailable (or we'll loop)
+        if (moreAvailable && !newSyncKey) {
+            mLooping = true;
+        }
+
+        // Commit any changes
+        commit();
+
+        boolean abortSyncs = false;
+
+        // If the sync interval has changed, we need to save it
+        if (mMailbox.mSyncInterval != interval) {
+            cv.put(MailboxColumns.SYNC_INTERVAL, mMailbox.mSyncInterval);
+            mailboxUpdated = true;
+        // If there are changes, and we were bounced from push/ping, try again
+        } else if (mService.mChangeCount > 0 &&
+                mAccount.mSyncInterval == Account.CHECK_INTERVAL_PUSH &&
+                mMailbox.mSyncInterval > 0) {
+            userLog("Changes found to ping loop mailbox ", mMailbox.mDisplayName, ": will ping.");
+            cv.put(MailboxColumns.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PING);
+            mailboxUpdated = true;
+            abortSyncs = true;
+        }
+
+        if (mailboxUpdated) {
+             synchronized (mService.getSynchronizer()) {
+                if (!mService.isStopped()) {
+                     mMailbox.update(mContext, cv);
+                }
+            }
+        }
+
+        if (abortSyncs) {
+            userLog("Aborting account syncs due to mailbox change to ping...");
+            ExchangeService.stopAccountSyncs(mAccount.mId);
+        }
+
+        // Let the caller know that there's more to do
+        if (moreAvailable) {
+            userLog("MoreAvailable");
+        }
+        return moreAvailable;
+    }
+
+    void userLog(String ...strings) {
+        mService.userLog(strings);
+    }
+
+    void userLog(String string, int num, String string2) {
+        mService.userLog(string, num, string2);
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/AccountSyncAdapter.java b/exchange2/src/com/android/exchange/adapter/AccountSyncAdapter.java
new file mode 100644
index 0000000..cf54ed5
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/AccountSyncAdapter.java
@@ -0,0 +1,45 @@
+package com.android.exchange.adapter;
+
+import com.android.exchange.EasSyncService;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class AccountSyncAdapter extends AbstractSyncAdapter {
+
+    public AccountSyncAdapter(EasSyncService service) {
+        super(service);
+     }
+
+    @Override
+    public void cleanup() {
+    }
+
+    @Override
+    public void wipe() {
+    }
+
+    @Override
+    public String getCollectionName() {
+        return null;
+    }
+
+    @Override
+    public boolean parse(InputStream is) throws IOException {
+        return false;
+    }
+
+    @Override
+    public boolean sendLocalChanges(Serializer s) throws IOException {
+        return false;
+    }
+
+    @Override
+    public boolean isSyncable() {
+        return true;
+    }
+
+    @Override
+    public void sendSyncOptions(Double protocolVersion, Serializer s) throws IOException {
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/AttachmentLoader.java b/exchange2/src/com/android/exchange/adapter/AttachmentLoader.java
new file mode 100644
index 0000000..04cf555
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/AttachmentLoader.java
@@ -0,0 +1,248 @@
+/* Copyright (C) 2011 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.os.RemoteException;
+
+import com.android.emailcommon.provider.EmailContent.Attachment;
+import com.android.emailcommon.provider.EmailContent.AttachmentColumns;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.service.EmailServiceStatus;
+import com.android.emailcommon.utility.AttachmentUtilities;
+import com.android.exchange.Eas;
+import com.android.exchange.EasResponse;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.ExchangeService;
+import com.android.exchange.PartRequest;
+import com.android.exchange.utility.UriCodec;
+import com.android.mail.providers.UIProvider;
+import com.google.common.annotations.VisibleForTesting;
+
+import org.apache.http.HttpStatus;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Handle EAS attachment loading, regardless of protocol version
+ */
+public class AttachmentLoader {
+    static private final int CHUNK_SIZE = 16*1024;
+
+    private final EasSyncService mService;
+    private final Context mContext;
+    private final ContentResolver mResolver;
+    private final Attachment mAttachment;
+    private final long mAttachmentId;
+    private final int mAttachmentSize;
+    private final long mMessageId;
+    private final Message mMessage;
+    private final long mAccountId;
+    private final Uri mAttachmentUri;
+
+    public AttachmentLoader(EasSyncService service, PartRequest req) {
+        mService = service;
+        mContext = service.mContext;
+        mResolver = service.mContentResolver;
+        mAttachment = req.mAttachment;
+        mAttachmentId = mAttachment.mId;
+        mAttachmentSize = (int)mAttachment.mSize;
+        mAccountId = mAttachment.mAccountKey;
+        mMessageId = mAttachment.mMessageKey;
+        mMessage = Message.restoreMessageWithId(mContext, mMessageId);
+        mAttachmentUri = AttachmentUtilities.getAttachmentUri(mAccountId, mAttachmentId);
+    }
+
+    private void doStatusCallback(int status) {
+        try {
+            ExchangeService.callback().loadAttachmentStatus(mMessageId, mAttachmentId, status, 0);
+        } catch (RemoteException e) {
+            // No danger if the client is no longer around
+        }
+    }
+
+    private void doProgressCallback(int progress) {
+        try {
+            ExchangeService.callback().loadAttachmentStatus(mMessageId, mAttachmentId,
+                    EmailServiceStatus.IN_PROGRESS, progress);
+        } catch (RemoteException e) {
+            // No danger if the client is no longer around
+        }
+    }
+
+    /**
+     * Save away the contentUri for this Attachment and notify listeners
+     */
+    private void finishLoadAttachment() {
+        ContentValues cv = new ContentValues();
+        cv.put(AttachmentColumns.CONTENT_URI, mAttachmentUri.toString());
+        cv.put(AttachmentColumns.UI_STATE, UIProvider.AttachmentState.SAVED);
+        mAttachment.update(mContext, cv);
+        doStatusCallback(EmailServiceStatus.SUCCESS);
+    }
+
+    /**
+     * Read the attachment data in chunks and write the data back out to our attachment file
+     * @param inputStream the InputStream we're reading the attachment from
+     * @param outputStream the OutputStream the attachment will be written to
+     * @param len the number of expected bytes we're going to read
+     * @throws IOException
+     */
+    public void readChunked(InputStream inputStream, OutputStream outputStream, int len)
+            throws IOException {
+        byte[] bytes = new byte[CHUNK_SIZE];
+        int length = len;
+        // Loop terminates 1) when EOF is reached or 2) IOException occurs
+        // One of these is guaranteed to occur
+        int totalRead = 0;
+        int lastCallbackPct = -1;
+        int lastCallbackTotalRead = 0;
+        mService.userLog("Expected attachment length: ", len);
+        while (true) {
+            int read = inputStream.read(bytes, 0, CHUNK_SIZE);
+            if (read < 0) {
+                // -1 means EOF
+                mService.userLog("Attachment load reached EOF, totalRead: ", totalRead);
+                break;
+            }
+
+            // Keep track of how much we've read for progress callback
+            totalRead += read;
+            // Write these bytes out
+            outputStream.write(bytes, 0, read);
+
+            // We can't report percentage if data is chunked; the length of incoming data is unknown
+            if (length > 0) {
+                int pct = (totalRead * 100) / length;
+                // Callback only if we've read at least 1% more and have read more than CHUNK_SIZE
+                // We don't want to spam the Email app
+                if ((pct > lastCallbackPct) && (totalRead > (lastCallbackTotalRead + CHUNK_SIZE))) {
+                    // Report progress back to the UI
+                    doProgressCallback(pct);
+                    lastCallbackTotalRead = totalRead;
+                    lastCallbackPct = pct;
+                }
+            }
+        }
+        if (totalRead > length) {
+            // Apparently, the length, as reported by EAS, isn't always accurate; let's log it
+            mService.userLog("Read more than expected: ", totalRead);
+        }
+    }
+
+    @VisibleForTesting
+    static String encodeForExchange2003(String str) {
+        AttachmentNameEncoder enc = new AttachmentNameEncoder();
+        StringBuilder sb = new StringBuilder(str.length() + 16);
+        enc.appendPartiallyEncoded(sb, str);
+        return sb.toString();
+    }
+
+    /**
+     * Encoder for Exchange 2003 attachment names.  They come from the server partially encoded,
+     * but there are still possible characters that need to be encoded (Why, MSFT, why?)
+     */
+    private static class AttachmentNameEncoder extends UriCodec {
+        @Override protected boolean isRetained(char c) {
+            // These four characters are commonly received in EAS 2.5 attachment names and are
+            // valid (verified by testing); we won't encode them
+            return c == '_' || c == ':' || c == '/' || c == '.';
+        }
+    }
+
+    /**
+     * Loads an attachment, based on the PartRequest passed in the constructor
+     * @throws IOException
+     */
+    public void loadAttachment() throws IOException {
+        if (mMessage == null) {
+            doStatusCallback(EmailServiceStatus.MESSAGE_NOT_FOUND);
+            return;
+        }
+        // Say we've started loading the attachment
+        doProgressCallback(0);
+
+        EasResponse resp;
+        boolean eas14 = mService.mProtocolVersionDouble >= Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE;
+        // The method of attachment loading is different in EAS 14.0 than in earlier versions
+        if (eas14) {
+            Serializer s = new Serializer();
+            s.start(Tags.ITEMS_ITEMS).start(Tags.ITEMS_FETCH);
+            s.data(Tags.ITEMS_STORE, "Mailbox");
+            s.data(Tags.BASE_FILE_REFERENCE, mAttachment.mLocation);
+            s.end().end().done(); // ITEMS_FETCH, ITEMS_ITEMS
+            resp = mService.sendHttpClientPost("ItemOperations", s.toByteArray());
+        } else {
+            String location = mAttachment.mLocation;
+            // For Exchange 2003 (EAS 2.5), we have to look for illegal characters in the file name
+            // that EAS sent to us!
+            if (mService.mProtocolVersionDouble < Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+                location = encodeForExchange2003(location);
+            }
+            String cmd = "GetAttachment&AttachmentName=" + location;
+            resp = mService.sendHttpClientPost(cmd, null, EasSyncService.COMMAND_TIMEOUT);
+        }
+
+        try {
+            int status = resp.getStatus();
+            if (status == HttpStatus.SC_OK) {
+                if (!resp.isEmpty()) {
+                    InputStream is = resp.getInputStream();
+                    OutputStream os = null;
+                    try {
+                        os = mResolver.openOutputStream(mAttachmentUri);
+                        if (eas14) {
+                            ItemOperationsParser p = new ItemOperationsParser(this, is, os,
+                                    mAttachmentSize);
+                            p.parse();
+                            if (p.getStatusCode() == 1 /* Success */) {
+                                finishLoadAttachment();
+                                return;
+                            }
+                        } else {
+                            int len = resp.getLength();
+                            if (len != 0) {
+                                // len > 0 means that Content-Length was set in the headers
+                                // len < 0 means "chunked" transfer-encoding
+                                readChunked(is, os, (len < 0) ? mAttachmentSize : len);
+                                finishLoadAttachment();
+                                return;
+                            }
+                        }
+                    } catch (FileNotFoundException e) {
+                        mService.errorLog("Can't get attachment; write file not found?");
+                    } finally {
+                        if (os != null) {
+                            os.flush();
+                            os.close();
+                        }
+                    }
+                }
+            }
+        } finally {
+            resp.close();
+        }
+
+        // All errors lead here...
+        doStatusCallback(EmailServiceStatus.ATTACHMENT_NOT_FOUND);
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/Base64InputStream.java b/exchange2/src/com/android/exchange/adapter/Base64InputStream.java
new file mode 100644
index 0000000..5b78c4c
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/Base64InputStream.java
@@ -0,0 +1,175 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+/**
+ * Modified for Exchange attachment decoding 5/12/11.  Changes are bracketed with START EAS CHANGES
+ * and END EAS CHANGES
+ *
+ * Without the included changes, the final bytes of the input stream will be read here and thrown
+ * away; in that case, the WBXML parser will lose information necessary to determine that the
+ * entire stream has been processed correctly.  Since inline WBXML text is terminated with a zero
+ * byte, and since zero is not valid Base64, we terminate reading when we find a zero byte, leaving
+ * the remainder of the stream untouched (to be read by the Parser that created the
+ * Base64InputStream.
+ */
+
+package com.android.exchange.adapter;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Performs Base-64 decoding on an underlying stream.
+ *
+ *
+ * @version $Id: Base64InputStream.java,v 1.3 2004/11/29 13:15:47 ntherning Exp $
+ */
+public class Base64InputStream extends InputStream {
+    private final InputStream s;
+    private int outCount = 0;
+    private int outIndex = 0;
+    private final int[] outputBuffer = new int[3];
+    private final byte[] inputBuffer = new byte[4];
+    private boolean done = false;
+    // START EAS CHANGES
+    private boolean padSeen = false;
+    // END EAS CHANGES
+
+    public Base64InputStream(InputStream s) {
+        this.s = s;
+    }
+
+    /**
+     * Closes the underlying stream.
+     *
+     * @throws IOException on I/O errors.
+     */
+    @Override
+    public void close() throws IOException {
+        s.close();
+    }
+
+    @Override
+    public int read() throws IOException {
+        if (outIndex == outCount) {
+            fillBuffer();
+            if (outIndex == outCount) {
+                return -1;
+            }
+        }
+
+        return outputBuffer[outIndex++];
+    }
+
+    /**
+     * Retrieve data from the underlying stream, decode it,
+     * and put the results in the byteq.
+     * @throws IOException
+     */
+    private void fillBuffer() throws IOException {
+        outCount = 0;
+        outIndex = 0;
+        int inCount = 0;
+
+        int i;
+        // "done" is needed for the two successive '=' at the end
+        while (!done) {
+            switch (i = s.read()) {
+                // START EAS CHANGES
+                case 0:
+                    // In EAS, a zero will indicate the end of the (inline) base64 string
+                    // Stop reading at this point, so that we can continue with WBXML
+                    done = true;
+                    return;
+                // END EAS CHANGES
+                case -1:
+                    // No more input - just return, let outputBuffer drain out, and be done
+                    return;
+                case '=':
+                    // START EAS CHANGES
+                    // Allow for a second '=' before we're really done (we should get a zero next)
+                    if (padSeen) {
+                        return;
+                    }
+                    // We've seen a (first) end padding character, flush what's in the buffer
+                    padSeen = true;
+                    // END EAS CHANGES
+                    // PRE-EAS LINE COMMENTED OUT
+                    //done = true;
+                    decodeAndEnqueue(inCount);
+                    return;
+                default:
+                    byte sX = TRANSLATION[i];
+                    if (sX < 0) continue;
+                    inputBuffer[inCount++] = sX;
+                    if (inCount == 4) {
+                        decodeAndEnqueue(inCount);
+                        return;
+                    }
+                    break;
+            }
+        }
+    }
+
+    private void decodeAndEnqueue(int len) {
+        int accum = 0;
+        accum |= inputBuffer[0] << 18;
+        accum |= inputBuffer[1] << 12;
+        accum |= inputBuffer[2] << 6;
+        accum |= inputBuffer[3];
+
+        // There's a bit of duplicated code here because we want to have straight-through operation
+        // for the most common case of len==4
+        if (len == 4) {
+            outputBuffer[0] = (accum >> 16) & 0xFF;
+            outputBuffer[1] = (accum >> 8) & 0xFF;
+            outputBuffer[2] = (accum) & 0xFF;
+            outCount = 3;
+            return;
+        } else if (len == 3) {
+            outputBuffer[0] = (accum >> 16) & 0xFF;
+            outputBuffer[1] = (accum >> 8) & 0xFF;
+            outCount = 2;
+            return;
+        } else {    // len == 2
+            outputBuffer[0] = (accum >> 16) & 0xFF;
+            outCount = 1;
+            return;
+        }
+    }
+
+    private static byte[] TRANSLATION = {
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
+        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
+        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 0x40 */
+        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
+        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
+        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 */
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 0xF0 */
+    };
+}
diff --git a/exchange2/src/com/android/exchange/adapter/CalendarSyncAdapter.java b/exchange2/src/com/android/exchange/adapter/CalendarSyncAdapter.java
new file mode 100644
index 0000000..4df45a9
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/CalendarSyncAdapter.java
@@ -0,0 +1,2163 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import android.content.ContentProviderClient;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Entity;
+import android.content.Entity.NamedContentValues;
+import android.content.EntityIterator;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.CalendarContract;
+import android.provider.CalendarContract.Attendees;
+import android.provider.CalendarContract.Calendars;
+import android.provider.CalendarContract.Events;
+import android.provider.CalendarContract.EventsEntity;
+import android.provider.CalendarContract.ExtendedProperties;
+import android.provider.CalendarContract.Reminders;
+import android.provider.CalendarContract.SyncState;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.SyncStateContract;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.calendarcommon.DateException;
+import com.android.calendarcommon.Duration;
+import com.android.emailcommon.AccountManagerTypes;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.Eas;
+import com.android.exchange.EasOutboxService;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.ExchangeService;
+import com.android.exchange.utility.CalendarUtilities;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.UUID;
+
+/**
+ * Sync adapter class for EAS calendars
+ *
+ */
+public class CalendarSyncAdapter extends AbstractSyncAdapter {
+
+    private static final String TAG = "EasCalendarSyncAdapter";
+
+    private static final String EVENT_SAVED_TIMEZONE_COLUMN = Events.SYNC_DATA1;
+    /**
+     * Used to keep track of exception vs parent event dirtiness.
+     */
+    private static final String EVENT_SYNC_MARK = Events.SYNC_DATA8;
+    private static final String EVENT_SYNC_VERSION = Events.SYNC_DATA4;
+    // Since exceptions will have the same _SYNC_ID as the original event we have to check that
+    // there's no original event when finding an item by _SYNC_ID
+    private static final String SERVER_ID_AND_CALENDAR_ID = Events._SYNC_ID + "=? AND " +
+        Events.ORIGINAL_SYNC_ID + " ISNULL AND " + Events.CALENDAR_ID + "=?";
+    private static final String EVENT_ID_AND_CALENDAR_ID = Events._ID + "=? AND " +
+        Events.ORIGINAL_SYNC_ID + " ISNULL AND " + Events.CALENDAR_ID + "=?";
+    private static final String DIRTY_OR_MARKED_TOP_LEVEL_IN_CALENDAR = "(" + Events.DIRTY
+            + "=1 OR " + EVENT_SYNC_MARK + "= 1) AND " +
+        Events.ORIGINAL_ID + " ISNULL AND " + Events.CALENDAR_ID + "=?";
+    private static final String DIRTY_EXCEPTION_IN_CALENDAR =
+        Events.DIRTY + "=1 AND " + Events.ORIGINAL_ID + " NOTNULL AND " +
+        Events.CALENDAR_ID + "=?";
+    private static final String CLIENT_ID_SELECTION = Events.SYNC_DATA2 + "=?";
+    private static final String ORIGINAL_EVENT_AND_CALENDAR =
+        Events.ORIGINAL_SYNC_ID + "=? AND " + Events.CALENDAR_ID + "=?";
+    private static final String ATTENDEES_EXCEPT_ORGANIZER = Attendees.EVENT_ID + "=? AND " +
+        Attendees.ATTENDEE_RELATIONSHIP + "!=" + Attendees.RELATIONSHIP_ORGANIZER;
+    private static final String[] ID_PROJECTION = new String[] {Events._ID};
+    private static final String[] ORIGINAL_EVENT_PROJECTION =
+        new String[] {Events.ORIGINAL_ID, Events._ID};
+    private static final String EVENT_ID_AND_NAME =
+        ExtendedProperties.EVENT_ID + "=? AND " + ExtendedProperties.NAME + "=?";
+
+    // Note that we use LIKE below for its case insensitivity
+    private static final String EVENT_AND_EMAIL  =
+        Attendees.EVENT_ID + "=? AND "+ Attendees.ATTENDEE_EMAIL + " LIKE ?";
+    private static final int ATTENDEE_STATUS_COLUMN_STATUS = 0;
+    private static final String[] ATTENDEE_STATUS_PROJECTION =
+        new String[] {Attendees.ATTENDEE_STATUS};
+
+    public static final String CALENDAR_SELECTION =
+        Calendars.ACCOUNT_NAME + "=? AND " + Calendars.ACCOUNT_TYPE + "=?";
+    private static final int CALENDAR_SELECTION_ID = 0;
+
+    private static final String[] EXTENDED_PROPERTY_PROJECTION =
+        new String[] {ExtendedProperties._ID};
+    private static final int EXTENDED_PROPERTY_ID = 0;
+
+    private static final String CATEGORY_TOKENIZER_DELIMITER = "\\";
+    private static final String ATTENDEE_TOKENIZER_DELIMITER = CATEGORY_TOKENIZER_DELIMITER;
+
+    private static final String EXTENDED_PROPERTY_USER_ATTENDEE_STATUS = "userAttendeeStatus";
+    private static final String EXTENDED_PROPERTY_ATTENDEES = "attendees";
+    private static final String EXTENDED_PROPERTY_DTSTAMP = "dtstamp";
+    private static final String EXTENDED_PROPERTY_MEETING_STATUS = "meeting_status";
+    private static final String EXTENDED_PROPERTY_CATEGORIES = "categories";
+    // Used to indicate that we removed the attendee list because it was too large
+    private static final String EXTENDED_PROPERTY_ATTENDEES_REDACTED = "attendeesRedacted";
+    // Used to indicate that upsyncs aren't allowed (we catch this in sendLocalChanges)
+    private static final String EXTENDED_PROPERTY_UPSYNC_PROHIBITED = "upsyncProhibited";
+
+    private static final Operation PLACEHOLDER_OPERATION =
+        new Operation(ContentProviderOperation.newInsert(Uri.EMPTY));
+
+    private static final Object sSyncKeyLock = new Object();
+
+    private static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC");
+    private final TimeZone mLocalTimeZone = TimeZone.getDefault();
+
+
+    // Maximum number of allowed attendees; above this number, we mark the Event with the
+    // attendeesRedacted extended property and don't allow the event to be upsynced to the server
+    private static final int MAX_SYNCED_ATTENDEES = 50;
+    // We set the organizer to this when the user is the organizer and we've redacted the
+    // attendee list.  By making the meeting organizer OTHER than the user, we cause the UI to
+    // prevent edits to this event (except local changes like reminder).
+    private static final String BOGUS_ORGANIZER_EMAIL = "upload_disallowed@uploadisdisallowed.aaa";
+    // Maximum number of CPO's before we start redacting attendees in exceptions
+    // The number 500 has been determined empirically; 1500 CPOs appears to be the limit before
+    // binder failures occur, but we need room at any point for additional events/exceptions so
+    // we set our limit at 1/3 of the apparent maximum for extra safety
+    // TODO Find a better solution to this workaround
+    private static final int MAX_OPS_BEFORE_EXCEPTION_ATTENDEE_REDACTION = 500;
+
+    private long mCalendarId = -1;
+    private String mCalendarIdString;
+    private String[] mCalendarIdArgument;
+    /*package*/ String mEmailAddress;
+
+    private ArrayList<Long> mDeletedIdList = new ArrayList<Long>();
+    private ArrayList<Long> mUploadedIdList = new ArrayList<Long>();
+    private ArrayList<Long> mSendCancelIdList = new ArrayList<Long>();
+    private ArrayList<Message> mOutgoingMailList = new ArrayList<Message>();
+
+    private final Uri mAsSyncAdapterAttendees;
+    private final Uri mAsSyncAdapterEvents;
+    private final Uri mAsSyncAdapterReminders;
+    private final Uri mAsSyncAdapterExtendedProperties;
+
+    public CalendarSyncAdapter(EasSyncService service) {
+        super(service);
+        mEmailAddress = mAccount.mEmailAddress;
+
+        String amType = Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE;
+        mAsSyncAdapterAttendees =
+                asSyncAdapter(Attendees.CONTENT_URI, mEmailAddress, amType);
+        mAsSyncAdapterEvents =
+                asSyncAdapter(Events.CONTENT_URI, mEmailAddress, amType);
+        mAsSyncAdapterReminders =
+                asSyncAdapter(Reminders.CONTENT_URI, mEmailAddress, amType);
+        mAsSyncAdapterExtendedProperties =
+                asSyncAdapter(ExtendedProperties.CONTENT_URI, mEmailAddress, amType);
+
+        Cursor c = mService.mContentResolver.query(Calendars.CONTENT_URI,
+                new String[] {Calendars._ID}, CALENDAR_SELECTION,
+                new String[] {mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE}, null);
+        if (c == null) return;
+        try {
+            if (c.moveToFirst()) {
+                mCalendarId = c.getLong(CALENDAR_SELECTION_ID);
+            } else {
+                mCalendarId = CalendarUtilities.createCalendar(mService, mAccount, mMailbox);
+            }
+            mCalendarIdString = Long.toString(mCalendarId);
+            mCalendarIdArgument = new String[] {mCalendarIdString};
+        } finally {
+            c.close();
+        }
+        }
+
+    @Override
+    public String getCollectionName() {
+        return "Calendar";
+    }
+
+    @Override
+    public void cleanup() {
+    }
+
+    @Override
+    public void wipe() {
+        // Delete the calendar associated with this account
+        // CalendarProvider2 does NOT handle selection arguments in deletions
+        mContentResolver.delete(
+                asSyncAdapter(Calendars.CONTENT_URI, mEmailAddress,
+                        Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                Calendars.ACCOUNT_NAME + "=" + DatabaseUtils.sqlEscapeString(mEmailAddress)
+                        + " AND " + Calendars.ACCOUNT_TYPE + "="
+                        + DatabaseUtils.sqlEscapeString(AccountManagerTypes.TYPE_EXCHANGE), null);
+        // Invalidate our calendar observers
+        ExchangeService.unregisterCalendarObservers();
+    }
+
+    @Override
+    public void sendSyncOptions(Double protocolVersion, Serializer s) throws IOException  {
+        setPimSyncOptions(protocolVersion, Eas.FILTER_2_WEEKS, s);
+    }
+
+    @Override
+    public boolean isSyncable() {
+        return ContentResolver.getSyncAutomatically(mAccountManagerAccount,
+                CalendarContract.AUTHORITY);
+    }
+
+    @Override
+    public boolean parse(InputStream is) throws IOException, CommandStatusException {
+        EasCalendarSyncParser p = new EasCalendarSyncParser(is, this);
+        return p.parse();
+    }
+
+    public static Uri asSyncAdapter(Uri uri, String account, String accountType) {
+        return uri.buildUpon().appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
+                .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
+                .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
+    }
+
+    /**
+     * Generate the uri for the data row associated with this NamedContentValues object
+     * @param ncv the NamedContentValues object
+     * @return a uri that can be used to refer to this row
+     */
+    public Uri dataUriFromNamedContentValues(NamedContentValues ncv) {
+        long id = ncv.values.getAsLong(RawContacts._ID);
+        Uri dataUri = ContentUris.withAppendedId(ncv.uri, id);
+        return dataUri;
+    }
+
+    /**
+     * We get our SyncKey from CalendarProvider.  If there's not one, we set it to "0" (the reset
+     * state) and save that away.
+     */
+    @Override
+    public String getSyncKey() throws IOException {
+        synchronized (sSyncKeyLock) {
+            ContentProviderClient client = mService.mContentResolver
+                    .acquireContentProviderClient(CalendarContract.CONTENT_URI);
+            try {
+                byte[] data = SyncStateContract.Helpers.get(
+                        client,
+                        asSyncAdapter(SyncState.CONTENT_URI, mEmailAddress,
+                                Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), mAccountManagerAccount);
+                if (data == null || data.length == 0) {
+                    // Initialize the SyncKey
+                    setSyncKey("0", false);
+                    return "0";
+                } else {
+                    String syncKey = new String(data);
+                    userLog("SyncKey retrieved as ", syncKey, " from CalendarProvider");
+                    return syncKey;
+                }
+            } catch (RemoteException e) {
+                throw new IOException("Can't get SyncKey from CalendarProvider");
+            }
+        }
+    }
+
+    /**
+     * We only need to set this when we're forced to make the SyncKey "0" (a reset).  In all other
+     * cases, the SyncKey is set within Calendar
+     */
+    @Override
+    public void setSyncKey(String syncKey, boolean inCommands) throws IOException {
+        synchronized (sSyncKeyLock) {
+            if ("0".equals(syncKey) || !inCommands) {
+                ContentProviderClient client = mService.mContentResolver
+                        .acquireContentProviderClient(CalendarContract.CONTENT_URI);
+                try {
+                    SyncStateContract.Helpers.set(
+                            client,
+                            asSyncAdapter(SyncState.CONTENT_URI, mEmailAddress,
+                                    Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), mAccountManagerAccount,
+                            syncKey.getBytes());
+                    userLog("SyncKey set to ", syncKey, " in CalendarProvider");
+                } catch (RemoteException e) {
+                    throw new IOException("Can't set SyncKey in CalendarProvider");
+                }
+            }
+            mMailbox.mSyncKey = syncKey;
+        }
+    }
+
+    public class EasCalendarSyncParser extends AbstractSyncParser {
+
+        String[] mBindArgument = new String[1];
+        Uri mAccountUri;
+        CalendarOperations mOps = new CalendarOperations();
+
+        public EasCalendarSyncParser(InputStream in, CalendarSyncAdapter adapter)
+                throws IOException {
+            super(in, adapter);
+            setLoggingTag("CalendarParser");
+            mAccountUri = Events.CONTENT_URI;
+        }
+
+        private void addOrganizerToAttendees(CalendarOperations ops, long eventId,
+                String organizerName, String organizerEmail) {
+            // Handle the organizer (who IS an attendee on device, but NOT in EAS)
+            if (organizerName != null || organizerEmail != null) {
+                ContentValues attendeeCv = new ContentValues();
+                if (organizerName != null) {
+                    attendeeCv.put(Attendees.ATTENDEE_NAME, organizerName);
+                }
+                if (organizerEmail != null) {
+                    attendeeCv.put(Attendees.ATTENDEE_EMAIL, organizerEmail);
+                }
+                attendeeCv.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ORGANIZER);
+                attendeeCv.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
+                attendeeCv.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_ACCEPTED);
+                if (eventId < 0) {
+                    ops.newAttendee(attendeeCv);
+                } else {
+                    ops.updatedAttendee(attendeeCv, eventId);
+                }
+            }
+        }
+
+        /**
+         * Set DTSTART, DTEND, DURATION and EVENT_TIMEZONE as appropriate for the given Event
+         * The follow rules are enforced by CalendarProvider2:
+         *   Events that aren't exceptions MUST have either 1) a DTEND or 2) a DURATION
+         *   Recurring events (i.e. events with RRULE) must have a DURATION
+         *   All-day recurring events MUST have a DURATION that is in the form P<n>D
+         *   Other events MAY have a DURATION in any valid form (we use P<n>M)
+         *   All-day events MUST have hour, minute, and second = 0; in addition, they must have
+         *   the EVENT_TIMEZONE set to UTC
+         *   Also, exceptions to all-day events need to have an ORIGINAL_INSTANCE_TIME that has
+         *   hour, minute, and second = 0 and be set in UTC
+         * @param cv the ContentValues for the Event
+         * @param startTime the start time for the Event
+         * @param endTime the end time for the Event
+         * @param allDayEvent whether this is an all day event (1) or not (0)
+         */
+        /*package*/ void setTimeRelatedValues(ContentValues cv, long startTime, long endTime,
+                int allDayEvent) {
+            // If there's no startTime, the event will be found to be invalid, so return
+            if (startTime < 0) return;
+            // EAS events can arrive without an end time, but CalendarProvider requires them
+            // so we'll default to 30 minutes; this will be superceded if this is an all-day event
+            if (endTime < 0) endTime = startTime + (30*MINUTES);
+
+            // If this is an all-day event, set hour, minute, and second to zero, and use UTC
+            if (allDayEvent != 0) {
+                startTime = CalendarUtilities.getUtcAllDayCalendarTime(startTime, mLocalTimeZone);
+                endTime = CalendarUtilities.getUtcAllDayCalendarTime(endTime, mLocalTimeZone);
+                String originalTimeZone = cv.getAsString(Events.EVENT_TIMEZONE);
+                cv.put(EVENT_SAVED_TIMEZONE_COLUMN, originalTimeZone);
+                cv.put(Events.EVENT_TIMEZONE, UTC_TIMEZONE.getID());
+            }
+
+            // If this is an exception, and the original was an all-day event, make sure the
+            // original instance time has hour, minute, and second set to zero, and is in UTC
+            if (cv.containsKey(Events.ORIGINAL_INSTANCE_TIME) &&
+                    cv.containsKey(Events.ORIGINAL_ALL_DAY)) {
+                Integer ade = cv.getAsInteger(Events.ORIGINAL_ALL_DAY);
+                if (ade != null && ade != 0) {
+                    long exceptionTime = cv.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
+                    GregorianCalendar cal = new GregorianCalendar(UTC_TIMEZONE);
+                    cal.setTimeInMillis(exceptionTime);
+                    cal.set(GregorianCalendar.HOUR_OF_DAY, 0);
+                    cal.set(GregorianCalendar.MINUTE, 0);
+                    cal.set(GregorianCalendar.SECOND, 0);
+                    cv.put(Events.ORIGINAL_INSTANCE_TIME, cal.getTimeInMillis());
+                }
+            }
+
+            // Always set DTSTART
+            cv.put(Events.DTSTART, startTime);
+            // For recurring events, set DURATION.  Use P<n>D format for all day events
+            if (cv.containsKey(Events.RRULE)) {
+                if (allDayEvent != 0) {
+                    cv.put(Events.DURATION, "P" + ((endTime - startTime) / DAYS) + "D");
+                }
+                else {
+                    cv.put(Events.DURATION, "P" + ((endTime - startTime) / MINUTES) + "M");
+                }
+            // For other events, set DTEND and LAST_DATE
+            } else {
+                cv.put(Events.DTEND, endTime);
+                cv.put(Events.LAST_DATE, endTime);
+            }
+        }
+
+        public void addEvent(CalendarOperations ops, String serverId, boolean update)
+                throws IOException {
+            ContentValues cv = new ContentValues();
+            cv.put(Events.CALENDAR_ID, mCalendarId);
+            cv.put(Events._SYNC_ID, serverId);
+            cv.put(Events.HAS_ATTENDEE_DATA, 1);
+            cv.put(Events.SYNC_DATA2, "0");
+
+            int allDayEvent = 0;
+            String organizerName = null;
+            String organizerEmail = null;
+            int eventOffset = -1;
+            int deleteOffset = -1;
+            int busyStatus = CalendarUtilities.BUSY_STATUS_TENTATIVE;
+            int responseType = CalendarUtilities.RESPONSE_TYPE_NONE;
+
+            boolean firstTag = true;
+            long eventId = -1;
+            long startTime = -1;
+            long endTime = -1;
+            TimeZone timeZone = null;
+
+            // Keep track of the attendees; exceptions will need them
+            ArrayList<ContentValues> attendeeValues = new ArrayList<ContentValues>();
+            int reminderMins = -1;
+            String dtStamp = null;
+            boolean organizerAdded = false;
+
+            while (nextTag(Tags.SYNC_APPLICATION_DATA) != END) {
+                if (update && firstTag) {
+                    // Find the event that's being updated
+                    Cursor c = getServerIdCursor(serverId);
+                    long id = -1;
+                    try {
+                        if (c != null && c.moveToFirst()) {
+                            id = c.getLong(0);
+                        }
+                    } finally {
+                        if (c != null) c.close();
+                    }
+                    if (id > 0) {
+                        // DTSTAMP can come first, and we simply need to track it
+                        if (tag == Tags.CALENDAR_DTSTAMP) {
+                            dtStamp = getValue();
+                            continue;
+                        } else if (tag == Tags.CALENDAR_ATTENDEES) {
+                            // This is an attendees-only update; just
+                            // delete/re-add attendees
+                            mBindArgument[0] = Long.toString(id);
+                            ops.add(new Operation(ContentProviderOperation
+                                    .newDelete(mAsSyncAdapterAttendees)
+                                    .withSelection(ATTENDEES_EXCEPT_ORGANIZER, mBindArgument)));
+                            eventId = id;
+                        } else {
+                            // Otherwise, delete the original event and recreate it
+                            userLog("Changing (delete/add) event ", serverId);
+                            deleteOffset = ops.newDelete(id, serverId);
+                            // Add a placeholder event so that associated tables can reference
+                            // this as a back reference.  We add the event at the end of the method
+                            eventOffset = ops.newEvent(PLACEHOLDER_OPERATION);
+                        }
+                    } else {
+                        // The changed item isn't found. We'll treat this as a new item
+                        eventOffset = ops.newEvent(PLACEHOLDER_OPERATION);
+                        userLog(TAG, "Changed item not found; treating as new.");
+                    }
+                } else if (firstTag) {
+                    // Add a placeholder event so that associated tables can reference
+                    // this as a back reference.  We add the event at the end of the method
+                   eventOffset = ops.newEvent(PLACEHOLDER_OPERATION);
+                }
+                firstTag = false;
+                switch (tag) {
+                    case Tags.CALENDAR_ALL_DAY_EVENT:
+                        allDayEvent = getValueInt();
+                        if (allDayEvent != 0 && timeZone != null) {
+                            // If the event doesn't start at midnight local time, we won't consider
+                            // this an all-day event in the local time zone (this is what OWA does)
+                            GregorianCalendar cal = new GregorianCalendar(mLocalTimeZone);
+                            cal.setTimeInMillis(startTime);
+                            userLog("All-day event arrived in: " + timeZone.getID());
+                            if (cal.get(GregorianCalendar.HOUR_OF_DAY) != 0 ||
+                                    cal.get(GregorianCalendar.MINUTE) != 0) {
+                                allDayEvent = 0;
+                                userLog("Not an all-day event locally: " + mLocalTimeZone.getID());
+                            }
+                        }
+                        cv.put(Events.ALL_DAY, allDayEvent);
+                        break;
+                    case Tags.CALENDAR_ATTACHMENTS:
+                        attachmentsParser();
+                        break;
+                    case Tags.CALENDAR_ATTENDEES:
+                        // If eventId >= 0, this is an update; otherwise, a new Event
+                        attendeeValues = attendeesParser(ops, eventId);
+                        break;
+                    case Tags.BASE_BODY:
+                        cv.put(Events.DESCRIPTION, bodyParser());
+                        break;
+                    case Tags.CALENDAR_BODY:
+                        cv.put(Events.DESCRIPTION, getValue());
+                        break;
+                    case Tags.CALENDAR_TIME_ZONE:
+                        timeZone = CalendarUtilities.tziStringToTimeZone(getValue());
+                        if (timeZone == null) {
+                            timeZone = mLocalTimeZone;
+                        }
+                        cv.put(Events.EVENT_TIMEZONE, timeZone.getID());
+                        break;
+                    case Tags.CALENDAR_START_TIME:
+                        startTime = Utility.parseDateTimeToMillis(getValue());
+                        break;
+                    case Tags.CALENDAR_END_TIME:
+                        endTime = Utility.parseDateTimeToMillis(getValue());
+                        break;
+                    case Tags.CALENDAR_EXCEPTIONS:
+                        // For exceptions to show the organizer, the organizer must be added before
+                        // we call exceptionsParser
+                        addOrganizerToAttendees(ops, eventId, organizerName, organizerEmail);
+                        organizerAdded = true;
+                        exceptionsParser(ops, cv, attendeeValues, reminderMins, busyStatus,
+                                startTime, endTime);
+                        break;
+                    case Tags.CALENDAR_LOCATION:
+                        cv.put(Events.EVENT_LOCATION, getValue());
+                        break;
+                    case Tags.CALENDAR_RECURRENCE:
+                        String rrule = recurrenceParser();
+                        if (rrule != null) {
+                            cv.put(Events.RRULE, rrule);
+                        }
+                        break;
+                    case Tags.CALENDAR_ORGANIZER_EMAIL:
+                        organizerEmail = getValue();
+                        cv.put(Events.ORGANIZER, organizerEmail);
+                        break;
+                    case Tags.CALENDAR_SUBJECT:
+                        cv.put(Events.TITLE, getValue());
+                        break;
+                    case Tags.CALENDAR_SENSITIVITY:
+                        cv.put(Events.ACCESS_LEVEL, encodeVisibility(getValueInt()));
+                        break;
+                    case Tags.CALENDAR_ORGANIZER_NAME:
+                        organizerName = getValue();
+                        break;
+                    case Tags.CALENDAR_REMINDER_MINS_BEFORE:
+                        // Save away whether this tag has content; Exchange 2010 sends an empty tag
+                        // rather than not sending one (as with Ex07 and Ex03)
+                        boolean hasContent = !noContent;
+                        reminderMins = getValueInt();
+                        if (hasContent) {
+                            ops.newReminder(reminderMins);
+                            cv.put(Events.HAS_ALARM, 1);
+                        }
+                        break;
+                    // The following are fields we should save (for changes), though they don't
+                    // relate to data used by CalendarProvider at this point
+                    case Tags.CALENDAR_UID:
+                        cv.put(Events.SYNC_DATA2, getValue());
+                        break;
+                    case Tags.CALENDAR_DTSTAMP:
+                        dtStamp = getValue();
+                        break;
+                    case Tags.CALENDAR_MEETING_STATUS:
+                        ops.newExtendedProperty(EXTENDED_PROPERTY_MEETING_STATUS, getValue());
+                        break;
+                    case Tags.CALENDAR_BUSY_STATUS:
+                        // We'll set the user's status in the Attendees table below
+                        // Don't set selfAttendeeStatus or CalendarProvider will create a duplicate
+                        // attendee!
+                        busyStatus = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RESPONSE_TYPE:
+                        // EAS 14+ uses this for the user's response status; we'll use this instead
+                        // of busy status, if it appears
+                        responseType = getValueInt();
+                        break;
+                    case Tags.CALENDAR_CATEGORIES:
+                        String categories = categoriesParser(ops);
+                        if (categories.length() > 0) {
+                            ops.newExtendedProperty(EXTENDED_PROPERTY_CATEGORIES, categories);
+                        }
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+
+            // Enforce CalendarProvider required properties
+            setTimeRelatedValues(cv, startTime, endTime, allDayEvent);
+
+            // If we haven't added the organizer to attendees, do it now
+            if (!organizerAdded) {
+                addOrganizerToAttendees(ops, eventId, organizerName, organizerEmail);
+            }
+
+            // Note that organizerEmail can be null with a DTSTAMP only change from the server
+            boolean selfOrganizer = (mEmailAddress.equals(organizerEmail));
+
+            // Store email addresses of attendees (in a tokenizable string) in ExtendedProperties
+            // If the user is an attendee, set the attendee status using busyStatus (note that the
+            // busyStatus is inherited from the parent unless it's specified in the exception)
+            // Add the insert/update operation for each attendee (based on whether it's add/change)
+            int numAttendees = attendeeValues.size();
+            if (numAttendees > MAX_SYNCED_ATTENDEES) {
+                // Indicate that we've redacted attendees.  If we're the organizer, disable edit
+                // by setting organizerEmail to a bogus value and by setting the upsync prohibited
+                // extended properly.
+                // Note that we don't set ANY attendees if we're in this branch; however, the
+                // organizer has already been included above, and WILL show up (which is good)
+                if (eventId < 0) {
+                    ops.newExtendedProperty(EXTENDED_PROPERTY_ATTENDEES_REDACTED, "1");
+                    if (selfOrganizer) {
+                        ops.newExtendedProperty(EXTENDED_PROPERTY_UPSYNC_PROHIBITED, "1");
+                    }
+                } else {
+                    ops.updatedExtendedProperty(EXTENDED_PROPERTY_ATTENDEES_REDACTED, "1", eventId);
+                    if (selfOrganizer) {
+                        ops.updatedExtendedProperty(EXTENDED_PROPERTY_UPSYNC_PROHIBITED, "1",
+                                eventId);
+                    }
+                }
+                if (selfOrganizer) {
+                    organizerEmail = BOGUS_ORGANIZER_EMAIL;
+                    cv.put(Events.ORGANIZER, organizerEmail);
+                }
+                // Tell UI that we don't have any attendees
+                cv.put(Events.HAS_ATTENDEE_DATA, "0");
+                mService.userLog("Maximum number of attendees exceeded; redacting");
+            } else if (numAttendees > 0) {
+                StringBuilder sb = new StringBuilder();
+                for (ContentValues attendee: attendeeValues) {
+                    String attendeeEmail = attendee.getAsString(Attendees.ATTENDEE_EMAIL);
+                    sb.append(attendeeEmail);
+                    sb.append(ATTENDEE_TOKENIZER_DELIMITER);
+                    if (mEmailAddress.equalsIgnoreCase(attendeeEmail)) {
+                        int attendeeStatus;
+                        // We'll use the response type (EAS 14), if we've got one; otherwise, we'll
+                        // try to infer it from busy status
+                        if (responseType != CalendarUtilities.RESPONSE_TYPE_NONE) {
+                            attendeeStatus =
+                                CalendarUtilities.attendeeStatusFromResponseType(responseType);
+                        } else if (!update) {
+                            // For new events in EAS < 14, we have no idea what the busy status
+                            // means, so we show "none", allowing the user to select an option.
+                            attendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
+                        } else {
+                            // For updated events, we'll try to infer the attendee status from the
+                            // busy status
+                            attendeeStatus =
+                                CalendarUtilities.attendeeStatusFromBusyStatus(busyStatus);
+                        }
+                        attendee.put(Attendees.ATTENDEE_STATUS, attendeeStatus);
+                        // If we're an attendee, save away our initial attendee status in the
+                        // event's ExtendedProperties (we look for differences between this and
+                        // the user's current attendee status to determine whether an email needs
+                        // to be sent to the organizer)
+                        // organizerEmail will be null in the case that this is an attendees-only
+                        // change from the server
+                        if (organizerEmail == null ||
+                                !organizerEmail.equalsIgnoreCase(attendeeEmail)) {
+                            if (eventId < 0) {
+                                ops.newExtendedProperty(EXTENDED_PROPERTY_USER_ATTENDEE_STATUS,
+                                        Integer.toString(attendeeStatus));
+                            } else {
+                                ops.updatedExtendedProperty(EXTENDED_PROPERTY_USER_ATTENDEE_STATUS,
+                                        Integer.toString(attendeeStatus), eventId);
+
+                            }
+                        }
+                    }
+                    if (eventId < 0) {
+                        ops.newAttendee(attendee);
+                    } else {
+                        ops.updatedAttendee(attendee, eventId);
+                    }
+                }
+                if (eventId < 0) {
+                    ops.newExtendedProperty(EXTENDED_PROPERTY_ATTENDEES, sb.toString());
+                    ops.newExtendedProperty(EXTENDED_PROPERTY_ATTENDEES_REDACTED, "0");
+                    ops.newExtendedProperty(EXTENDED_PROPERTY_UPSYNC_PROHIBITED, "0");
+                } else {
+                    ops.updatedExtendedProperty(EXTENDED_PROPERTY_ATTENDEES, sb.toString(),
+                            eventId);
+                    ops.updatedExtendedProperty(EXTENDED_PROPERTY_ATTENDEES_REDACTED, "0", eventId);
+                    ops.updatedExtendedProperty(EXTENDED_PROPERTY_UPSYNC_PROHIBITED, "0", eventId);
+                }
+            }
+
+            // Put the real event in the proper place in the ops ArrayList
+            if (eventOffset >= 0) {
+                // Store away the DTSTAMP here
+                if (dtStamp != null) {
+                    ops.newExtendedProperty(EXTENDED_PROPERTY_DTSTAMP, dtStamp);
+                }
+
+                if (isValidEventValues(cv)) {
+                    ops.set(eventOffset,
+                            new Operation(ContentProviderOperation
+                                    .newInsert(mAsSyncAdapterEvents).withValues(cv)));
+                } else {
+                    // If we can't add this event (it's invalid), remove all of the inserts
+                    // we've built for it
+                    int cnt = ops.mCount - eventOffset;
+                    userLog(TAG, "Removing " + cnt + " inserts from mOps");
+                    for (int i = 0; i < cnt; i++) {
+                        ops.remove(eventOffset);
+                    }
+                    ops.mCount = eventOffset;
+                    // If this is a change, we need to also remove the deletion that comes
+                    // before the addition
+                    if (deleteOffset >= 0) {
+                        // Remove the deletion
+                        ops.remove(deleteOffset);
+                        // And the deletion of exceptions
+                        ops.remove(deleteOffset);
+                        userLog(TAG, "Removing deletion ops from mOps");
+                        ops.mCount = deleteOffset;
+                    }
+                }
+            }
+            // Mark the end of the event
+            addSeparatorOperation(ops, Events.CONTENT_URI);
+        }
+
+        private void logEventColumns(ContentValues cv, String reason) {
+            if (Eas.USER_LOG) {
+                StringBuilder sb =
+                    new StringBuilder("Event invalid, " + reason + ", skipping: Columns = ");
+                for (Entry<String, Object> entry: cv.valueSet()) {
+                    sb.append(entry.getKey());
+                    sb.append('/');
+                }
+                userLog(TAG, sb.toString());
+            }
+        }
+
+        /*package*/ boolean isValidEventValues(ContentValues cv) {
+            boolean isException = cv.containsKey(Events.ORIGINAL_INSTANCE_TIME);
+            // All events require DTSTART
+            if (!cv.containsKey(Events.DTSTART)) {
+                logEventColumns(cv, "DTSTART missing");
+                return false;
+            // If we're a top-level event, we must have _SYNC_DATA (uid)
+            } else if (!isException && !cv.containsKey(Events.SYNC_DATA2)) {
+                logEventColumns(cv, "_SYNC_DATA missing");
+                return false;
+            // We must also have DTEND or DURATION if we're not an exception
+            } else if (!isException && !cv.containsKey(Events.DTEND) &&
+                    !cv.containsKey(Events.DURATION)) {
+                logEventColumns(cv, "DTEND/DURATION missing");
+                return false;
+            // Exceptions require DTEND
+            } else if (isException && !cv.containsKey(Events.DTEND)) {
+                logEventColumns(cv, "Exception missing DTEND");
+                return false;
+            // If this is a recurrence, we need a DURATION (in days if an all-day event)
+            } else if (cv.containsKey(Events.RRULE)) {
+                String duration = cv.getAsString(Events.DURATION);
+                if (duration == null) return false;
+                if (cv.containsKey(Events.ALL_DAY)) {
+                    Integer ade = cv.getAsInteger(Events.ALL_DAY);
+                    if (ade != null && ade != 0 && !duration.endsWith("D")) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        public String recurrenceParser() throws IOException {
+            // Turn this information into an RRULE
+            int type = -1;
+            int occurrences = -1;
+            int interval = -1;
+            int dow = -1;
+            int dom = -1;
+            int wom = -1;
+            int moy = -1;
+            String until = null;
+
+            while (nextTag(Tags.CALENDAR_RECURRENCE) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_RECURRENCE_TYPE:
+                        type = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_INTERVAL:
+                        interval = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_OCCURRENCES:
+                        occurrences = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_DAYOFWEEK:
+                        dow = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_DAYOFMONTH:
+                        dom = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_WEEKOFMONTH:
+                        wom = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_MONTHOFYEAR:
+                        moy = getValueInt();
+                        break;
+                    case Tags.CALENDAR_RECURRENCE_UNTIL:
+                        until = getValue();
+                        break;
+                    default:
+                       skipTag();
+                }
+            }
+
+            return CalendarUtilities.rruleFromRecurrence(type, occurrences, interval,
+                    dow, dom, wom, moy, until);
+        }
+
+        private void exceptionParser(CalendarOperations ops, ContentValues parentCv,
+                ArrayList<ContentValues> attendeeValues, int reminderMins, int busyStatus,
+                long startTime, long endTime) throws IOException {
+            ContentValues cv = new ContentValues();
+            cv.put(Events.CALENDAR_ID, mCalendarId);
+
+            // It appears that these values have to be copied from the parent if they are to appear
+            // Note that they can be overridden below
+            cv.put(Events.ORGANIZER, parentCv.getAsString(Events.ORGANIZER));
+            cv.put(Events.TITLE, parentCv.getAsString(Events.TITLE));
+            cv.put(Events.DESCRIPTION, parentCv.getAsString(Events.DESCRIPTION));
+            cv.put(Events.ORIGINAL_ALL_DAY, parentCv.getAsInteger(Events.ALL_DAY));
+            cv.put(Events.EVENT_LOCATION, parentCv.getAsString(Events.EVENT_LOCATION));
+            cv.put(Events.ACCESS_LEVEL, parentCv.getAsString(Events.ACCESS_LEVEL));
+            cv.put(Events.EVENT_TIMEZONE, parentCv.getAsString(Events.EVENT_TIMEZONE));
+            // Exceptions should always have this set to zero, since EAS has no concept of
+            // separate attendee lists for exceptions; if we fail to do this, then the UI will
+            // allow the user to change attendee data, and this change would never get reflected
+            // on the server.
+            cv.put(Events.HAS_ATTENDEE_DATA, 0);
+
+            int allDayEvent = 0;
+
+            // This column is the key that links the exception to the serverId
+            cv.put(Events.ORIGINAL_SYNC_ID, parentCv.getAsString(Events._SYNC_ID));
+
+            String exceptionStartTime = "_noStartTime";
+            while (nextTag(Tags.SYNC_APPLICATION_DATA) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_ATTACHMENTS:
+                        attachmentsParser();
+                        break;
+                    case Tags.CALENDAR_EXCEPTION_START_TIME:
+                        exceptionStartTime = getValue();
+                        cv.put(Events.ORIGINAL_INSTANCE_TIME,
+                                Utility.parseDateTimeToMillis(exceptionStartTime));
+                        break;
+                    case Tags.CALENDAR_EXCEPTION_IS_DELETED:
+                        if (getValueInt() == 1) {
+                            cv.put(Events.STATUS, Events.STATUS_CANCELED);
+                        }
+                        break;
+                    case Tags.CALENDAR_ALL_DAY_EVENT:
+                        allDayEvent = getValueInt();
+                        cv.put(Events.ALL_DAY, allDayEvent);
+                        break;
+                    case Tags.BASE_BODY:
+                        cv.put(Events.DESCRIPTION, bodyParser());
+                        break;
+                    case Tags.CALENDAR_BODY:
+                        cv.put(Events.DESCRIPTION, getValue());
+                        break;
+                    case Tags.CALENDAR_START_TIME:
+                        startTime = Utility.parseDateTimeToMillis(getValue());
+                        break;
+                    case Tags.CALENDAR_END_TIME:
+                        endTime = Utility.parseDateTimeToMillis(getValue());
+                        break;
+                    case Tags.CALENDAR_LOCATION:
+                        cv.put(Events.EVENT_LOCATION, getValue());
+                        break;
+                    case Tags.CALENDAR_RECURRENCE:
+                        String rrule = recurrenceParser();
+                        if (rrule != null) {
+                            cv.put(Events.RRULE, rrule);
+                        }
+                        break;
+                    case Tags.CALENDAR_SUBJECT:
+                        cv.put(Events.TITLE, getValue());
+                        break;
+                    case Tags.CALENDAR_SENSITIVITY:
+                        cv.put(Events.ACCESS_LEVEL, encodeVisibility(getValueInt()));
+                        break;
+                    case Tags.CALENDAR_BUSY_STATUS:
+                        busyStatus = getValueInt();
+                        // Don't set selfAttendeeStatus or CalendarProvider will create a duplicate
+                        // attendee!
+                        break;
+                        // TODO How to handle these items that are linked to event id!
+//                    case Tags.CALENDAR_DTSTAMP:
+//                        ops.newExtendedProperty("dtstamp", getValue());
+//                        break;
+//                    case Tags.CALENDAR_REMINDER_MINS_BEFORE:
+//                        ops.newReminder(getValueInt());
+//                        break;
+                    default:
+                        skipTag();
+                }
+            }
+
+            // We need a _sync_id, but it can't be the parent's id, so we generate one
+            cv.put(Events._SYNC_ID, parentCv.getAsString(Events._SYNC_ID) + '_' +
+                    exceptionStartTime);
+
+            // Enforce CalendarProvider required properties
+            setTimeRelatedValues(cv, startTime, endTime, allDayEvent);
+
+            // Don't insert an invalid exception event
+            if (!isValidEventValues(cv)) return;
+
+            // Add the exception insert
+            int exceptionStart = ops.mCount;
+            ops.newException(cv);
+            // Also add the attendees, because they need to be copied over from the parent event
+            boolean attendeesRedacted = false;
+            if (attendeeValues != null) {
+                for (ContentValues attValues: attendeeValues) {
+                    // If this is the user, use his busy status for attendee status
+                    String attendeeEmail = attValues.getAsString(Attendees.ATTENDEE_EMAIL);
+                    // Note that the exception at which we surpass the redaction limit might have
+                    // any number of attendees shown; since this is an edge case and a workaround,
+                    // it seems to be an acceptable implementation
+                    if (mEmailAddress.equalsIgnoreCase(attendeeEmail)) {
+                        attValues.put(Attendees.ATTENDEE_STATUS,
+                                CalendarUtilities.attendeeStatusFromBusyStatus(busyStatus));
+                        ops.newAttendee(attValues, exceptionStart);
+                    } else if (ops.size() < MAX_OPS_BEFORE_EXCEPTION_ATTENDEE_REDACTION) {
+                        ops.newAttendee(attValues, exceptionStart);
+                    } else {
+                        attendeesRedacted = true;
+                    }
+                }
+            }
+            // And add the parent's reminder value
+            if (reminderMins > 0) {
+                ops.newReminder(reminderMins, exceptionStart);
+            }
+            if (attendeesRedacted) {
+                mService.userLog("Attendees redacted in this exception");
+            }
+        }
+
+        private int encodeVisibility(int easVisibility) {
+            int visibility = 0;
+            switch(easVisibility) {
+                case 0:
+                    visibility = Events.ACCESS_DEFAULT;
+                    break;
+                case 1:
+                    visibility = Events.ACCESS_PUBLIC;
+                    break;
+                case 2:
+                    visibility = Events.ACCESS_PRIVATE;
+                    break;
+                case 3:
+                    visibility = Events.ACCESS_CONFIDENTIAL;
+                    break;
+            }
+            return visibility;
+        }
+
+        private void exceptionsParser(CalendarOperations ops, ContentValues cv,
+                ArrayList<ContentValues> attendeeValues, int reminderMins, int busyStatus,
+                long startTime, long endTime) throws IOException {
+            while (nextTag(Tags.CALENDAR_EXCEPTIONS) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_EXCEPTION:
+                        exceptionParser(ops, cv, attendeeValues, reminderMins, busyStatus,
+                                startTime, endTime);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        private String categoriesParser(CalendarOperations ops) throws IOException {
+            StringBuilder categories = new StringBuilder();
+            while (nextTag(Tags.CALENDAR_CATEGORIES) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_CATEGORY:
+                        // TODO Handle categories (there's no similar concept for gdata AFAIK)
+                        // We need to save them and spit them back when we update the event
+                        categories.append(getValue());
+                        categories.append(CATEGORY_TOKENIZER_DELIMITER);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+            return categories.toString();
+        }
+
+        /**
+         * For now, we ignore (but still have to parse) event attachments; these are new in EAS 14
+         */
+        private void attachmentsParser() throws IOException {
+            while (nextTag(Tags.CALENDAR_ATTACHMENTS) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_ATTACHMENT:
+                        skipParser(Tags.CALENDAR_ATTACHMENT);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        private ArrayList<ContentValues> attendeesParser(CalendarOperations ops, long eventId)
+                throws IOException {
+            int attendeeCount = 0;
+            ArrayList<ContentValues> attendeeValues = new ArrayList<ContentValues>();
+            while (nextTag(Tags.CALENDAR_ATTENDEES) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_ATTENDEE:
+                        ContentValues cv = attendeeParser(ops, eventId);
+                        // If we're going to redact these attendees anyway, let's avoid unnecessary
+                        // memory pressure, and not keep them around
+                        // We still need to parse them all, however
+                        attendeeCount++;
+                        // Allow one more than MAX_ATTENDEES, so that the check for "too many" will
+                        // succeed in addEvent
+                        if (attendeeCount <= (MAX_SYNCED_ATTENDEES+1)) {
+                            attendeeValues.add(cv);
+                        }
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+            return attendeeValues;
+        }
+
+        private ContentValues attendeeParser(CalendarOperations ops, long eventId)
+                throws IOException {
+            ContentValues cv = new ContentValues();
+            while (nextTag(Tags.CALENDAR_ATTENDEE) != END) {
+                switch (tag) {
+                    case Tags.CALENDAR_ATTENDEE_EMAIL:
+                        cv.put(Attendees.ATTENDEE_EMAIL, getValue());
+                        break;
+                    case Tags.CALENDAR_ATTENDEE_NAME:
+                        cv.put(Attendees.ATTENDEE_NAME, getValue());
+                        break;
+                    case Tags.CALENDAR_ATTENDEE_STATUS:
+                        int status = getValueInt();
+                        cv.put(Attendees.ATTENDEE_STATUS,
+                                (status == 2) ? Attendees.ATTENDEE_STATUS_TENTATIVE :
+                                (status == 3) ? Attendees.ATTENDEE_STATUS_ACCEPTED :
+                                (status == 4) ? Attendees.ATTENDEE_STATUS_DECLINED :
+                                (status == 5) ? Attendees.ATTENDEE_STATUS_INVITED :
+                                    Attendees.ATTENDEE_STATUS_NONE);
+                        break;
+                    case Tags.CALENDAR_ATTENDEE_TYPE:
+                        int type = Attendees.TYPE_NONE;
+                        // EAS types: 1 = req'd, 2 = opt, 3 = resource
+                        switch (getValueInt()) {
+                            case 1:
+                                type = Attendees.TYPE_REQUIRED;
+                                break;
+                            case 2:
+                                type = Attendees.TYPE_OPTIONAL;
+                                break;
+                        }
+                        cv.put(Attendees.ATTENDEE_TYPE, type);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+            cv.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
+            return cv;
+        }
+
+        private String bodyParser() throws IOException {
+            String body = null;
+            while (nextTag(Tags.BASE_BODY) != END) {
+                switch (tag) {
+                    case Tags.BASE_DATA:
+                        body = getValue();
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+
+            // Handle null data without error
+            if (body == null) return "";
+            // Remove \r's from any body text
+            return body.replace("\r\n", "\n");
+        }
+
+        public void addParser(CalendarOperations ops) throws IOException {
+            String serverId = null;
+            while (nextTag(Tags.SYNC_ADD) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID: // same as
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_APPLICATION_DATA:
+                        addEvent(ops, serverId, false);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        private Cursor getServerIdCursor(String serverId) {
+            return mContentResolver.query(mAccountUri, ID_PROJECTION, SERVER_ID_AND_CALENDAR_ID,
+                    new String[] {serverId, mCalendarIdString}, null);
+        }
+
+        private Cursor getClientIdCursor(String clientId) {
+            mBindArgument[0] = clientId;
+            return mContentResolver.query(mAccountUri, ID_PROJECTION, CLIENT_ID_SELECTION,
+                    mBindArgument, null);
+        }
+
+        public void deleteParser(CalendarOperations ops) throws IOException {
+            while (nextTag(Tags.SYNC_DELETE) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        String serverId = getValue();
+                        // Find the event with the given serverId
+                        Cursor c = getServerIdCursor(serverId);
+                        try {
+                            if (c.moveToFirst()) {
+                                userLog("Deleting ", serverId);
+                                ops.delete(c.getLong(0), serverId);
+                            }
+                        } finally {
+                            c.close();
+                        }
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        /**
+         * A change is handled as a delete (including all exceptions) and an add
+         * This isn't as efficient as attempting to traverse the original and all of its exceptions,
+         * but changes happen infrequently and this code is both simpler and easier to maintain
+         * @param ops the array of pending ContactProviderOperations.
+         * @throws IOException
+         */
+        public void changeParser(CalendarOperations ops) throws IOException {
+            String serverId = null;
+            while (nextTag(Tags.SYNC_CHANGE) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_APPLICATION_DATA:
+                        userLog("Changing " + serverId);
+                        addEvent(ops, serverId, true);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        @Override
+        public void commandsParser() throws IOException {
+            while (nextTag(Tags.SYNC_COMMANDS) != END) {
+                if (tag == Tags.SYNC_ADD) {
+                    addParser(mOps);
+                    incrementChangeCount();
+                } else if (tag == Tags.SYNC_DELETE) {
+                    deleteParser(mOps);
+                    incrementChangeCount();
+                } else if (tag == Tags.SYNC_CHANGE) {
+                    changeParser(mOps);
+                    incrementChangeCount();
+                } else
+                    skipTag();
+            }
+        }
+
+        @Override
+        public void commit() throws IOException {
+            userLog("Calendar SyncKey saved as: ", mMailbox.mSyncKey);
+            // Save the syncKey here, using the Helper provider by Calendar provider
+            mOps.add(new Operation(SyncStateContract.Helpers.newSetOperation(
+                    asSyncAdapter(SyncState.CONTENT_URI, mEmailAddress,
+                            Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                    mAccountManagerAccount,
+                    mMailbox.mSyncKey.getBytes())));
+
+            // We need to send cancellations now, because the Event won't exist after the commit
+            for (long eventId: mSendCancelIdList) {
+                EmailContent.Message msg;
+                try {
+                    msg = CalendarUtilities.createMessageForEventId(mContext, eventId,
+                            EmailContent.Message.FLAG_OUTGOING_MEETING_CANCEL, null,
+                            mAccount);
+                } catch (RemoteException e) {
+                    // Nothing to do here; the Event may no longer exist
+                    continue;
+                }
+                if (msg != null) {
+                    EasOutboxService.sendMessage(mContext, mAccount.mId, msg);
+                }
+            }
+
+            // Execute our CPO's safely
+            try {
+                mOps.mResults = safeExecute(CalendarContract.AUTHORITY, mOps);
+            } catch (RemoteException e) {
+                throw new IOException("Remote exception caught; will retry");
+            }
+
+            if (mOps.mResults != null) {
+                // Clear dirty and mark flags for updates sent to server
+                if (!mUploadedIdList.isEmpty())  {
+                    ContentValues cv = new ContentValues();
+                    cv.put(Events.DIRTY, 0);
+                    cv.put(EVENT_SYNC_MARK, "0");
+                    for (long eventId : mUploadedIdList) {
+                        mContentResolver.update(
+                                asSyncAdapter(
+                                        ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
+                                        mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), cv,
+                                null, null);
+                    }
+                }
+                // Delete events marked for deletion
+                if (!mDeletedIdList.isEmpty()) {
+                    for (long eventId : mDeletedIdList) {
+                        mContentResolver.delete(
+                                asSyncAdapter(
+                                        ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
+                                        mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), null,
+                                null);
+                    }
+                }
+                // Send any queued up email (invitations replies, etc.)
+                for (Message msg: mOutgoingMailList) {
+                    EasOutboxService.sendMessage(mContext, mAccount.mId, msg);
+                }
+            }
+        }
+
+        public void addResponsesParser() throws IOException {
+            String serverId = null;
+            String clientId = null;
+            int status = -1;
+            ContentValues cv = new ContentValues();
+            while (nextTag(Tags.SYNC_ADD) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_CLIENT_ID:
+                        clientId = getValue();
+                        break;
+                    case Tags.SYNC_STATUS:
+                        status = getValueInt();
+                        if (status != 1) {
+                            userLog("Attempt to add event failed with status: " + status);
+                        }
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+
+            if (clientId == null) return;
+            if (serverId == null) {
+                // TODO Reconsider how to handle this
+                serverId = "FAIL:" + status;
+            }
+
+            Cursor c = getClientIdCursor(clientId);
+            try {
+                if (c.moveToFirst()) {
+                    cv.put(Events._SYNC_ID, serverId);
+                    cv.put(Events.SYNC_DATA2, clientId);
+                    long id = c.getLong(0);
+                    // Write the serverId into the Event
+                    mOps.add(new Operation(ContentProviderOperation
+                            .newUpdate(ContentUris.withAppendedId(mAsSyncAdapterEvents, id))
+                            .withValues(cv)));
+                    userLog("New event " + clientId + " was given serverId: " + serverId);
+                }
+            } finally {
+                c.close();
+            }
+        }
+
+        public void changeResponsesParser() throws IOException {
+            String serverId = null;
+            String status = null;
+            while (nextTag(Tags.SYNC_CHANGE) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_STATUS:
+                        status = getValue();
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+            if (serverId != null && status != null) {
+                userLog("Changed event " + serverId + " failed with status: " + status);
+            }
+        }
+
+
+        @Override
+        public void responsesParser() throws IOException {
+            // Handle server responses here (for Add and Change)
+            while (nextTag(Tags.SYNC_RESPONSES) != END) {
+                if (tag == Tags.SYNC_ADD) {
+                    addResponsesParser();
+                } else if (tag == Tags.SYNC_CHANGE) {
+                    changeResponsesParser();
+                } else
+                    skipTag();
+            }
+        }
+    }
+
+    protected class CalendarOperations extends ArrayList<Operation> {
+        private static final long serialVersionUID = 1L;
+        public int mCount = 0;
+        private ContentProviderResult[] mResults = null;
+        private int mEventStart = 0;
+
+        @Override
+        public boolean add(Operation op) {
+            super.add(op);
+            mCount++;
+            return true;
+        }
+
+        public int newEvent(Operation op) {
+            mEventStart = mCount;
+            add(op);
+            return mEventStart;
+        }
+
+        public int newDelete(long id, String serverId) {
+            int offset = mCount;
+            delete(id, serverId);
+            return offset;
+        }
+
+        public void newAttendee(ContentValues cv) {
+            newAttendee(cv, mEventStart);
+        }
+
+        public void newAttendee(ContentValues cv, int eventStart) {
+            add(new Operation(ContentProviderOperation.newInsert(mAsSyncAdapterAttendees)
+                    .withValues(cv),
+                    Attendees.EVENT_ID,
+                    eventStart));
+        }
+
+        public void updatedAttendee(ContentValues cv, long id) {
+            cv.put(Attendees.EVENT_ID, id);
+            add(new Operation(ContentProviderOperation.newInsert(mAsSyncAdapterAttendees)
+                    .withValues(cv)));
+        }
+
+        public void newException(ContentValues cv) {
+            add(new Operation(ContentProviderOperation.newInsert(mAsSyncAdapterEvents)
+                    .withValues(cv)));
+        }
+
+        public void newExtendedProperty(String name, String value) {
+            add(new Operation(ContentProviderOperation.newInsert(mAsSyncAdapterExtendedProperties)
+                    .withValue(ExtendedProperties.NAME, name)
+                    .withValue(ExtendedProperties.VALUE, value),
+                    ExtendedProperties.EVENT_ID,
+                    mEventStart));
+        }
+
+        public void updatedExtendedProperty(String name, String value, long id) {
+            // Find an existing ExtendedProperties row for this event and property name
+            Cursor c = mService.mContentResolver.query(ExtendedProperties.CONTENT_URI,
+                    EXTENDED_PROPERTY_PROJECTION, EVENT_ID_AND_NAME,
+                    new String[] {Long.toString(id), name}, null);
+            long extendedPropertyId = -1;
+            // If there is one, capture its _id
+            if (c != null) {
+                try {
+                    if (c.moveToFirst()) {
+                        extendedPropertyId = c.getLong(EXTENDED_PROPERTY_ID);
+                    }
+                } finally {
+                    c.close();
+                }
+            }
+            // Either do an update or an insert, depending on whether one
+            // already exists
+            if (extendedPropertyId >= 0) {
+                add(new Operation(ContentProviderOperation
+                        .newUpdate(
+                                ContentUris.withAppendedId(mAsSyncAdapterExtendedProperties,
+                                        extendedPropertyId))
+                        .withValue(ExtendedProperties.VALUE, value)));
+            } else {
+                newExtendedProperty(name, value);
+            }
+        }
+
+        public void newReminder(int mins, int eventStart) {
+            add(new Operation(ContentProviderOperation.newInsert(mAsSyncAdapterReminders)
+                    .withValue(Reminders.MINUTES, mins)
+                    .withValue(Reminders.METHOD, Reminders.METHOD_ALERT),
+                    ExtendedProperties.EVENT_ID,
+                    eventStart));
+        }
+
+        public void newReminder(int mins) {
+            newReminder(mins, mEventStart);
+        }
+
+        public void delete(long id, String syncId) {
+            add(new Operation(ContentProviderOperation.newDelete(
+                    ContentUris.withAppendedId(mAsSyncAdapterEvents, id))));
+            // Delete the exceptions for this Event (CalendarProvider doesn't do this)
+            add(new Operation(ContentProviderOperation
+                    .newDelete(mAsSyncAdapterEvents)
+                    .withSelection(Events.ORIGINAL_SYNC_ID + "=?", new String[] {syncId})));
+        }
+    }
+
+    private String decodeVisibility(int visibility) {
+        int easVisibility = 0;
+        switch(visibility) {
+            case Events.ACCESS_DEFAULT:
+                easVisibility = 0;
+                break;
+            case Events.ACCESS_PUBLIC:
+                easVisibility = 1;
+                break;
+            case Events.ACCESS_PRIVATE:
+                easVisibility = 2;
+                break;
+            case Events.ACCESS_CONFIDENTIAL:
+                easVisibility = 3;
+                break;
+        }
+        return Integer.toString(easVisibility);
+    }
+
+    private int getInt(ContentValues cv, String column) {
+        Integer i = cv.getAsInteger(column);
+        if (i == null) return 0;
+        return i;
+    }
+
+    private void sendEvent(Entity entity, String clientId, Serializer s)
+            throws IOException {
+        // Serialize for EAS here
+        // Set uid with the client id we created
+        // 1) Serialize the top-level event
+        // 2) Serialize attendees and reminders from subvalues
+        // 3) Look for exceptions and serialize with the top-level event
+        ContentValues entityValues = entity.getEntityValues();
+        final boolean isException = (clientId == null);
+        boolean hasAttendees = false;
+        final boolean isChange = entityValues.containsKey(Events._SYNC_ID);
+        final Double version = mService.mProtocolVersionDouble;
+        final boolean allDay =
+            CalendarUtilities.getIntegerValueAsBoolean(entityValues, Events.ALL_DAY);
+
+        // NOTE: Exchange 2003 (EAS 2.5) seems to require the "exception deleted" and "exception
+        // start time" data before other data in exceptions.  Failure to do so results in a
+        // status 6 error during sync
+        if (isException) {
+           // Send exception deleted flag if necessary
+            Integer deleted = entityValues.getAsInteger(Events.DELETED);
+            boolean isDeleted = deleted != null && deleted == 1;
+            Integer eventStatus = entityValues.getAsInteger(Events.STATUS);
+            boolean isCanceled = eventStatus != null && eventStatus.equals(Events.STATUS_CANCELED);
+            if (isDeleted || isCanceled) {
+                s.data(Tags.CALENDAR_EXCEPTION_IS_DELETED, "1");
+                // If we're deleted, the UI will continue to show this exception until we mark
+                // it canceled, so we'll do that here...
+                if (isDeleted && !isCanceled) {
+                    final long eventId = entityValues.getAsLong(Events._ID);
+                    ContentValues cv = new ContentValues();
+                    cv.put(Events.STATUS, Events.STATUS_CANCELED);
+                    mService.mContentResolver.update(
+                            asSyncAdapter(ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
+                                    mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), cv, null,
+                            null);
+                }
+            } else {
+                s.data(Tags.CALENDAR_EXCEPTION_IS_DELETED, "0");
+            }
+
+            // TODO Add reminders to exceptions (allow them to be specified!)
+            Long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
+            if (originalTime != null) {
+                final boolean originalAllDay =
+                    CalendarUtilities.getIntegerValueAsBoolean(entityValues,
+                            Events.ORIGINAL_ALL_DAY);
+                if (originalAllDay) {
+                    // For all day events, we need our local all-day time
+                    originalTime =
+                        CalendarUtilities.getLocalAllDayCalendarTime(originalTime, mLocalTimeZone);
+                }
+                s.data(Tags.CALENDAR_EXCEPTION_START_TIME,
+                        CalendarUtilities.millisToEasDateTime(originalTime));
+            } else {
+                // Illegal; what should we do?
+            }
+        }
+
+        // Get the event's time zone
+        String timeZoneName =
+            entityValues.getAsString(allDay ? EVENT_SAVED_TIMEZONE_COLUMN : Events.EVENT_TIMEZONE);
+        if (timeZoneName == null) {
+            timeZoneName = mLocalTimeZone.getID();
+        }
+        TimeZone eventTimeZone = TimeZone.getTimeZone(timeZoneName);
+
+        if (!isException) {
+            // A time zone is required in all EAS events; we'll use the default if none is set
+            // Exchange 2003 seems to require this first... :-)
+            String timeZone = CalendarUtilities.timeZoneToTziString(eventTimeZone);
+            s.data(Tags.CALENDAR_TIME_ZONE, timeZone);
+        }
+
+        s.data(Tags.CALENDAR_ALL_DAY_EVENT, allDay ? "1" : "0");
+
+        // DTSTART is always supplied
+        long startTime = entityValues.getAsLong(Events.DTSTART);
+        // Determine endTime; it's either provided as DTEND or we calculate using DURATION
+        // If no DURATION is provided, we default to one hour
+        long endTime;
+        if (entityValues.containsKey(Events.DTEND)) {
+            endTime = entityValues.getAsLong(Events.DTEND);
+        } else {
+            long durationMillis = HOURS;
+            if (entityValues.containsKey(Events.DURATION)) {
+                Duration duration = new Duration();
+                try {
+                    duration.parse(entityValues.getAsString(Events.DURATION));
+                    durationMillis = duration.getMillis();
+                } catch (DateException e) {
+                    // Can't do much about this; use the default (1 hour)
+                }
+            }
+            endTime = startTime + durationMillis;
+        }
+        if (allDay) {
+            TimeZone tz = mLocalTimeZone;
+            startTime = CalendarUtilities.getLocalAllDayCalendarTime(startTime, tz);
+            endTime = CalendarUtilities.getLocalAllDayCalendarTime(endTime, tz);
+        }
+        s.data(Tags.CALENDAR_START_TIME, CalendarUtilities.millisToEasDateTime(startTime));
+        s.data(Tags.CALENDAR_END_TIME, CalendarUtilities.millisToEasDateTime(endTime));
+
+        s.data(Tags.CALENDAR_DTSTAMP,
+                CalendarUtilities.millisToEasDateTime(System.currentTimeMillis()));
+
+        String loc = entityValues.getAsString(Events.EVENT_LOCATION);
+        if (!TextUtils.isEmpty(loc)) {
+            if (version < Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+                // EAS 2.5 doesn't like bare line feeds
+                loc = Utility.replaceBareLfWithCrlf(loc);
+            }
+            s.data(Tags.CALENDAR_LOCATION, loc);
+        }
+        s.writeStringValue(entityValues, Events.TITLE, Tags.CALENDAR_SUBJECT);
+
+        if (version >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+            s.start(Tags.BASE_BODY);
+            s.data(Tags.BASE_TYPE, "1");
+            s.writeStringValue(entityValues, Events.DESCRIPTION, Tags.BASE_DATA);
+            s.end();
+        } else {
+            // EAS 2.5 doesn't like bare line feeds
+            s.writeStringValue(entityValues, Events.DESCRIPTION, Tags.CALENDAR_BODY);
+        }
+
+        if (!isException) {
+            // For Exchange 2003, only upsync if the event is new
+            if ((version >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) || !isChange) {
+                s.writeStringValue(entityValues, Events.ORGANIZER, Tags.CALENDAR_ORGANIZER_EMAIL);
+            }
+
+            String rrule = entityValues.getAsString(Events.RRULE);
+            if (rrule != null) {
+                CalendarUtilities.recurrenceFromRrule(rrule, startTime, s);
+            }
+
+            // Handle associated data EXCEPT for attendees, which have to be grouped
+            ArrayList<NamedContentValues> subValues = entity.getSubValues();
+            // The earliest of the reminders for this Event; we can only send one reminder...
+            int earliestReminder = -1;
+            for (NamedContentValues ncv: subValues) {
+                Uri ncvUri = ncv.uri;
+                ContentValues ncvValues = ncv.values;
+                if (ncvUri.equals(ExtendedProperties.CONTENT_URI)) {
+                    String propertyName =
+                        ncvValues.getAsString(ExtendedProperties.NAME);
+                    String propertyValue =
+                        ncvValues.getAsString(ExtendedProperties.VALUE);
+                    if (TextUtils.isEmpty(propertyValue)) {
+                        continue;
+                    }
+                    if (propertyName.equals(EXTENDED_PROPERTY_CATEGORIES)) {
+                        // Send all the categories back to the server
+                        // We've saved them as a String of delimited tokens
+                        StringTokenizer st =
+                            new StringTokenizer(propertyValue, CATEGORY_TOKENIZER_DELIMITER);
+                        if (st.countTokens() > 0) {
+                            s.start(Tags.CALENDAR_CATEGORIES);
+                            while (st.hasMoreTokens()) {
+                                String category = st.nextToken();
+                                s.data(Tags.CALENDAR_CATEGORY, category);
+                            }
+                            s.end();
+                        }
+                    }
+                } else if (ncvUri.equals(Reminders.CONTENT_URI)) {
+                    Integer mins = ncvValues.getAsInteger(Reminders.MINUTES);
+                    if (mins != null) {
+                        // -1 means "default", which for Exchange, is 30
+                        if (mins < 0) {
+                            mins = 30;
+                        }
+                        // Save this away if it's the earliest reminder (greatest minutes)
+                        if (mins > earliestReminder) {
+                            earliestReminder = mins;
+                        }
+                    }
+                }
+            }
+
+            // If we have a reminder, send it to the server
+            if (earliestReminder >= 0) {
+                s.data(Tags.CALENDAR_REMINDER_MINS_BEFORE, Integer.toString(earliestReminder));
+            }
+
+            // We've got to send a UID, unless this is an exception.  If the event is new, we've
+            // generated one; if not, we should have gotten one from extended properties.
+            if (clientId != null) {
+                s.data(Tags.CALENDAR_UID, clientId);
+            }
+
+            // Handle attendee data here; keep track of organizer and stream it afterward
+            String organizerName = null;
+            String organizerEmail = null;
+            for (NamedContentValues ncv: subValues) {
+                Uri ncvUri = ncv.uri;
+                ContentValues ncvValues = ncv.values;
+                if (ncvUri.equals(Attendees.CONTENT_URI)) {
+                    Integer relationship = ncvValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
+                    // If there's no relationship, we can't create this for EAS
+                    // Similarly, we need an attendee email for each invitee
+                    if (relationship != null && ncvValues.containsKey(Attendees.ATTENDEE_EMAIL)) {
+                        // Organizer isn't among attendees in EAS
+                        if (relationship == Attendees.RELATIONSHIP_ORGANIZER) {
+                            organizerName = ncvValues.getAsString(Attendees.ATTENDEE_NAME);
+                            organizerEmail = ncvValues.getAsString(Attendees.ATTENDEE_EMAIL);
+                            continue;
+                        }
+                        if (!hasAttendees) {
+                            s.start(Tags.CALENDAR_ATTENDEES);
+                            hasAttendees = true;
+                        }
+                        s.start(Tags.CALENDAR_ATTENDEE);
+                        String attendeeEmail = ncvValues.getAsString(Attendees.ATTENDEE_EMAIL);
+                        String attendeeName = ncvValues.getAsString(Attendees.ATTENDEE_NAME);
+                        if (attendeeName == null) {
+                            attendeeName = attendeeEmail;
+                        }
+                        s.data(Tags.CALENDAR_ATTENDEE_NAME, attendeeName);
+                        s.data(Tags.CALENDAR_ATTENDEE_EMAIL, attendeeEmail);
+                        if (version >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+                            s.data(Tags.CALENDAR_ATTENDEE_TYPE, "1"); // Required
+                        }
+                        s.end(); // Attendee
+                     }
+                }
+            }
+            if (hasAttendees) {
+                s.end();  // Attendees
+            }
+
+            // Get busy status from Attendees table
+            long eventId = entityValues.getAsLong(Events._ID);
+            int busyStatus = CalendarUtilities.BUSY_STATUS_TENTATIVE;
+            Cursor c = mService.mContentResolver.query(
+                    asSyncAdapter(Attendees.CONTENT_URI, mEmailAddress,
+                            Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                    ATTENDEE_STATUS_PROJECTION, EVENT_AND_EMAIL,
+                    new String[] {Long.toString(eventId), mEmailAddress}, null);
+            if (c != null) {
+                try {
+                    if (c.moveToFirst()) {
+                        busyStatus = CalendarUtilities.busyStatusFromAttendeeStatus(
+                                c.getInt(ATTENDEE_STATUS_COLUMN_STATUS));
+                    }
+                } finally {
+                    c.close();
+                }
+            }
+            s.data(Tags.CALENDAR_BUSY_STATUS, Integer.toString(busyStatus));
+
+            // Meeting status, 0 = appointment, 1 = meeting, 3 = attendee
+            if (mEmailAddress.equalsIgnoreCase(organizerEmail)) {
+                s.data(Tags.CALENDAR_MEETING_STATUS, hasAttendees ? "1" : "0");
+            } else {
+                s.data(Tags.CALENDAR_MEETING_STATUS, "3");
+            }
+
+            // For Exchange 2003, only upsync if the event is new
+            if (((version >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) || !isChange) &&
+                    organizerName != null) {
+                s.data(Tags.CALENDAR_ORGANIZER_NAME, organizerName);
+            }
+
+            // NOTE: Sensitivity must NOT be sent to the server for exceptions in Exchange 2003
+            // The result will be a status 6 failure during sync
+            Integer visibility = entityValues.getAsInteger(Events.ACCESS_LEVEL);
+            if (visibility != null) {
+                s.data(Tags.CALENDAR_SENSITIVITY, decodeVisibility(visibility));
+            } else {
+                // Default to private if not set
+                s.data(Tags.CALENDAR_SENSITIVITY, "1");
+            }
+        }
+    }
+
+    /**
+     * Convenience method for sending an email to the organizer declining the meeting
+     * @param entity
+     * @param clientId
+     */
+    private void sendDeclinedEmail(Entity entity, String clientId) {
+        Message msg =
+            CalendarUtilities.createMessageForEntity(mContext, entity,
+                    Message.FLAG_OUTGOING_MEETING_DECLINE, clientId, mAccount);
+        if (msg != null) {
+            userLog("Queueing declined response to " + msg.mTo);
+            mOutgoingMailList.add(msg);
+        }
+    }
+
+    @Override
+    public boolean sendLocalChanges(Serializer s) throws IOException {
+        ContentResolver cr = mService.mContentResolver;
+
+        if (getSyncKey().equals("0")) {
+            return false;
+        }
+
+        try {
+            // We've got to handle exceptions as part of the parent when changes occur, so we need
+            // to find new/changed exceptions and mark the parent dirty
+            ArrayList<Long> orphanedExceptions = new ArrayList<Long>();
+            Cursor c = cr.query(Events.CONTENT_URI, ORIGINAL_EVENT_PROJECTION,
+                    DIRTY_EXCEPTION_IN_CALENDAR, mCalendarIdArgument, null);
+            try {
+                ContentValues cv = new ContentValues();
+                // We use _sync_mark here to distinguish dirty parents from parents with dirty
+                // exceptions
+                cv.put(EVENT_SYNC_MARK, "1");
+                while (c.moveToNext()) {
+                    // Mark the parents of dirty exceptions
+                    long parentId = c.getLong(0);
+                    int cnt = cr.update(
+                            asSyncAdapter(Events.CONTENT_URI, mEmailAddress,
+                                    Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), cv,
+                            EVENT_ID_AND_CALENDAR_ID, new String[] {
+                                    Long.toString(parentId), mCalendarIdString
+                            });
+                    // Keep track of any orphaned exceptions
+                    if (cnt == 0) {
+                        orphanedExceptions.add(c.getLong(1));
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            // Delete any orphaned exceptions
+            for (long orphan : orphanedExceptions) {
+                userLog(TAG, "Deleted orphaned exception: " + orphan);
+                cr.delete(
+                        asSyncAdapter(ContentUris.withAppendedId(Events.CONTENT_URI, orphan),
+                                mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), null, null);
+            }
+            orphanedExceptions.clear();
+
+            // Now we can go through dirty/marked top-level events and send them
+            // back to the server
+            EntityIterator eventIterator = EventsEntity.newEntityIterator(cr.query(
+                    asSyncAdapter(Events.CONTENT_URI, mEmailAddress,
+                            Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), null,
+                    DIRTY_OR_MARKED_TOP_LEVEL_IN_CALENDAR, mCalendarIdArgument, null), cr);
+            ContentValues cidValues = new ContentValues();
+
+            try {
+                boolean first = true;
+                while (eventIterator.hasNext()) {
+                    Entity entity = eventIterator.next();
+
+                    // For each of these entities, create the change commands
+                    ContentValues entityValues = entity.getEntityValues();
+                    String serverId = entityValues.getAsString(Events._SYNC_ID);
+
+                    // We first need to check whether we can upsync this event; our test for this
+                    // is currently the value of EXTENDED_PROPERTY_ATTENDEES_REDACTED
+                    // If this is set to "1", we can't upsync the event
+                    for (NamedContentValues ncv: entity.getSubValues()) {
+                        if (ncv.uri.equals(ExtendedProperties.CONTENT_URI)) {
+                            ContentValues ncvValues = ncv.values;
+                            if (ncvValues.getAsString(ExtendedProperties.NAME).equals(
+                                    EXTENDED_PROPERTY_UPSYNC_PROHIBITED)) {
+                                if ("1".equals(ncvValues.getAsString(ExtendedProperties.VALUE))) {
+                                    // Make sure we mark this to clear the dirty flag
+                                    mUploadedIdList.add(entityValues.getAsLong(Events._ID));
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+
+                    // Find our uid in the entity; otherwise create one
+                    String clientId = entityValues.getAsString(Events.SYNC_DATA2);
+                    if (clientId == null) {
+                        clientId = UUID.randomUUID().toString();
+                    }
+
+                    // EAS 2.5 needs: BusyStatus DtStamp EndTime Sensitivity StartTime TimeZone UID
+                    // We can generate all but what we're testing for below
+                    String organizerEmail = entityValues.getAsString(Events.ORGANIZER);
+                    boolean selfOrganizer = organizerEmail.equalsIgnoreCase(mEmailAddress);
+
+                    if (!entityValues.containsKey(Events.DTSTART)
+                            || (!entityValues.containsKey(Events.DURATION) &&
+                                    !entityValues.containsKey(Events.DTEND))
+                                    || organizerEmail == null) {
+                        continue;
+                    }
+
+                    if (first) {
+                        s.start(Tags.SYNC_COMMANDS);
+                        userLog("Sending Calendar changes to the server");
+                        first = false;
+                    }
+                    long eventId = entityValues.getAsLong(Events._ID);
+                    if (serverId == null) {
+                        // This is a new event; create a clientId
+                        userLog("Creating new event with clientId: ", clientId);
+                        s.start(Tags.SYNC_ADD).data(Tags.SYNC_CLIENT_ID, clientId);
+                        // And save it in the Event as the local id
+                        cidValues.put(Events.SYNC_DATA2, clientId);
+                        cidValues.put(EVENT_SYNC_VERSION, "0");
+                        cr.update(
+                                asSyncAdapter(
+                                        ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
+                                        mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                                cidValues, null, null);
+                    } else {
+                        if (entityValues.getAsInteger(Events.DELETED) == 1) {
+                            userLog("Deleting event with serverId: ", serverId);
+                            s.start(Tags.SYNC_DELETE).data(Tags.SYNC_SERVER_ID, serverId).end();
+                            mDeletedIdList.add(eventId);
+                            if (selfOrganizer) {
+                                mSendCancelIdList.add(eventId);
+                            } else {
+                                sendDeclinedEmail(entity, clientId);
+                            }
+                            continue;
+                        }
+                        userLog("Upsync change to event with serverId: " + serverId);
+                        // Get the current version
+                        String version = entityValues.getAsString(EVENT_SYNC_VERSION);
+                        // This should never be null, but catch this error anyway
+                        // Version should be "0" when we create the event, so use that
+                        if (version == null) {
+                            version = "0";
+                        } else {
+                            // Increment and save
+                            try {
+                                version = Integer.toString((Integer.parseInt(version) + 1));
+                            } catch (Exception e) {
+                                // Handle the case in which someone writes a non-integer here;
+                                // shouldn't happen, but we don't want to kill the sync for his
+                                version = "0";
+                            }
+                        }
+                        cidValues.put(EVENT_SYNC_VERSION, version);
+                        // Also save in entityValues so that we send it this time around
+                        entityValues.put(EVENT_SYNC_VERSION, version);
+                        cr.update(
+                                asSyncAdapter(
+                                        ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
+                                        mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                                cidValues, null, null);
+                        s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, serverId);
+                    }
+                    s.start(Tags.SYNC_APPLICATION_DATA);
+
+                    sendEvent(entity, clientId, s);
+
+                    // Now, the hard part; find exceptions for this event
+                    if (serverId != null) {
+                        EntityIterator exIterator = EventsEntity.newEntityIterator(cr.query(
+                                asSyncAdapter(Events.CONTENT_URI, mEmailAddress,
+                                        Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), null,
+                                ORIGINAL_EVENT_AND_CALENDAR, new String[] {
+                                        serverId, mCalendarIdString
+                                }, null), cr);
+                        boolean exFirst = true;
+                        while (exIterator.hasNext()) {
+                            Entity exEntity = exIterator.next();
+                            if (exFirst) {
+                                s.start(Tags.CALENDAR_EXCEPTIONS);
+                                exFirst = false;
+                            }
+                            s.start(Tags.CALENDAR_EXCEPTION);
+                            sendEvent(exEntity, null, s);
+                            ContentValues exValues = exEntity.getEntityValues();
+                            if (getInt(exValues, Events.DIRTY) == 1) {
+                                // This is a new/updated exception, so we've got to notify our
+                                // attendees about it
+                                long exEventId = exValues.getAsLong(Events._ID);
+                                int flag;
+
+                                // Copy subvalues into the exception; otherwise, we won't see the
+                                // attendees when preparing the message
+                                for (NamedContentValues ncv: entity.getSubValues()) {
+                                    exEntity.addSubValue(ncv.uri, ncv.values);
+                                }
+
+                                if ((getInt(exValues, Events.DELETED) == 1) ||
+                                        (getInt(exValues, Events.STATUS) ==
+                                            Events.STATUS_CANCELED)) {
+                                    flag = Message.FLAG_OUTGOING_MEETING_CANCEL;
+                                    if (!selfOrganizer) {
+                                        // Send a cancellation notice to the organizer
+                                        // Since CalendarProvider2 sets the organizer of exceptions
+                                        // to the user, we have to reset it first to the original
+                                        // organizer
+                                        exValues.put(Events.ORGANIZER,
+                                                entityValues.getAsString(Events.ORGANIZER));
+                                        sendDeclinedEmail(exEntity, clientId);
+                                    }
+                                } else {
+                                    flag = Message.FLAG_OUTGOING_MEETING_INVITE;
+                                }
+                                // Add the eventId of the exception to the uploaded id list, so that
+                                // the dirty/mark bits are cleared
+                                mUploadedIdList.add(exEventId);
+
+                                // Copy version so the ics attachment shows the proper sequence #
+                                exValues.put(EVENT_SYNC_VERSION,
+                                        entityValues.getAsString(EVENT_SYNC_VERSION));
+                                // Copy location so that it's included in the outgoing email
+                                if (entityValues.containsKey(Events.EVENT_LOCATION)) {
+                                    exValues.put(Events.EVENT_LOCATION,
+                                            entityValues.getAsString(Events.EVENT_LOCATION));
+                                }
+
+                                if (selfOrganizer) {
+                                    Message msg =
+                                        CalendarUtilities.createMessageForEntity(mContext,
+                                                exEntity, flag, clientId, mAccount);
+                                    if (msg != null) {
+                                        userLog("Queueing exception update to " + msg.mTo);
+                                        mOutgoingMailList.add(msg);
+                                    }
+                                }
+                            }
+                            s.end(); // EXCEPTION
+                        }
+                        if (!exFirst) {
+                            s.end(); // EXCEPTIONS
+                        }
+                    }
+
+                    s.end().end(); // ApplicationData & Change
+                    mUploadedIdList.add(eventId);
+
+                    // Go through the extended properties of this Event and pull out our tokenized
+                    // attendees list and the user attendee status; we will need them later
+                    String attendeeString = null;
+                    long attendeeStringId = -1;
+                    String userAttendeeStatus = null;
+                    long userAttendeeStatusId = -1;
+                    for (NamedContentValues ncv: entity.getSubValues()) {
+                        if (ncv.uri.equals(ExtendedProperties.CONTENT_URI)) {
+                            ContentValues ncvValues = ncv.values;
+                            String propertyName =
+                                ncvValues.getAsString(ExtendedProperties.NAME);
+                            if (propertyName.equals(EXTENDED_PROPERTY_ATTENDEES)) {
+                                attendeeString =
+                                    ncvValues.getAsString(ExtendedProperties.VALUE);
+                                attendeeStringId =
+                                    ncvValues.getAsLong(ExtendedProperties._ID);
+                            } else if (propertyName.equals(
+                                    EXTENDED_PROPERTY_USER_ATTENDEE_STATUS)) {
+                                userAttendeeStatus =
+                                    ncvValues.getAsString(ExtendedProperties.VALUE);
+                                userAttendeeStatusId =
+                                    ncvValues.getAsLong(ExtendedProperties._ID);
+                            }
+                        }
+                    }
+
+                    // Send the meeting invite if there are attendees and we're the organizer AND
+                    // if the Event itself is dirty (we might be syncing only because an exception
+                    // is dirty, in which case we DON'T send email about the Event)
+                    if (selfOrganizer &&
+                            (getInt(entityValues, Events.DIRTY) == 1)) {
+                        EmailContent.Message msg =
+                            CalendarUtilities.createMessageForEventId(mContext, eventId,
+                                    EmailContent.Message.FLAG_OUTGOING_MEETING_INVITE, clientId,
+                                    mAccount);
+                        if (msg != null) {
+                            userLog("Queueing invitation to ", msg.mTo);
+                            mOutgoingMailList.add(msg);
+                        }
+                        // Make a list out of our tokenized attendees, if we have any
+                        ArrayList<String> originalAttendeeList = new ArrayList<String>();
+                        if (attendeeString != null) {
+                            StringTokenizer st =
+                                new StringTokenizer(attendeeString, ATTENDEE_TOKENIZER_DELIMITER);
+                            while (st.hasMoreTokens()) {
+                                originalAttendeeList.add(st.nextToken());
+                            }
+                        }
+                        StringBuilder newTokenizedAttendees = new StringBuilder();
+                        // See if any attendees have been dropped and while we're at it, build
+                        // an updated String with tokenized attendee addresses
+                        for (NamedContentValues ncv: entity.getSubValues()) {
+                            if (ncv.uri.equals(Attendees.CONTENT_URI)) {
+                                String attendeeEmail =
+                                    ncv.values.getAsString(Attendees.ATTENDEE_EMAIL);
+                                // Remove all found attendees
+                                originalAttendeeList.remove(attendeeEmail);
+                                newTokenizedAttendees.append(attendeeEmail);
+                                newTokenizedAttendees.append(ATTENDEE_TOKENIZER_DELIMITER);
+                            }
+                        }
+                        // Update extended properties with the new attendee list, if we have one
+                        // Otherwise, create one (this would be the case for Events created on
+                        // device or "legacy" events (before this code was added)
+                        ContentValues cv = new ContentValues();
+                        cv.put(ExtendedProperties.VALUE, newTokenizedAttendees.toString());
+                        if (attendeeString != null) {
+                            cr.update(asSyncAdapter(ContentUris.withAppendedId(
+                                    ExtendedProperties.CONTENT_URI, attendeeStringId),
+                                    mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                                    cv, null, null);
+                        } else {
+                            // If there wasn't an "attendees" property, insert one
+                            cv.put(ExtendedProperties.NAME, EXTENDED_PROPERTY_ATTENDEES);
+                            cv.put(ExtendedProperties.EVENT_ID, eventId);
+                            cr.insert(asSyncAdapter(ExtendedProperties.CONTENT_URI,
+                                    mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), cv);
+                        }
+                        // Whoever is left has been removed from the attendee list; send them
+                        // a cancellation
+                        for (String removedAttendee: originalAttendeeList) {
+                            // Send a cancellation message to each of them
+                            msg = CalendarUtilities.createMessageForEventId(mContext, eventId,
+                                    Message.FLAG_OUTGOING_MEETING_CANCEL, clientId, mAccount,
+                                    removedAttendee);
+                            if (msg != null) {
+                                // Just send it to the removed attendee
+                                userLog("Queueing cancellation to removed attendee " + msg.mTo);
+                                mOutgoingMailList.add(msg);
+                            }
+                        }
+                    } else if (!selfOrganizer) {
+                        // If we're not the organizer, see if we've changed our attendee status
+                        // Our last synced attendee status is in ExtendedProperties, and we've
+                        // retrieved it above as userAttendeeStatus
+                        int currentStatus = entityValues.getAsInteger(Events.SELF_ATTENDEE_STATUS);
+                        int syncStatus = Attendees.ATTENDEE_STATUS_NONE;
+                        if (userAttendeeStatus != null) {
+                            try {
+                                syncStatus = Integer.parseInt(userAttendeeStatus);
+                            } catch (NumberFormatException e) {
+                                // Just in case somebody else mucked with this and it's not Integer
+                            }
+                        }
+                        if ((currentStatus != syncStatus) &&
+                                (currentStatus != Attendees.ATTENDEE_STATUS_NONE)) {
+                            // If so, send a meeting reply
+                            int messageFlag = 0;
+                            switch (currentStatus) {
+                                case Attendees.ATTENDEE_STATUS_ACCEPTED:
+                                    messageFlag = Message.FLAG_OUTGOING_MEETING_ACCEPT;
+                                    break;
+                                case Attendees.ATTENDEE_STATUS_DECLINED:
+                                    messageFlag = Message.FLAG_OUTGOING_MEETING_DECLINE;
+                                    break;
+                                case Attendees.ATTENDEE_STATUS_TENTATIVE:
+                                    messageFlag = Message.FLAG_OUTGOING_MEETING_TENTATIVE;
+                                    break;
+                            }
+                            // Make sure we have a valid status (messageFlag should never be zero)
+                            if (messageFlag != 0 && userAttendeeStatusId >= 0) {
+                                // Save away the new status
+                                cidValues.clear();
+                                cidValues.put(ExtendedProperties.VALUE,
+                                        Integer.toString(currentStatus));
+                                cr.update(asSyncAdapter(ContentUris.withAppendedId(
+                                        ExtendedProperties.CONTENT_URI, userAttendeeStatusId),
+                                        mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                                        cidValues, null, null);
+                                // Send mail to the organizer advising of the new status
+                                EmailContent.Message msg =
+                                    CalendarUtilities.createMessageForEventId(mContext, eventId,
+                                            messageFlag, clientId, mAccount);
+                                if (msg != null) {
+                                    userLog("Queueing invitation reply to " + msg.mTo);
+                                    mOutgoingMailList.add(msg);
+                                }
+                            }
+                        }
+                    }
+                }
+                if (!first) {
+                    s.end(); // Commands
+                }
+            } finally {
+                eventIterator.close();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not read dirty events.");
+        }
+
+        return false;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/ContactsSyncAdapter.java b/exchange2/src/com/android/exchange/adapter/ContactsSyncAdapter.java
new file mode 100644
index 0000000..1b21d11
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/ContactsSyncAdapter.java
@@ -0,0 +1,1935 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import android.content.ContentProviderClient;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderOperation.Builder;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Entity;
+import android.content.Entity.NamedContentValues;
+import android.content.EntityIterator;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Event;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.RawContactsEntity;
+import android.provider.ContactsContract.Settings;
+import android.provider.ContactsContract.SyncState;
+import android.provider.SyncStateContract;
+import android.text.TextUtils;
+import android.text.util.Rfc822Token;
+import android.text.util.Rfc822Tokenizer;
+import android.util.Base64;
+import android.util.Log;
+
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.Eas;
+import com.android.exchange.EasSyncService;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Sync adapter for EAS Contacts
+ *
+ */
+public class ContactsSyncAdapter extends AbstractSyncAdapter {
+
+    private static final String TAG = "EasContactsSyncAdapter";
+    private static final String SERVER_ID_SELECTION = RawContacts.SOURCE_ID + "=?";
+    private static final String CLIENT_ID_SELECTION = RawContacts.SYNC1 + "=?";
+    private static final String[] ID_PROJECTION = new String[] {RawContacts._ID};
+    private static final String[] GROUP_TITLE_PROJECTION = new String[] {Groups.TITLE};
+    private static final String MIMETYPE_GROUP_MEMBERSHIP_AND_ID_EQUALS = Data.MIMETYPE + "='" +
+        GroupMembership.CONTENT_ITEM_TYPE + "' AND " + GroupMembership.GROUP_ROW_ID + "=?";
+    private static final String[] GROUPS_ID_PROJECTION = new String[] {Groups._ID};
+
+    private static final ArrayList<NamedContentValues> EMPTY_ARRAY_NAMEDCONTENTVALUES
+        = new ArrayList<NamedContentValues>();
+
+    private static final String FOUND_DATA_ROW = "com.android.exchange.FOUND_ROW";
+
+    private static final int[] HOME_ADDRESS_TAGS = new int[] {Tags.CONTACTS_HOME_ADDRESS_CITY,
+        Tags.CONTACTS_HOME_ADDRESS_COUNTRY,
+        Tags.CONTACTS_HOME_ADDRESS_POSTAL_CODE,
+        Tags.CONTACTS_HOME_ADDRESS_STATE,
+        Tags.CONTACTS_HOME_ADDRESS_STREET};
+
+    private static final int[] WORK_ADDRESS_TAGS = new int[] {Tags.CONTACTS_BUSINESS_ADDRESS_CITY,
+        Tags.CONTACTS_BUSINESS_ADDRESS_COUNTRY,
+        Tags.CONTACTS_BUSINESS_ADDRESS_POSTAL_CODE,
+        Tags.CONTACTS_BUSINESS_ADDRESS_STATE,
+        Tags.CONTACTS_BUSINESS_ADDRESS_STREET};
+
+    private static final int[] OTHER_ADDRESS_TAGS = new int[] {Tags.CONTACTS_HOME_ADDRESS_CITY,
+        Tags.CONTACTS_OTHER_ADDRESS_COUNTRY,
+        Tags.CONTACTS_OTHER_ADDRESS_POSTAL_CODE,
+        Tags.CONTACTS_OTHER_ADDRESS_STATE,
+        Tags.CONTACTS_OTHER_ADDRESS_STREET};
+
+    private static final int MAX_IM_ROWS = 3;
+    private static final int MAX_EMAIL_ROWS = 3;
+    private static final int MAX_PHONE_ROWS = 2;
+    private static final String COMMON_DATA_ROW = Im.DATA;  // Could have been Email.DATA, etc.
+    private static final String COMMON_TYPE_ROW = Phone.TYPE; // Could have been any typed row
+
+    private static final int[] IM_TAGS = new int[] {Tags.CONTACTS2_IM_ADDRESS,
+        Tags.CONTACTS2_IM_ADDRESS_2, Tags.CONTACTS2_IM_ADDRESS_3};
+
+    private static final int[] EMAIL_TAGS = new int[] {Tags.CONTACTS_EMAIL1_ADDRESS,
+        Tags.CONTACTS_EMAIL2_ADDRESS, Tags.CONTACTS_EMAIL3_ADDRESS};
+
+    private static final int[] WORK_PHONE_TAGS = new int[] {Tags.CONTACTS_BUSINESS_TELEPHONE_NUMBER,
+        Tags.CONTACTS_BUSINESS2_TELEPHONE_NUMBER};
+
+    private static final int[] HOME_PHONE_TAGS = new int[] {Tags.CONTACTS_HOME_TELEPHONE_NUMBER,
+        Tags.CONTACTS_HOME2_TELEPHONE_NUMBER};
+
+    private static final Object sSyncKeyLock = new Object();
+
+    ArrayList<Long> mDeletedIdList = new ArrayList<Long>();
+    ArrayList<Long> mUpdatedIdList = new ArrayList<Long>();
+
+    private final Uri mAccountUri;
+    private final ContentResolver mContentResolver;
+    private boolean mGroupsUsed = false;
+
+    public ContactsSyncAdapter(EasSyncService service) {
+        super(service);
+        mAccountUri = uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI);
+        mContentResolver = mContext.getContentResolver();
+    }
+
+    static Uri addCallerIsSyncAdapterParameter(Uri uri) {
+        return uri.buildUpon()
+                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+                .build();
+    }
+
+    @Override
+    public void sendSyncOptions(Double protocolVersion, Serializer s) throws IOException  {
+        setPimSyncOptions(protocolVersion, null, s);
+    }
+
+    @Override
+    public boolean isSyncable() {
+        return ContentResolver.getSyncAutomatically(
+                mAccountManagerAccount, ContactsContract.AUTHORITY);
+    }
+
+    @Override
+    public boolean parse(InputStream is) throws IOException, CommandStatusException {
+        EasContactsSyncParser p = new EasContactsSyncParser(is, this);
+        return p.parse();
+    }
+
+
+    @Override
+    public void wipe() {
+        mContentResolver.delete(mAccountUri, null, null);
+    }
+
+    interface UntypedRow {
+        public void addValues(RowBuilder builder);
+        public boolean isSameAs(int type, String value);
+    }
+
+    /**
+     * We get our SyncKey from ContactsProvider.  If there's not one, we set it to "0" (the reset
+     * state) and save that away.
+     */
+    @Override
+    public String getSyncKey() throws IOException {
+        synchronized (sSyncKeyLock) {
+            ContentProviderClient client = mService.mContentResolver
+                    .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
+            try {
+                byte[] data = SyncStateContract.Helpers.get(client,
+                        ContactsContract.SyncState.CONTENT_URI, mAccountManagerAccount);
+                if (data == null || data.length == 0) {
+                    // Initialize the SyncKey
+                    setSyncKey("0", false);
+                    // Make sure ungrouped contacts for Exchange are defaultly visible
+                    ContentValues cv = new ContentValues();
+                    cv.put(Groups.ACCOUNT_NAME, mAccount.mEmailAddress);
+                    cv.put(Groups.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+                    cv.put(Settings.UNGROUPED_VISIBLE, true);
+                    client.insert(addCallerIsSyncAdapterParameter(Settings.CONTENT_URI), cv);
+                    return "0";
+                } else {
+                    return new String(data);
+                }
+            } catch (RemoteException e) {
+                throw new IOException("Can't get SyncKey from ContactsProvider");
+            }
+        }
+    }
+
+    /**
+     * We only need to set this when we're forced to make the SyncKey "0" (a reset).  In all other
+     * cases, the SyncKey is set within ContactOperations
+     */
+    @Override
+    public void setSyncKey(String syncKey, boolean inCommands) throws IOException {
+        synchronized (sSyncKeyLock) {
+            if ("0".equals(syncKey) || !inCommands) {
+                ContentProviderClient client = mService.mContentResolver
+                        .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
+                try {
+                    SyncStateContract.Helpers.set(client, ContactsContract.SyncState.CONTENT_URI,
+                            mAccountManagerAccount, syncKey.getBytes());
+                    userLog("SyncKey set to ", syncKey, " in ContactsProvider");
+                } catch (RemoteException e) {
+                    throw new IOException("Can't set SyncKey in ContactsProvider");
+                }
+            }
+            mMailbox.mSyncKey = syncKey;
+        }
+    }
+
+    public static final class EasChildren {
+        private EasChildren() {}
+
+        /** MIME type used when storing this in data table. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_children";
+        public static final int MAX_CHILDREN = 8;
+        public static final String[] ROWS =
+            new String[] {"data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9"};
+    }
+
+    public static final class EasPersonal {
+        String anniversary;
+        String fileAs;
+
+            /** MIME type used when storing this in data table. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_personal";
+        public static final String ANNIVERSARY = "data2";
+        public static final String FILE_AS = "data4";
+
+        boolean hasData() {
+            return anniversary != null || fileAs != null;
+        }
+    }
+
+    public static final class EasBusiness {
+        String customerId;
+        String governmentId;
+        String accountName;
+
+        /** MIME type used when storing this in data table. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_business";
+        public static final String CUSTOMER_ID = "data6";
+        public static final String GOVERNMENT_ID = "data7";
+        public static final String ACCOUNT_NAME = "data8";
+
+        boolean hasData() {
+            return customerId != null || governmentId != null || accountName != null;
+        }
+    }
+
+    public static final class Address {
+        String city;
+        String country;
+        String code;
+        String street;
+        String state;
+
+        boolean hasData() {
+            return city != null || country != null || code != null || state != null
+                || street != null;
+        }
+    }
+
+    class EmailRow implements UntypedRow {
+        String email;
+        String displayName;
+
+        public EmailRow(String _email) {
+            Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(_email);
+            // Can't happen, but belt & suspenders
+            if (tokens.length == 0) {
+                email = "";
+                displayName = "";
+            } else {
+                Rfc822Token token = tokens[0];
+                email = token.getAddress();
+                displayName = token.getName();
+            }
+        }
+
+        public void addValues(RowBuilder builder) {
+            builder.withValue(Email.DATA, email);
+            builder.withValue(Email.DISPLAY_NAME, displayName);
+        }
+
+        public boolean isSameAs(int type, String value) {
+            return email.equalsIgnoreCase(value);
+        }
+    }
+
+    class ImRow implements UntypedRow {
+        String im;
+
+        public ImRow(String _im) {
+            im = _im;
+        }
+
+        public void addValues(RowBuilder builder) {
+            builder.withValue(Im.DATA, im);
+        }
+
+        public boolean isSameAs(int type, String value) {
+            return im.equalsIgnoreCase(value);
+        }
+    }
+
+    class PhoneRow implements UntypedRow {
+        String phone;
+        int type;
+
+        public PhoneRow(String _phone, int _type) {
+            phone = _phone;
+            type = _type;
+        }
+
+        public void addValues(RowBuilder builder) {
+            builder.withValue(Im.DATA, phone);
+            builder.withValue(Phone.TYPE, type);
+        }
+
+        public boolean isSameAs(int _type, String value) {
+            return type == _type && phone.equalsIgnoreCase(value);
+        }
+    }
+
+   class EasContactsSyncParser extends AbstractSyncParser {
+
+        String[] mBindArgument = new String[1];
+        String mMailboxIdAsString;
+        ContactOperations ops = new ContactOperations();
+
+        public EasContactsSyncParser(InputStream in, ContactsSyncAdapter adapter)
+                throws IOException {
+            super(in, adapter);
+        }
+
+        public void addData(String serverId, ContactOperations ops, Entity entity)
+                throws IOException {
+            String fileAs = null;
+            String prefix = null;
+            String firstName = null;
+            String lastName = null;
+            String middleName = null;
+            String suffix = null;
+            String companyName = null;
+            String yomiFirstName = null;
+            String yomiLastName = null;
+            String yomiCompanyName = null;
+            String title = null;
+            String department = null;
+            String officeLocation = null;
+            Address home = new Address();
+            Address work = new Address();
+            Address other = new Address();
+            EasBusiness business = new EasBusiness();
+            EasPersonal personal = new EasPersonal();
+            ArrayList<String> children = new ArrayList<String>();
+            ArrayList<UntypedRow> emails = new ArrayList<UntypedRow>();
+            ArrayList<UntypedRow> ims = new ArrayList<UntypedRow>();
+            ArrayList<UntypedRow> homePhones = new ArrayList<UntypedRow>();
+            ArrayList<UntypedRow> workPhones = new ArrayList<UntypedRow>();
+            if (entity == null) {
+                ops.newContact(serverId);
+            }
+
+            while (nextTag(Tags.SYNC_APPLICATION_DATA) != END) {
+                switch (tag) {
+                    case Tags.CONTACTS_FIRST_NAME:
+                        firstName = getValue();
+                        break;
+                    case Tags.CONTACTS_LAST_NAME:
+                        lastName = getValue();
+                        break;
+                    case Tags.CONTACTS_MIDDLE_NAME:
+                        middleName = getValue();
+                        break;
+                    case Tags.CONTACTS_FILE_AS:
+                        fileAs = getValue();
+                        break;
+                    case Tags.CONTACTS_SUFFIX:
+                        suffix = getValue();
+                        break;
+                    case Tags.CONTACTS_COMPANY_NAME:
+                        companyName = getValue();
+                        break;
+                    case Tags.CONTACTS_JOB_TITLE:
+                        title = getValue();
+                        break;
+                    case Tags.CONTACTS_EMAIL1_ADDRESS:
+                    case Tags.CONTACTS_EMAIL2_ADDRESS:
+                    case Tags.CONTACTS_EMAIL3_ADDRESS:
+                        emails.add(new EmailRow(getValue()));
+                        break;
+                    case Tags.CONTACTS_BUSINESS2_TELEPHONE_NUMBER:
+                    case Tags.CONTACTS_BUSINESS_TELEPHONE_NUMBER:
+                        workPhones.add(new PhoneRow(getValue(), Phone.TYPE_WORK));
+                        break;
+                    case Tags.CONTACTS2_MMS:
+                        ops.addPhone(entity, Phone.TYPE_MMS, getValue());
+                        break;
+                    case Tags.CONTACTS_BUSINESS_FAX_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_FAX_WORK, getValue());
+                        break;
+                    case Tags.CONTACTS2_COMPANY_MAIN_PHONE:
+                        ops.addPhone(entity, Phone.TYPE_COMPANY_MAIN, getValue());
+                        break;
+                    case Tags.CONTACTS_HOME_FAX_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_FAX_HOME, getValue());
+                        break;
+                    case Tags.CONTACTS_HOME_TELEPHONE_NUMBER:
+                    case Tags.CONTACTS_HOME2_TELEPHONE_NUMBER:
+                        homePhones.add(new PhoneRow(getValue(), Phone.TYPE_HOME));
+                        break;
+                    case Tags.CONTACTS_MOBILE_TELEPHONE_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_MOBILE, getValue());
+                        break;
+                    case Tags.CONTACTS_CAR_TELEPHONE_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_CAR, getValue());
+                        break;
+                    case Tags.CONTACTS_RADIO_TELEPHONE_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_RADIO, getValue());
+                        break;
+                    case Tags.CONTACTS_PAGER_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_PAGER, getValue());
+                        break;
+                    case Tags.CONTACTS_ASSISTANT_TELEPHONE_NUMBER:
+                        ops.addPhone(entity, Phone.TYPE_ASSISTANT, getValue());
+                        break;
+                    case Tags.CONTACTS2_IM_ADDRESS:
+                    case Tags.CONTACTS2_IM_ADDRESS_2:
+                    case Tags.CONTACTS2_IM_ADDRESS_3:
+                        ims.add(new ImRow(getValue()));
+                        break;
+                    case Tags.CONTACTS_BUSINESS_ADDRESS_CITY:
+                        work.city = getValue();
+                        break;
+                    case Tags.CONTACTS_BUSINESS_ADDRESS_COUNTRY:
+                        work.country = getValue();
+                        break;
+                    case Tags.CONTACTS_BUSINESS_ADDRESS_POSTAL_CODE:
+                        work.code = getValue();
+                        break;
+                    case Tags.CONTACTS_BUSINESS_ADDRESS_STATE:
+                        work.state = getValue();
+                        break;
+                    case Tags.CONTACTS_BUSINESS_ADDRESS_STREET:
+                        work.street = getValue();
+                        break;
+                    case Tags.CONTACTS_HOME_ADDRESS_CITY:
+                        home.city = getValue();
+                        break;
+                    case Tags.CONTACTS_HOME_ADDRESS_COUNTRY:
+                        home.country = getValue();
+                        break;
+                    case Tags.CONTACTS_HOME_ADDRESS_POSTAL_CODE:
+                        home.code = getValue();
+                        break;
+                    case Tags.CONTACTS_HOME_ADDRESS_STATE:
+                        home.state = getValue();
+                        break;
+                    case Tags.CONTACTS_HOME_ADDRESS_STREET:
+                        home.street = getValue();
+                        break;
+                    case Tags.CONTACTS_OTHER_ADDRESS_CITY:
+                        other.city = getValue();
+                        break;
+                    case Tags.CONTACTS_OTHER_ADDRESS_COUNTRY:
+                        other.country = getValue();
+                        break;
+                    case Tags.CONTACTS_OTHER_ADDRESS_POSTAL_CODE:
+                        other.code = getValue();
+                        break;
+                    case Tags.CONTACTS_OTHER_ADDRESS_STATE:
+                        other.state = getValue();
+                        break;
+                    case Tags.CONTACTS_OTHER_ADDRESS_STREET:
+                        other.street = getValue();
+                        break;
+
+                    case Tags.CONTACTS_CHILDREN:
+                        childrenParser(children);
+                        break;
+
+                    case Tags.CONTACTS_YOMI_COMPANY_NAME:
+                        yomiCompanyName = getValue();
+                        break;
+                    case Tags.CONTACTS_YOMI_FIRST_NAME:
+                        yomiFirstName = getValue();
+                        break;
+                    case Tags.CONTACTS_YOMI_LAST_NAME:
+                        yomiLastName = getValue();
+                        break;
+
+                    case Tags.CONTACTS2_NICKNAME:
+                        ops.addNickname(entity, getValue());
+                        break;
+
+                    case Tags.CONTACTS_ASSISTANT_NAME:
+                        ops.addRelation(entity, Relation.TYPE_ASSISTANT, getValue());
+                        break;
+                    case Tags.CONTACTS2_MANAGER_NAME:
+                        ops.addRelation(entity, Relation.TYPE_MANAGER, getValue());
+                        break;
+                    case Tags.CONTACTS_SPOUSE:
+                        ops.addRelation(entity, Relation.TYPE_SPOUSE, getValue());
+                        break;
+                    case Tags.CONTACTS_DEPARTMENT:
+                        department = getValue();
+                        break;
+                    case Tags.CONTACTS_TITLE:
+                        prefix = getValue();
+                        break;
+
+                    // EAS Business
+                    case Tags.CONTACTS_OFFICE_LOCATION:
+                        officeLocation = getValue();
+                        break;
+                    case Tags.CONTACTS2_CUSTOMER_ID:
+                        business.customerId = getValue();
+                        break;
+                    case Tags.CONTACTS2_GOVERNMENT_ID:
+                        business.governmentId = getValue();
+                        break;
+                    case Tags.CONTACTS2_ACCOUNT_NAME:
+                        business.accountName = getValue();
+                        break;
+
+                    // EAS Personal
+                    case Tags.CONTACTS_ANNIVERSARY:
+                        personal.anniversary = getValue();
+                        break;
+                    case Tags.CONTACTS_BIRTHDAY:
+                        ops.addBirthday(entity, getValue());
+                        break;
+                    case Tags.CONTACTS_WEBPAGE:
+                        ops.addWebpage(entity, getValue());
+                        break;
+
+                    case Tags.CONTACTS_PICTURE:
+                        ops.addPhoto(entity, getValue());
+                        break;
+
+                    case Tags.BASE_BODY:
+                        ops.addNote(entity, bodyParser());
+                        break;
+                    case Tags.CONTACTS_BODY:
+                        ops.addNote(entity, getValue());
+                        break;
+
+                    case Tags.CONTACTS_CATEGORIES:
+                        mGroupsUsed = true;
+                        categoriesParser(ops, entity);
+                        break;
+
+                    case Tags.CONTACTS_COMPRESSED_RTF:
+                        // We don't use this, and it isn't necessary to upload, so we'll ignore it
+                        skipTag();
+                        break;
+
+                    default:
+                        skipTag();
+                }
+            }
+
+            // We must have first name, last name, or company name
+            String name = null;
+            if (firstName != null || lastName != null) {
+                if (firstName == null) {
+                    name = lastName;
+                } else if (lastName == null) {
+                    name = firstName;
+                } else {
+                    name = firstName + ' ' + lastName;
+                }
+            } else if (companyName != null) {
+                name = companyName;
+            }
+
+            ops.addName(entity, prefix, firstName, lastName, middleName, suffix, name,
+                    yomiFirstName, yomiLastName, fileAs);
+            ops.addBusiness(entity, business);
+            ops.addPersonal(entity, personal);
+
+            ops.addUntyped(entity, emails, Email.CONTENT_ITEM_TYPE, -1, MAX_EMAIL_ROWS);
+            ops.addUntyped(entity, ims, Im.CONTENT_ITEM_TYPE, -1, MAX_IM_ROWS);
+            ops.addUntyped(entity, homePhones, Phone.CONTENT_ITEM_TYPE, Phone.TYPE_HOME,
+                    MAX_PHONE_ROWS);
+            ops.addUntyped(entity, workPhones, Phone.CONTENT_ITEM_TYPE, Phone.TYPE_WORK,
+                    MAX_PHONE_ROWS);
+
+            if (!children.isEmpty()) {
+                ops.addChildren(entity, children);
+            }
+
+            if (work.hasData()) {
+                ops.addPostal(entity, StructuredPostal.TYPE_WORK, work.street, work.city,
+                        work.state, work.country, work.code);
+            }
+            if (home.hasData()) {
+                ops.addPostal(entity, StructuredPostal.TYPE_HOME, home.street, home.city,
+                        home.state, home.country, home.code);
+            }
+            if (other.hasData()) {
+                ops.addPostal(entity, StructuredPostal.TYPE_OTHER, other.street, other.city,
+                        other.state, other.country, other.code);
+            }
+
+            if (companyName != null) {
+                ops.addOrganization(entity, Organization.TYPE_WORK, companyName, title, department,
+                        yomiCompanyName, officeLocation);
+            }
+
+            if (entity != null) {
+                // We've been removing rows from the list as they've been found in the xml
+                // Any that are left must have been deleted on the server
+                ArrayList<NamedContentValues> ncvList = entity.getSubValues();
+                for (NamedContentValues ncv: ncvList) {
+                    // These rows need to be deleted...
+                    Uri u = dataUriFromNamedContentValues(ncv);
+                    ops.add(ContentProviderOperation.newDelete(addCallerIsSyncAdapterParameter(u))
+                            .build());
+                }
+            }
+        }
+
+        private void categoriesParser(ContactOperations ops, Entity entity) throws IOException {
+            while (nextTag(Tags.CONTACTS_CATEGORIES) != END) {
+                switch (tag) {
+                    case Tags.CONTACTS_CATEGORY:
+                        ops.addGroup(entity, getValue());
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        private void childrenParser(ArrayList<String> children) throws IOException {
+            while (nextTag(Tags.CONTACTS_CHILDREN) != END) {
+                switch (tag) {
+                    case Tags.CONTACTS_CHILD:
+                        if (children.size() < EasChildren.MAX_CHILDREN) {
+                            children.add(getValue());
+                        }
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        private String bodyParser() throws IOException {
+            String body = null;
+            while (nextTag(Tags.BASE_BODY) != END) {
+                switch (tag) {
+                    case Tags.BASE_DATA:
+                        body = getValue();
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+            return body;
+        }
+
+        public void addParser(ContactOperations ops) throws IOException {
+            String serverId = null;
+            while (nextTag(Tags.SYNC_ADD) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID: // same as
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_APPLICATION_DATA:
+                        addData(serverId, ops, null);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        private Cursor getServerIdCursor(String serverId) {
+            mBindArgument[0] = serverId;
+            return mContentResolver.query(mAccountUri, ID_PROJECTION, SERVER_ID_SELECTION,
+                    mBindArgument, null);
+        }
+
+        private Cursor getClientIdCursor(String clientId) {
+            mBindArgument[0] = clientId;
+            return mContentResolver.query(mAccountUri, ID_PROJECTION, CLIENT_ID_SELECTION,
+                    mBindArgument, null);
+        }
+
+        public void deleteParser(ContactOperations ops) throws IOException {
+            while (nextTag(Tags.SYNC_DELETE) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        String serverId = getValue();
+                        // Find the message in this mailbox with the given serverId
+                        Cursor c = getServerIdCursor(serverId);
+                        try {
+                            if (c.moveToFirst()) {
+                                userLog("Deleting ", serverId);
+                                ops.delete(c.getLong(0));
+                            }
+                        } finally {
+                            c.close();
+                        }
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        class ServerChange {
+            long id;
+            boolean read;
+
+            ServerChange(long _id, boolean _read) {
+                id = _id;
+                read = _read;
+            }
+        }
+
+        /**
+         * Changes are handled row by row, and only changed/new rows are acted upon
+         * @param ops the array of pending ContactProviderOperations.
+         * @throws IOException
+         */
+        public void changeParser(ContactOperations ops) throws IOException {
+            String serverId = null;
+            Entity entity = null;
+            while (nextTag(Tags.SYNC_CHANGE) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        serverId = getValue();
+                        Cursor c = getServerIdCursor(serverId);
+                        try {
+                            if (c.moveToFirst()) {
+                                // TODO Handle deleted individual rows...
+                                Uri uri = ContentUris.withAppendedId(
+                                        RawContacts.CONTENT_URI, c.getLong(0));
+                                uri = Uri.withAppendedPath(
+                                        uri, RawContacts.Entity.CONTENT_DIRECTORY);
+                                EntityIterator entityIterator = RawContacts.newEntityIterator(
+                                    mContentResolver.query(uri, null, null, null, null));
+                                if (entityIterator.hasNext()) {
+                                    entity = entityIterator.next();
+                                }
+                                userLog("Changing contact ", serverId);
+                            }
+                        } finally {
+                            c.close();
+                        }
+                        break;
+                    case Tags.SYNC_APPLICATION_DATA:
+                        addData(serverId, ops, entity);
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+        }
+
+        @Override
+        public void commandsParser() throws IOException {
+            while (nextTag(Tags.SYNC_COMMANDS) != END) {
+                if (tag == Tags.SYNC_ADD) {
+                    addParser(ops);
+                    incrementChangeCount();
+                } else if (tag == Tags.SYNC_DELETE) {
+                    deleteParser(ops);
+                    incrementChangeCount();
+                } else if (tag == Tags.SYNC_CHANGE) {
+                    changeParser(ops);
+                    incrementChangeCount();
+                } else
+                    skipTag();
+            }
+        }
+
+        @Override
+        public void commit() throws IOException {
+           // Save the syncKey here, using the Helper provider by Contacts provider
+            userLog("Contacts SyncKey saved as: ", mMailbox.mSyncKey);
+            ops.add(SyncStateContract.Helpers.newSetOperation(SyncState.CONTENT_URI,
+                    mAccountManagerAccount, mMailbox.mSyncKey.getBytes()));
+
+            // Execute these all at once...
+            ops.execute();
+
+            if (ops.mResults != null) {
+                ContentValues cv = new ContentValues();
+                cv.put(RawContacts.DIRTY, 0);
+                for (int i = 0; i < ops.mContactIndexCount; i++) {
+                    int index = ops.mContactIndexArray[i];
+                    Uri u = ops.mResults[index].uri;
+                    if (u != null) {
+                        String idString = u.getLastPathSegment();
+                        mContentResolver.update(
+                                addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI), cv,
+                                RawContacts._ID + "=" + idString, null);
+                    }
+                }
+            }
+        }
+
+        public void addResponsesParser() throws IOException {
+            String serverId = null;
+            String clientId = null;
+            ContentValues cv = new ContentValues();
+            while (nextTag(Tags.SYNC_ADD) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_CLIENT_ID:
+                        clientId = getValue();
+                        break;
+                    case Tags.SYNC_STATUS:
+                        getValue();
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+
+            // This is theoretically impossible, but...
+            if (clientId == null || serverId == null) return;
+
+            Cursor c = getClientIdCursor(clientId);
+            try {
+                if (c.moveToFirst()) {
+                    cv.put(RawContacts.SOURCE_ID, serverId);
+                    cv.put(RawContacts.DIRTY, 0);
+                    ops.add(ContentProviderOperation.newUpdate(
+                            ContentUris.withAppendedId(
+                                    addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI),
+                                    c.getLong(0)))
+                            .withValues(cv)
+                            .build());
+                    userLog("New contact " + clientId + " was given serverId: " + serverId);
+                }
+            } finally {
+                c.close();
+            }
+        }
+
+        public void changeResponsesParser() throws IOException {
+            String serverId = null;
+            String status = null;
+            while (nextTag(Tags.SYNC_CHANGE) != END) {
+                switch (tag) {
+                    case Tags.SYNC_SERVER_ID:
+                        serverId = getValue();
+                        break;
+                    case Tags.SYNC_STATUS:
+                        status = getValue();
+                        break;
+                    default:
+                        skipTag();
+                }
+            }
+            if (serverId != null && status != null) {
+                userLog("Changed contact " + serverId + " failed with status: " + status);
+            }
+        }
+
+
+        @Override
+        public void responsesParser() throws IOException {
+            // Handle server responses here (for Add and Change)
+            while (nextTag(Tags.SYNC_RESPONSES) != END) {
+                if (tag == Tags.SYNC_ADD) {
+                    addResponsesParser();
+                } else if (tag == Tags.SYNC_CHANGE) {
+                    changeResponsesParser();
+                } else
+                    skipTag();
+            }
+        }
+    }
+
+
+    private Uri uriWithAccountAndIsSyncAdapter(Uri uri) {
+        return uri.buildUpon()
+            .appendQueryParameter(RawContacts.ACCOUNT_NAME, mAccount.mEmailAddress)
+            .appendQueryParameter(RawContacts.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE)
+            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+            .build();
+    }
+
+    /**
+     * SmartBuilder is a wrapper for the Builder class that is used to create/update rows for a
+     * ContentProvider.  It has, in addition to the Builder, ContentValues which, if present,
+     * represent the current values of that row, that can be compared against current values to
+     * see whether an update is even necessary.  The methods on SmartBuilder are delegated to
+     * the Builder.
+     */
+    private class RowBuilder {
+        Builder builder;
+        ContentValues cv;
+
+        public RowBuilder(Builder _builder) {
+            builder = _builder;
+        }
+
+        public RowBuilder(Builder _builder, NamedContentValues _ncv) {
+            builder = _builder;
+            cv = _ncv.values;
+        }
+
+        RowBuilder withValues(ContentValues values) {
+            builder.withValues(values);
+            return this;
+        }
+
+        RowBuilder withValueBackReference(String key, int previousResult) {
+            builder.withValueBackReference(key, previousResult);
+            return this;
+        }
+
+        ContentProviderOperation build() {
+            return builder.build();
+        }
+
+        RowBuilder withValue(String key, Object value) {
+            builder.withValue(key, value);
+            return this;
+        }
+    }
+
+    private class ContactOperations extends ArrayList<ContentProviderOperation> {
+        private static final long serialVersionUID = 1L;
+        private int mCount = 0;
+        private int mContactBackValue = mCount;
+        // Make an array big enough for the PIM window (max items we can get)
+        private int[] mContactIndexArray =
+            new int[Integer.parseInt(AbstractSyncAdapter.PIM_WINDOW_SIZE)];
+        private int mContactIndexCount = 0;
+        private ContentProviderResult[] mResults = null;
+
+        @Override
+        public boolean add(ContentProviderOperation op) {
+            super.add(op);
+            mCount++;
+            return true;
+        }
+
+        public void newContact(String serverId) {
+            Builder builder = ContentProviderOperation
+                .newInsert(uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI));
+            ContentValues values = new ContentValues();
+            values.put(RawContacts.SOURCE_ID, serverId);
+            builder.withValues(values);
+            mContactBackValue = mCount;
+            mContactIndexArray[mContactIndexCount++] = mCount;
+            add(builder.build());
+        }
+
+        public void delete(long id) {
+            add(ContentProviderOperation
+                    .newDelete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, id)
+                            .buildUpon()
+                            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+                            .build())
+                    .build());
+        }
+
+        public void execute() {
+            synchronized (mService.getSynchronizer()) {
+                if (!mService.isStopped()) {
+                    try {
+                        if (!isEmpty()) {
+                            mService.userLog("Executing ", size(), " CPO's");
+                            mResults = mContext.getContentResolver().applyBatch(
+                                    ContactsContract.AUTHORITY, this);
+                        }
+                    } catch (RemoteException e) {
+                        // There is nothing sensible to be done here
+                        Log.e(TAG, "problem inserting contact during server update", e);
+                    } catch (OperationApplicationException e) {
+                        // There is nothing sensible to be done here
+                        Log.e(TAG, "problem inserting contact during server update", e);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Given the list of NamedContentValues for an entity, a mime type, and a subtype,
+         * tries to find a match, returning it
+         * @param list the list of NCV's from the contact entity
+         * @param contentItemType the mime type we're looking for
+         * @param type the subtype (e.g. HOME, WORK, etc.)
+         * @return the matching NCV or null if not found
+         */
+        private NamedContentValues findTypedData(ArrayList<NamedContentValues> list,
+                String contentItemType, int type, String stringType) {
+            NamedContentValues result = null;
+
+            // Loop through the ncv's, looking for an existing row
+            for (NamedContentValues namedContentValues: list) {
+                Uri uri = namedContentValues.uri;
+                ContentValues cv = namedContentValues.values;
+                if (Data.CONTENT_URI.equals(uri)) {
+                    String mimeType = cv.getAsString(Data.MIMETYPE);
+                    if (mimeType.equals(contentItemType)) {
+                        if (stringType != null) {
+                            if (cv.getAsString(GroupMembership.GROUP_ROW_ID).equals(stringType)) {
+                                result = namedContentValues;
+                            }
+                        // Note Email.TYPE could be ANY type column; they are all defined in
+                        // the private CommonColumns class in ContactsContract
+                        // We'll accept either type < 0 (don't care), cv doesn't have a type,
+                        // or the types are equal
+                        } else if (type < 0 || !cv.containsKey(Email.TYPE) ||
+                                cv.getAsInteger(Email.TYPE) == type) {
+                            result = namedContentValues;
+                        }
+                    }
+                }
+            }
+
+            // If we've found an existing data row, we'll delete it.  Any rows left at the
+            // end should be deleted...
+            if (result != null) {
+                list.remove(result);
+            }
+
+            // Return the row found (or null)
+            return result;
+        }
+
+        /**
+         * Given the list of NamedContentValues for an entity and a mime type
+         * gather all of the matching NCV's, returning them
+         * @param list the list of NCV's from the contact entity
+         * @param contentItemType the mime type we're looking for
+         * @param type the subtype (e.g. HOME, WORK, etc.)
+         * @return the matching NCVs
+         */
+        private ArrayList<NamedContentValues> findUntypedData(ArrayList<NamedContentValues> list,
+                int type, String contentItemType) {
+            ArrayList<NamedContentValues> result = new ArrayList<NamedContentValues>();
+
+            // Loop through the ncv's, looking for an existing row
+            for (NamedContentValues namedContentValues: list) {
+                Uri uri = namedContentValues.uri;
+                ContentValues cv = namedContentValues.values;
+                if (Data.CONTENT_URI.equals(uri)) {
+                    String mimeType = cv.getAsString(Data.MIMETYPE);
+                    if (mimeType.equals(contentItemType)) {
+                        if (type != -1) {
+                            int subtype = cv.getAsInteger(Phone.TYPE);
+                            if (type != subtype) {
+                                continue;
+                            }
+                        }
+                        result.add(namedContentValues);
+                    }
+                }
+            }
+
+            // If we've found an existing data row, we'll delete it.  Any rows left at the
+            // end should be deleted...
+            for (NamedContentValues values : result) {
+                list.remove(values);
+            }
+
+            // Return the row found (or null)
+            return result;
+        }
+
+        /**
+         * Create a wrapper for a builder (insert or update) that also includes the NCV for
+         * an existing row of this type.   If the SmartBuilder's cv field is not null, then
+         * it represents the current (old) values of this field.  The caller can then check
+         * whether the field is now different and needs to be updated; if it's not different,
+         * the caller will simply return and not generate a new CPO.  Otherwise, the builder
+         * should have its content values set, and the built CPO should be added to the
+         * ContactOperations list.
+         *
+         * @param entity the contact entity (or null if this is a new contact)
+         * @param mimeType the mime type of this row
+         * @param type the subtype of this row
+         * @param stringType for groups, the name of the group (type will be ignored), or null
+         * @return the created SmartBuilder
+         */
+        public RowBuilder createBuilder(Entity entity, String mimeType, int type,
+                String stringType) {
+            RowBuilder builder = null;
+
+            if (entity != null) {
+                NamedContentValues ncv =
+                    findTypedData(entity.getSubValues(), mimeType, type, stringType);
+                if (ncv != null) {
+                    builder = new RowBuilder(
+                            ContentProviderOperation
+                                .newUpdate(addCallerIsSyncAdapterParameter(
+                                    dataUriFromNamedContentValues(ncv))),
+                            ncv);
+                }
+            }
+
+            if (builder == null) {
+                builder = newRowBuilder(entity, mimeType);
+            }
+
+            // Return the appropriate builder (insert or update)
+            // Caller will fill in the appropriate values; 4 MIMETYPE is already set
+            return builder;
+        }
+
+        private RowBuilder typedRowBuilder(Entity entity, String mimeType, int type) {
+            return createBuilder(entity, mimeType, type, null);
+        }
+
+        private RowBuilder untypedRowBuilder(Entity entity, String mimeType) {
+            return createBuilder(entity, mimeType, -1, null);
+        }
+
+        private RowBuilder newRowBuilder(Entity entity, String mimeType) {
+            // This is a new row; first get the contactId
+            // If the Contact is new, use the saved back value; otherwise the value in the entity
+            int contactId = mContactBackValue;
+            if (entity != null) {
+                contactId = entity.getEntityValues().getAsInteger(RawContacts._ID);
+            }
+
+            // Create an insert operation with the proper contactId reference
+            RowBuilder builder =
+                new RowBuilder(ContentProviderOperation.newInsert(
+                        addCallerIsSyncAdapterParameter(Data.CONTENT_URI)));
+            if (entity == null) {
+                builder.withValueBackReference(Data.RAW_CONTACT_ID, contactId);
+            } else {
+                builder.withValue(Data.RAW_CONTACT_ID, contactId);
+            }
+
+            // Set the mime type of the row
+            builder.withValue(Data.MIMETYPE, mimeType);
+            return builder;
+        }
+
+        /**
+         * Compare a column in a ContentValues with an (old) value, and see if they are the
+         * same.  For this purpose, null and an empty string are considered the same.
+         * @param cv a ContentValues object, from a NamedContentValues
+         * @param column a column that might be in the ContentValues
+         * @param oldValue an old value (or null) to check against
+         * @return whether the column's value in the ContentValues matches oldValue
+         */
+        private boolean cvCompareString(ContentValues cv, String column, String oldValue) {
+            if (cv.containsKey(column)) {
+                if (oldValue != null && cv.getAsString(column).equals(oldValue)) {
+                    return true;
+                }
+            } else if (oldValue == null || oldValue.length() == 0) {
+                return true;
+            }
+            return false;
+        }
+
+        public void addChildren(Entity entity, ArrayList<String> children) {
+            RowBuilder builder = untypedRowBuilder(entity, EasChildren.CONTENT_ITEM_TYPE);
+            int i = 0;
+            for (String child: children) {
+                builder.withValue(EasChildren.ROWS[i++], child);
+            }
+            add(builder.build());
+        }
+
+        public void addGroup(Entity entity, String group) {
+            RowBuilder builder =
+                createBuilder(entity, GroupMembership.CONTENT_ITEM_TYPE, -1, group);
+            builder.withValue(GroupMembership.GROUP_SOURCE_ID, group);
+            add(builder.build());
+        }
+
+        public void addBirthday(Entity entity, String birthday) {
+            RowBuilder builder =
+                    typedRowBuilder(entity, Event.CONTENT_ITEM_TYPE, Event.TYPE_BIRTHDAY);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, Event.START_DATE, birthday)) {
+                return;
+            }
+            builder.withValue(Event.START_DATE, birthday);
+            builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY);
+            add(builder.build());
+        }
+
+        public void addName(Entity entity, String prefix, String givenName, String familyName,
+                String middleName, String suffix, String displayName, String yomiFirstName,
+                String yomiLastName, String fileAs) {
+            RowBuilder builder = untypedRowBuilder(entity, StructuredName.CONTENT_ITEM_TYPE);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, StructuredName.GIVEN_NAME, givenName) &&
+                    cvCompareString(cv, StructuredName.FAMILY_NAME, familyName) &&
+                    cvCompareString(cv, StructuredName.MIDDLE_NAME, middleName) &&
+                    cvCompareString(cv, StructuredName.PREFIX, prefix) &&
+                    cvCompareString(cv, StructuredName.PHONETIC_GIVEN_NAME, yomiFirstName) &&
+                    cvCompareString(cv, StructuredName.PHONETIC_FAMILY_NAME, yomiLastName) &&
+                    //cvCompareString(cv, StructuredName.DISPLAY_NAME, fileAs) &&
+                    cvCompareString(cv, StructuredName.SUFFIX, suffix)) {
+                return;
+            }
+            builder.withValue(StructuredName.GIVEN_NAME, givenName);
+            builder.withValue(StructuredName.FAMILY_NAME, familyName);
+            builder.withValue(StructuredName.MIDDLE_NAME, middleName);
+            builder.withValue(StructuredName.SUFFIX, suffix);
+            builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, yomiFirstName);
+            builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, yomiLastName);
+            builder.withValue(StructuredName.PREFIX, prefix);
+            //builder.withValue(StructuredName.DISPLAY_NAME, fileAs);
+            add(builder.build());
+        }
+
+        public void addPersonal(Entity entity, EasPersonal personal) {
+            RowBuilder builder = untypedRowBuilder(entity, EasPersonal.CONTENT_ITEM_TYPE);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, EasPersonal.ANNIVERSARY, personal.anniversary) &&
+                    cvCompareString(cv, EasPersonal.FILE_AS , personal.fileAs)) {
+                return;
+            }
+            if (!personal.hasData()) {
+                return;
+            }
+            builder.withValue(EasPersonal.FILE_AS, personal.fileAs);
+            builder.withValue(EasPersonal.ANNIVERSARY, personal.anniversary);
+            add(builder.build());
+        }
+
+        public void addBusiness(Entity entity, EasBusiness business) {
+            RowBuilder builder = untypedRowBuilder(entity, EasBusiness.CONTENT_ITEM_TYPE);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, EasBusiness.ACCOUNT_NAME, business.accountName) &&
+                    cvCompareString(cv, EasBusiness.CUSTOMER_ID, business.customerId) &&
+                    cvCompareString(cv, EasBusiness.GOVERNMENT_ID, business.governmentId)) {
+                return;
+            }
+            if (!business.hasData()) {
+                return;
+            }
+            builder.withValue(EasBusiness.ACCOUNT_NAME, business.accountName);
+            builder.withValue(EasBusiness.CUSTOMER_ID, business.customerId);
+            builder.withValue(EasBusiness.GOVERNMENT_ID, business.governmentId);
+            add(builder.build());
+        }
+
+        public void addPhoto(Entity entity, String photo) {
+            RowBuilder builder = untypedRowBuilder(entity, Photo.CONTENT_ITEM_TYPE);
+            // We're always going to add this; it's not worth trying to figure out whether the
+            // picture is the same as the one stored.
+            byte[] pic = Base64.decode(photo, Base64.DEFAULT);
+            builder.withValue(Photo.PHOTO, pic);
+            add(builder.build());
+        }
+
+        public void addPhone(Entity entity, int type, String phone) {
+            RowBuilder builder = typedRowBuilder(entity, Phone.CONTENT_ITEM_TYPE, type);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, Phone.NUMBER, phone)) {
+                return;
+            }
+            builder.withValue(Phone.TYPE, type);
+            builder.withValue(Phone.NUMBER, phone);
+            add(builder.build());
+        }
+
+        public void addWebpage(Entity entity, String url) {
+            RowBuilder builder = untypedRowBuilder(entity, Website.CONTENT_ITEM_TYPE);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, Website.URL, url)) {
+                return;
+            }
+            builder.withValue(Website.TYPE, Website.TYPE_WORK);
+            builder.withValue(Website.URL, url);
+            add(builder.build());
+        }
+
+        public void addRelation(Entity entity, int type, String value) {
+            RowBuilder builder = typedRowBuilder(entity, Relation.CONTENT_ITEM_TYPE, type);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, Relation.DATA, value)) {
+                return;
+            }
+            builder.withValue(Relation.TYPE, type);
+            builder.withValue(Relation.DATA, value);
+            add(builder.build());
+        }
+
+        public void addNickname(Entity entity, String name) {
+            RowBuilder builder =
+                typedRowBuilder(entity, Nickname.CONTENT_ITEM_TYPE, Nickname.TYPE_DEFAULT);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, Nickname.NAME, name)) {
+                return;
+            }
+            builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT);
+            builder.withValue(Nickname.NAME, name);
+            add(builder.build());
+        }
+
+        public void addPostal(Entity entity, int type, String street, String city, String state,
+                String country, String code) {
+            RowBuilder builder = typedRowBuilder(entity, StructuredPostal.CONTENT_ITEM_TYPE,
+                    type);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, StructuredPostal.CITY, city) &&
+                    cvCompareString(cv, StructuredPostal.STREET, street) &&
+                    cvCompareString(cv, StructuredPostal.COUNTRY, country) &&
+                    cvCompareString(cv, StructuredPostal.POSTCODE, code) &&
+                    cvCompareString(cv, StructuredPostal.REGION, state)) {
+                return;
+            }
+            builder.withValue(StructuredPostal.TYPE, type);
+            builder.withValue(StructuredPostal.CITY, city);
+            builder.withValue(StructuredPostal.STREET, street);
+            builder.withValue(StructuredPostal.COUNTRY, country);
+            builder.withValue(StructuredPostal.POSTCODE, code);
+            builder.withValue(StructuredPostal.REGION, state);
+            add(builder.build());
+        }
+
+       /**
+         * We now are dealing with up to maxRows typeless rows of mimeType data.  We need to try to
+         * match them with existing rows; if there's a match, everything's great.  Otherwise, we
+         * either need to add a new row for the data, or we have to replace an existing one
+         * that no longer matches.  This is similar to the way Emails are handled.
+         */
+        public void addUntyped(Entity entity, ArrayList<UntypedRow> rows, String mimeType,
+                int type, int maxRows) {
+            // Make a list of all same type rows in the existing entity
+            ArrayList<NamedContentValues> oldValues = EMPTY_ARRAY_NAMEDCONTENTVALUES;
+            ArrayList<NamedContentValues> entityValues = EMPTY_ARRAY_NAMEDCONTENTVALUES;
+            if (entity != null) {
+                oldValues = findUntypedData(entityValues, type, mimeType);
+                entityValues = entity.getSubValues();
+            }
+
+            // These will be rows needing replacement with new values
+            ArrayList<UntypedRow> rowsToReplace = new ArrayList<UntypedRow>();
+
+            // The count of existing rows
+            int numRows = oldValues.size();
+            for (UntypedRow row: rows) {
+                boolean found = false;
+                // If we already have this row, mark it
+                for (NamedContentValues ncv: oldValues) {
+                    ContentValues cv = ncv.values;
+                    String data = cv.getAsString(COMMON_DATA_ROW);
+                    int rowType = -1;
+                    if (cv.containsKey(COMMON_TYPE_ROW)) {
+                        rowType = cv.getAsInteger(COMMON_TYPE_ROW);
+                    }
+                    if (row.isSameAs(rowType, data)) {
+                        cv.put(FOUND_DATA_ROW, true);
+                        // Remove this to indicate it's still being used
+                        entityValues.remove(ncv);
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    // If we don't, there are two possibilities
+                    if (numRows < maxRows) {
+                        // If there are available rows, add a new one
+                        RowBuilder builder = newRowBuilder(entity, mimeType);
+                        row.addValues(builder);
+                        add(builder.build());
+                        numRows++;
+                    } else {
+                        // Otherwise, say we need to replace a row with this
+                        rowsToReplace.add(row);
+                    }
+                }
+            }
+
+            // Go through rows needing replacement
+            for (UntypedRow row: rowsToReplace) {
+                for (NamedContentValues ncv: oldValues) {
+                    ContentValues cv = ncv.values;
+                    // Find a row that hasn't been used (i.e. doesn't match current rows)
+                    if (!cv.containsKey(FOUND_DATA_ROW)) {
+                        // And update it
+                        RowBuilder builder = new RowBuilder(
+                                ContentProviderOperation
+                                    .newUpdate(addCallerIsSyncAdapterParameter(
+                                        dataUriFromNamedContentValues(ncv))),
+                                ncv);
+                        row.addValues(builder);
+                        add(builder.build());
+                    }
+                }
+            }
+        }
+
+        public void addOrganization(Entity entity, int type, String company, String title,
+                String department, String yomiCompanyName, String officeLocation) {
+            RowBuilder builder = typedRowBuilder(entity, Organization.CONTENT_ITEM_TYPE, type);
+            ContentValues cv = builder.cv;
+            if (cv != null && cvCompareString(cv, Organization.COMPANY, company) &&
+                    cvCompareString(cv, Organization.PHONETIC_NAME, yomiCompanyName) &&
+                    cvCompareString(cv, Organization.DEPARTMENT, department) &&
+                    cvCompareString(cv, Organization.TITLE, title) &&
+                    cvCompareString(cv, Organization.OFFICE_LOCATION, officeLocation)) {
+                return;
+            }
+            builder.withValue(Organization.TYPE, type);
+            builder.withValue(Organization.COMPANY, company);
+            builder.withValue(Organization.TITLE, title);
+            builder.withValue(Organization.DEPARTMENT, department);
+            builder.withValue(Organization.PHONETIC_NAME, yomiCompanyName);
+            builder.withValue(Organization.OFFICE_LOCATION, officeLocation);
+            add(builder.build());
+        }
+
+        public void addNote(Entity entity, String note) {
+            RowBuilder builder = typedRowBuilder(entity, Note.CONTENT_ITEM_TYPE, -1);
+            ContentValues cv = builder.cv;
+            if (note == null) return;
+            note = note.replaceAll("\r\n", "\n");
+            if (cv != null && cvCompareString(cv, Note.NOTE, note)) {
+                return;
+            }
+
+            // Reject notes with nothing in them.  Often, we get something from Outlook when
+            // nothing was ever entered.  Sigh.
+            int len = note.length();
+            int i = 0;
+            for (; i < len; i++) {
+                char c = note.charAt(i);
+                if (!Character.isWhitespace(c)) {
+                    break;
+                }
+            }
+            if (i == len) return;
+
+            builder.withValue(Note.NOTE, note);
+            add(builder.build());
+        }
+    }
+
+    /**
+     * Generate the uri for the data row associated with this NamedContentValues object
+     * @param ncv the NamedContentValues object
+     * @return a uri that can be used to refer to this row
+     */
+    public Uri dataUriFromNamedContentValues(NamedContentValues ncv) {
+        long id = ncv.values.getAsLong(RawContacts._ID);
+        Uri dataUri = ContentUris.withAppendedId(ncv.uri, id);
+        return dataUri;
+    }
+
+    @Override
+    public void cleanup() {
+        // Mark the changed contacts dirty = 0
+        // Permanently delete the user deletions
+        ContactOperations ops = new ContactOperations();
+        for (Long id: mUpdatedIdList) {
+            ops.add(ContentProviderOperation
+                    .newUpdate(ContentUris.withAppendedId(RawContacts.CONTENT_URI, id)
+                            .buildUpon()
+                            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+                            .build())
+                    .withValue(RawContacts.DIRTY, 0).build());
+        }
+        for (Long id: mDeletedIdList) {
+            ops.add(ContentProviderOperation
+                    .newDelete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, id)
+                            .buildUpon()
+                            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+                            .build())
+                    .build());
+        }
+        ops.execute();
+        ContentResolver cr = mContext.getContentResolver();
+        if (mGroupsUsed) {
+            // Make sure the title column is set for all of our groups
+            // And that all of our groups are visible
+            // TODO Perhaps the visible part should only happen when the group is created, but
+            // this is fine for now.
+            Uri groupsUri = uriWithAccountAndIsSyncAdapter(Groups.CONTENT_URI);
+            Cursor c = cr.query(groupsUri, new String[] {Groups.SOURCE_ID, Groups.TITLE},
+                    Groups.TITLE + " IS NULL", null, null);
+            ContentValues values = new ContentValues();
+            values.put(Groups.GROUP_VISIBLE, 1);
+            try {
+                while (c.moveToNext()) {
+                    String sourceId = c.getString(0);
+                    values.put(Groups.TITLE, sourceId);
+                    cr.update(uriWithAccountAndIsSyncAdapter(groupsUri), values,
+                            Groups.SOURCE_ID + "=?", new String[] {sourceId});
+                }
+            } finally {
+                c.close();
+            }
+        }
+    }
+
+    @Override
+    public String getCollectionName() {
+        return "Contacts";
+    }
+
+    private void sendEmail(Serializer s, ContentValues cv, int count, String displayName)
+            throws IOException {
+        // Get both parts of the email address (a newly created one in the UI won't have a name)
+        String addr = cv.getAsString(Email.DATA);
+        String name = cv.getAsString(Email.DISPLAY_NAME);
+        if (name == null) {
+            if (displayName != null) {
+                name = displayName;
+            } else {
+                name = addr;
+            }
+        }
+        // Compose address from name and addr
+        if (addr != null) {
+            String value;
+            // Only send the raw email address for EAS 2.5 (Hotmail, in particular, chokes on
+            // an RFC822 address)
+            if (mService.mProtocolVersionDouble < Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+                value = addr;
+            } else {
+                value = '\"' + name + "\" <" + addr + '>';
+            }
+            if (count < MAX_EMAIL_ROWS) {
+                s.data(EMAIL_TAGS[count], value);
+            }
+        }
+    }
+
+    private void sendIm(Serializer s, ContentValues cv, int count) throws IOException {
+        String value = cv.getAsString(Im.DATA);
+        if (value == null) return;
+        if (count < MAX_IM_ROWS) {
+            s.data(IM_TAGS[count], value);
+        }
+    }
+
+    private void sendOnePostal(Serializer s, ContentValues cv, int[] fieldNames)
+            throws IOException{
+        sendStringData(s, cv, StructuredPostal.CITY, fieldNames[0]);
+        sendStringData(s, cv, StructuredPostal.COUNTRY, fieldNames[1]);
+        sendStringData(s, cv, StructuredPostal.POSTCODE, fieldNames[2]);
+        sendStringData(s, cv, StructuredPostal.REGION, fieldNames[3]);
+        sendStringData(s, cv, StructuredPostal.STREET, fieldNames[4]);
+    }
+
+    private void sendStructuredPostal(Serializer s, ContentValues cv) throws IOException {
+        switch (cv.getAsInteger(StructuredPostal.TYPE)) {
+            case StructuredPostal.TYPE_HOME:
+                sendOnePostal(s, cv, HOME_ADDRESS_TAGS);
+                break;
+            case StructuredPostal.TYPE_WORK:
+                sendOnePostal(s, cv, WORK_ADDRESS_TAGS);
+                break;
+            case StructuredPostal.TYPE_OTHER:
+                sendOnePostal(s, cv, OTHER_ADDRESS_TAGS);
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void sendStringData(Serializer s, ContentValues cv, String column, int tag)
+            throws IOException {
+        if (cv.containsKey(column)) {
+            String value = cv.getAsString(column);
+            if (!TextUtils.isEmpty(value)) {
+                s.data(tag, value);
+            }
+        }
+    }
+
+    private String sendStructuredName(Serializer s, ContentValues cv) throws IOException {
+        String displayName = null;
+        sendStringData(s, cv, StructuredName.FAMILY_NAME, Tags.CONTACTS_LAST_NAME);
+        sendStringData(s, cv, StructuredName.GIVEN_NAME, Tags.CONTACTS_FIRST_NAME);
+        sendStringData(s, cv, StructuredName.MIDDLE_NAME, Tags.CONTACTS_MIDDLE_NAME);
+        sendStringData(s, cv, StructuredName.SUFFIX, Tags.CONTACTS_SUFFIX);
+        sendStringData(s, cv, StructuredName.PHONETIC_GIVEN_NAME, Tags.CONTACTS_YOMI_FIRST_NAME);
+        sendStringData(s, cv, StructuredName.PHONETIC_FAMILY_NAME, Tags.CONTACTS_YOMI_LAST_NAME);
+        sendStringData(s, cv, StructuredName.PREFIX, Tags.CONTACTS_TITLE);
+        if (cv.containsKey(StructuredName.DISPLAY_NAME)) {
+            displayName = cv.getAsString(StructuredName.DISPLAY_NAME);
+            if (!TextUtils.isEmpty(displayName)) {
+                s.data(Tags.CONTACTS_FILE_AS, displayName);
+            }
+        }
+        return displayName;
+    }
+
+    private void sendBusiness(Serializer s, ContentValues cv) throws IOException {
+        sendStringData(s, cv, EasBusiness.ACCOUNT_NAME, Tags.CONTACTS2_ACCOUNT_NAME);
+        sendStringData(s, cv, EasBusiness.CUSTOMER_ID, Tags.CONTACTS2_CUSTOMER_ID);
+        sendStringData(s, cv, EasBusiness.GOVERNMENT_ID, Tags.CONTACTS2_GOVERNMENT_ID);
+    }
+
+    private void sendPersonal(Serializer s, ContentValues cv) throws IOException {
+        sendStringData(s, cv, EasPersonal.ANNIVERSARY, Tags.CONTACTS_ANNIVERSARY);
+        sendStringData(s, cv, EasPersonal.FILE_AS, Tags.CONTACTS_FILE_AS);
+    }
+
+    private void sendBirthday(Serializer s, ContentValues cv) throws IOException {
+        sendStringData(s, cv, Event.START_DATE, Tags.CONTACTS_BIRTHDAY);
+    }
+
+    private void sendPhoto(Serializer s, ContentValues cv) throws IOException {
+        if (cv.containsKey(Photo.PHOTO)) {
+            byte[] bytes = cv.getAsByteArray(Photo.PHOTO);
+            String pic = Base64.encodeToString(bytes, Base64.NO_WRAP);
+            s.data(Tags.CONTACTS_PICTURE, pic);
+        } else {
+            // Send an empty tag, which signals the server to delete any pre-existing photo
+            s.tag(Tags.CONTACTS_PICTURE);
+        }
+    }
+
+    private void sendOrganization(Serializer s, ContentValues cv) throws IOException {
+        sendStringData(s, cv, Organization.TITLE, Tags.CONTACTS_JOB_TITLE);
+        sendStringData(s, cv, Organization.COMPANY, Tags.CONTACTS_COMPANY_NAME);
+        sendStringData(s, cv, Organization.DEPARTMENT, Tags.CONTACTS_DEPARTMENT);
+        sendStringData(s, cv, Organization.OFFICE_LOCATION, Tags.CONTACTS_OFFICE_LOCATION);
+    }
+
+    private void sendNickname(Serializer s, ContentValues cv) throws IOException {
+        sendStringData(s, cv, Nickname.NAME, Tags.CONTACTS2_NICKNAME);
+    }
+
+    private void sendWebpage(Serializer s, ContentValues cv) throws IOException {
+        sendStringData(s, cv, Website.URL, Tags.CONTACTS_WEBPAGE);
+    }
+
+    private void sendNote(Serializer s, ContentValues cv) throws IOException {
+        // Even when there is no local note, we must explicitly upsync an empty note,
+        // which is the only way to force the server to delete any pre-existing note.
+        String note = "";
+        if (cv.containsKey(Note.NOTE)) {
+            // EAS won't accept note data with raw newline characters
+            note = cv.getAsString(Note.NOTE).replaceAll("\n", "\r\n");
+        }
+        // Format of upsync data depends on protocol version
+        if (mService.mProtocolVersionDouble >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
+            s.start(Tags.BASE_BODY);
+            s.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_TEXT).data(Tags.BASE_DATA, note);
+            s.end();
+        } else {
+            s.data(Tags.CONTACTS_BODY, note);
+        }
+    }
+
+    private void sendChildren(Serializer s, ContentValues cv) throws IOException {
+        boolean first = true;
+        for (int i = 0; i < EasChildren.MAX_CHILDREN; i++) {
+            String row = EasChildren.ROWS[i];
+            if (cv.containsKey(row)) {
+                if (first) {
+                    s.start(Tags.CONTACTS_CHILDREN);
+                    first = false;
+                }
+                s.data(Tags.CONTACTS_CHILD, cv.getAsString(row));
+            }
+        }
+        if (!first) {
+            s.end();
+        }
+    }
+
+    private void sendPhone(Serializer s, ContentValues cv, int workCount, int homeCount)
+            throws IOException {
+        String value = cv.getAsString(Phone.NUMBER);
+        if (value == null) return;
+        switch (cv.getAsInteger(Phone.TYPE)) {
+            case Phone.TYPE_WORK:
+                if (workCount < MAX_PHONE_ROWS) {
+                    s.data(WORK_PHONE_TAGS[workCount], value);
+                }
+                break;
+            case Phone.TYPE_MMS:
+                s.data(Tags.CONTACTS2_MMS, value);
+                break;
+            case Phone.TYPE_ASSISTANT:
+                s.data(Tags.CONTACTS_ASSISTANT_TELEPHONE_NUMBER, value);
+                break;
+            case Phone.TYPE_FAX_WORK:
+                s.data(Tags.CONTACTS_BUSINESS_FAX_NUMBER, value);
+                break;
+            case Phone.TYPE_COMPANY_MAIN:
+                s.data(Tags.CONTACTS2_COMPANY_MAIN_PHONE, value);
+                break;
+            case Phone.TYPE_HOME:
+                if (homeCount < MAX_PHONE_ROWS) {
+                    s.data(HOME_PHONE_TAGS[homeCount], value);
+                }
+                break;
+            case Phone.TYPE_MOBILE:
+                s.data(Tags.CONTACTS_MOBILE_TELEPHONE_NUMBER, value);
+                break;
+            case Phone.TYPE_CAR:
+                s.data(Tags.CONTACTS_CAR_TELEPHONE_NUMBER, value);
+                break;
+            case Phone.TYPE_PAGER:
+                s.data(Tags.CONTACTS_PAGER_NUMBER, value);
+                break;
+            case Phone.TYPE_RADIO:
+                s.data(Tags.CONTACTS_RADIO_TELEPHONE_NUMBER, value);
+                break;
+            case Phone.TYPE_FAX_HOME:
+                s.data(Tags.CONTACTS_HOME_FAX_NUMBER, value);
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void sendRelation(Serializer s, ContentValues cv) throws IOException {
+        String value = cv.getAsString(Relation.DATA);
+        if (value == null) return;
+        switch (cv.getAsInteger(Relation.TYPE)) {
+            case Relation.TYPE_ASSISTANT:
+                s.data(Tags.CONTACTS_ASSISTANT_NAME, value);
+                break;
+            case Relation.TYPE_MANAGER:
+                s.data(Tags.CONTACTS2_MANAGER_NAME, value);
+                break;
+            case Relation.TYPE_SPOUSE:
+                s.data(Tags.CONTACTS_SPOUSE, value);
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void dirtyContactsWithinDirtyGroups() {
+        ContentResolver cr = mService.mContentResolver;
+        Cursor c = cr.query(uriWithAccountAndIsSyncAdapter(Groups.CONTENT_URI),
+                GROUPS_ID_PROJECTION, Groups.DIRTY + "=1", null, null);
+        try {
+            if (c.getCount() > 0) {
+                String[] updateArgs = new String[1];
+                ContentValues updateValues = new ContentValues();
+                while (c.moveToNext()) {
+                    // For each, "touch" all data rows with this group id; this will mark contacts
+                    // in this group as dirty (per ContactsContract).  We will then know to upload
+                    // them to the server with the modified group information
+                    long id = c.getLong(0);
+                    updateValues.put(GroupMembership.GROUP_ROW_ID, id);
+                    updateArgs[0] = Long.toString(id);
+                    cr.update(Data.CONTENT_URI, updateValues,
+                            MIMETYPE_GROUP_MEMBERSHIP_AND_ID_EQUALS, updateArgs);
+                }
+                // Really delete groups that are marked deleted
+                cr.delete(uriWithAccountAndIsSyncAdapter(Groups.CONTENT_URI), Groups.DELETED + "=1",
+                        null);
+                // Clear the dirty flag for all of our groups
+                updateValues.clear();
+                updateValues.put(Groups.DIRTY, 0);
+                cr.update(uriWithAccountAndIsSyncAdapter(Groups.CONTENT_URI), updateValues, null,
+                        null);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    @Override
+    public boolean sendLocalChanges(Serializer s) throws IOException {
+        ContentResolver cr = mService.mContentResolver;
+
+        // Find any groups of ours that are dirty and dirty those groups' members
+        dirtyContactsWithinDirtyGroups();
+
+        // First, let's find Contacts that have changed.
+        Uri uri = uriWithAccountAndIsSyncAdapter(RawContactsEntity.CONTENT_URI);
+        if (getSyncKey().equals("0")) {
+            return false;
+        }
+
+        // Get them all atomically
+        EntityIterator ei = RawContacts.newEntityIterator(
+                cr.query(uri, null, RawContacts.DIRTY + "=1", null, null));
+        ContentValues cidValues = new ContentValues();
+        try {
+            boolean first = true;
+            final Uri rawContactUri = addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI);
+            while (ei.hasNext()) {
+                Entity entity = ei.next();
+                // For each of these entities, create the change commands
+                ContentValues entityValues = entity.getEntityValues();
+                String serverId = entityValues.getAsString(RawContacts.SOURCE_ID);
+                ArrayList<Integer> groupIds = new ArrayList<Integer>();
+                if (first) {
+                    s.start(Tags.SYNC_COMMANDS);
+                    userLog("Sending Contacts changes to the server");
+                    first = false;
+                }
+                if (serverId == null) {
+                    // This is a new contact; create a clientId
+                    String clientId = "new_" + mMailbox.mId + '_' + System.currentTimeMillis();
+                    userLog("Creating new contact with clientId: ", clientId);
+                    s.start(Tags.SYNC_ADD).data(Tags.SYNC_CLIENT_ID, clientId);
+                    // And save it in the raw contact
+                    cidValues.put(RawContacts.SYNC1, clientId);
+                    cr.update(ContentUris.
+                            withAppendedId(rawContactUri,
+                                    entityValues.getAsLong(RawContacts._ID)),
+                                    cidValues, null, null);
+                } else {
+                    if (entityValues.getAsInteger(RawContacts.DELETED) == 1) {
+                        userLog("Deleting contact with serverId: ", serverId);
+                        s.start(Tags.SYNC_DELETE).data(Tags.SYNC_SERVER_ID, serverId).end();
+                        mDeletedIdList.add(entityValues.getAsLong(RawContacts._ID));
+                        continue;
+                    }
+                    userLog("Upsync change to contact with serverId: " + serverId);
+                    s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, serverId);
+                }
+                s.start(Tags.SYNC_APPLICATION_DATA);
+                // Write out the data here
+                int imCount = 0;
+                int emailCount = 0;
+                int homePhoneCount = 0;
+                int workPhoneCount = 0;
+                String displayName = null;
+                ArrayList<ContentValues> emailValues = new ArrayList<ContentValues>();
+                for (NamedContentValues ncv: entity.getSubValues()) {
+                    ContentValues cv = ncv.values;
+                    String mimeType = cv.getAsString(Data.MIMETYPE);
+                    if (mimeType.equals(Email.CONTENT_ITEM_TYPE)) {
+                        emailValues.add(cv);
+                    } else if (mimeType.equals(Nickname.CONTENT_ITEM_TYPE)) {
+                        sendNickname(s, cv);
+                    } else if (mimeType.equals(EasChildren.CONTENT_ITEM_TYPE)) {
+                        sendChildren(s, cv);
+                    } else if (mimeType.equals(EasBusiness.CONTENT_ITEM_TYPE)) {
+                        sendBusiness(s, cv);
+                    } else if (mimeType.equals(Website.CONTENT_ITEM_TYPE)) {
+                        sendWebpage(s, cv);
+                    } else if (mimeType.equals(EasPersonal.CONTENT_ITEM_TYPE)) {
+                        sendPersonal(s, cv);
+                    } else if (mimeType.equals(Phone.CONTENT_ITEM_TYPE)) {
+                        sendPhone(s, cv, workPhoneCount, homePhoneCount);
+                        int type = cv.getAsInteger(Phone.TYPE);
+                        if (type == Phone.TYPE_HOME) homePhoneCount++;
+                        if (type == Phone.TYPE_WORK) workPhoneCount++;
+                    } else if (mimeType.equals(Relation.CONTENT_ITEM_TYPE)) {
+                        sendRelation(s, cv);
+                    } else if (mimeType.equals(StructuredName.CONTENT_ITEM_TYPE)) {
+                        displayName = sendStructuredName(s, cv);
+                    } else if (mimeType.equals(StructuredPostal.CONTENT_ITEM_TYPE)) {
+                        sendStructuredPostal(s, cv);
+                    } else if (mimeType.equals(Organization.CONTENT_ITEM_TYPE)) {
+                        sendOrganization(s, cv);
+                    } else if (mimeType.equals(Im.CONTENT_ITEM_TYPE)) {
+                        sendIm(s, cv, imCount++);
+                    } else if (mimeType.equals(Event.CONTENT_ITEM_TYPE)) {
+                        Integer eventType = cv.getAsInteger(Event.TYPE);
+                        if (eventType != null && eventType.equals(Event.TYPE_BIRTHDAY)) {
+                            sendBirthday(s, cv);
+                        }
+                    } else if (mimeType.equals(GroupMembership.CONTENT_ITEM_TYPE)) {
+                        // We must gather these, and send them together (below)
+                        groupIds.add(cv.getAsInteger(GroupMembership.GROUP_ROW_ID));
+                    } else if (mimeType.equals(Note.CONTENT_ITEM_TYPE)) {
+                        sendNote(s, cv);
+                    } else if (mimeType.equals(Photo.CONTENT_ITEM_TYPE)) {
+                        sendPhoto(s, cv);
+                    } else {
+                        userLog("Contacts upsync, unknown data: ", mimeType);
+                    }
+                }
+
+                // We do the email rows last, because we need to make sure we've found the
+                // displayName (if one exists); this would be in a StructuredName rnow
+                for (ContentValues cv: emailValues) {
+                    sendEmail(s, cv, emailCount++, displayName);
+                }
+
+                // Now, we'll send up groups, if any
+                if (!groupIds.isEmpty()) {
+                    boolean groupFirst = true;
+                    for (int id: groupIds) {
+                        // Since we get id's from the provider, we need to find their names
+                        Cursor c = cr.query(ContentUris.withAppendedId(Groups.CONTENT_URI, id),
+                                GROUP_TITLE_PROJECTION, null, null, null);
+                        try {
+                            // Presumably, this should always succeed, but ...
+                            if (c.moveToFirst()) {
+                                if (groupFirst) {
+                                    s.start(Tags.CONTACTS_CATEGORIES);
+                                    groupFirst = false;
+                                }
+                                s.data(Tags.CONTACTS_CATEGORY, c.getString(0));
+                            }
+                        } finally {
+                            c.close();
+                        }
+                    }
+                    if (!groupFirst) {
+                        s.end();
+                    }
+                }
+                s.end().end(); // ApplicationData & Change
+                mUpdatedIdList.add(entityValues.getAsLong(RawContacts._ID));
+            }
+            if (!first) {
+                s.end(); // Commands
+            }
+        } finally {
+            ei.close();
+        }
+
+        return false;
+    }
+}
diff --git a/exchange2_src/com/android/exchange/adapter/EmailSyncAdapter.java b/exchange2/src/com/android/exchange/adapter/EmailSyncAdapter.java
similarity index 100%
rename from exchange2_src/com/android/exchange/adapter/EmailSyncAdapter.java
rename to exchange2/src/com/android/exchange/adapter/EmailSyncAdapter.java
diff --git a/exchange2/src/com/android/exchange/adapter/FolderSyncParser.java b/exchange2/src/com/android/exchange/adapter/FolderSyncParser.java
new file mode 100644
index 0000000..3b0bc7c
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.os.RemoteException;
+import android.text.TextUtils;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.service.SyncWindow;
+import com.android.emailcommon.utility.AttachmentUtilities;
+import com.android.emailcommon.utility.EmailAsyncTask;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.CommandStatusException.CommandStatus;
+import com.android.exchange.Eas;
+import com.android.exchange.ExchangeService;
+import com.android.exchange.provider.MailboxUtilities;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Parse the result of a FolderSync command
+ *
+ * Handles the addition, deletion, and changes to folders in the user's Exchange account.
+ **/
+
+public class FolderSyncParser extends AbstractSyncParser {
+
+    public static final String TAG = "FolderSyncParser";
+
+    // These are defined by the EAS protocol
+    public static final int USER_GENERIC_TYPE = 1;
+    public static final int INBOX_TYPE = 2;
+    public static final int DRAFTS_TYPE = 3;
+    public static final int DELETED_TYPE = 4;
+    public static final int SENT_TYPE = 5;
+    public static final int OUTBOX_TYPE = 6;
+    public static final int TASKS_TYPE = 7;
+    public static final int CALENDAR_TYPE = 8;
+    public static final int CONTACTS_TYPE = 9;
+    public static final int NOTES_TYPE = 10;
+    public static final int JOURNAL_TYPE = 11;
+    public static final int USER_MAILBOX_TYPE = 12;
+
+    // Chunk size for our mailbox commits
+    public final static int MAILBOX_COMMIT_SIZE = 20;
+
+    // EAS types that we are willing to consider valid folders for EAS sync
+    public static final List<Integer> VALID_EAS_FOLDER_TYPES = Arrays.asList(INBOX_TYPE,
+            DRAFTS_TYPE, DELETED_TYPE, SENT_TYPE, OUTBOX_TYPE, USER_MAILBOX_TYPE, CALENDAR_TYPE,
+            CONTACTS_TYPE, USER_GENERIC_TYPE);
+
+    public static final String ALL_BUT_ACCOUNT_MAILBOX = MailboxColumns.ACCOUNT_KEY + "=? and " +
+        MailboxColumns.TYPE + "!=" + Mailbox.TYPE_EAS_ACCOUNT_MAILBOX;
+
+    private static final String WHERE_SERVER_ID_AND_ACCOUNT = MailboxColumns.SERVER_ID + "=? and " +
+        MailboxColumns.ACCOUNT_KEY + "=?";
+
+    private static final String WHERE_DISPLAY_NAME_AND_ACCOUNT = MailboxColumns.DISPLAY_NAME +
+        "=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
+
+    private static final String WHERE_PARENT_SERVER_ID_AND_ACCOUNT =
+        MailboxColumns.PARENT_SERVER_ID +"=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
+
+    private static final String[] MAILBOX_ID_COLUMNS_PROJECTION =
+        new String[] {MailboxColumns.ID, MailboxColumns.SERVER_ID, MailboxColumns.PARENT_SERVER_ID};
+    private static final int MAILBOX_ID_COLUMNS_ID = 0;
+    private static final int MAILBOX_ID_COLUMNS_SERVER_ID = 1;
+    private static final int MAILBOX_ID_COLUMNS_PARENT_SERVER_ID = 2;
+
+    @VisibleForTesting
+    long mAccountId;
+    @VisibleForTesting
+    String mAccountIdAsString;
+    @VisibleForTesting
+    boolean mInUnitTest = false;
+
+    private String[] mBindArguments = new String[2];
+    private ArrayList<ContentProviderOperation> mOperations =
+        new ArrayList<ContentProviderOperation>();
+    private boolean mInitialSync;
+    private ArrayList<String> mParentFixupsNeeded = new ArrayList<String>();
+    private boolean mFixupUninitializedNeeded = false;
+    // If true, we only care about status (this is true when validating an account) and ignore
+    // other data
+    private final boolean mStatusOnly;
+
+    private static final ContentValues UNINITIALIZED_PARENT_KEY = new ContentValues();
+
+    {
+        UNINITIALIZED_PARENT_KEY.put(MailboxColumns.PARENT_KEY, Mailbox.PARENT_KEY_UNINITIALIZED);
+    }
+
+    public FolderSyncParser(InputStream in, AbstractSyncAdapter adapter) throws IOException {
+        this(in, adapter, false);
+    }
+
+    public FolderSyncParser(InputStream in, AbstractSyncAdapter adapter, boolean statusOnly)
+            throws IOException {
+        super(in, adapter);
+        mAccountId = mAccount.mId;
+        mAccountIdAsString = Long.toString(mAccountId);
+        mStatusOnly = statusOnly;
+    }
+
+    @Override
+    public boolean parse() throws IOException, CommandStatusException {
+        int status;
+        boolean res = false;
+        boolean resetFolders = false;
+        // Since we're now (potentially) committing mailboxes in chunks, ensure that we start with
+        // only the account mailbox
+        String key = mAccount.mSyncKey;
+        mInitialSync = (key == null) || "0".equals(key);
+        if (mInitialSync) {
+            mContentResolver.delete(Mailbox.CONTENT_URI, ALL_BUT_ACCOUNT_MAILBOX,
+                    new String[] {Long.toString(mAccountId)});
+        }
+        if (nextTag(START_DOCUMENT) != Tags.FOLDER_FOLDER_SYNC)
+            throw new EasParserException();
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.FOLDER_STATUS) {
+                status = getValueInt();
+                if (status != Eas.FOLDER_STATUS_OK) {
+                    mService.errorLog("FolderSync failed: " + CommandStatus.toString(status));
+                    // If the account hasn't been saved, this is a validation attempt, so we don't
+                    // try reloading the folder list...
+                    if (CommandStatus.isDeniedAccess(status) ||
+                            CommandStatus.isNeedsProvisioning(status) ||
+                            (mAccount.mId == Account.NOT_SAVED)) {
+                        throw new CommandStatusException(status);
+                    // Note that we need to catch both old-style (Eas.FOLDER_STATUS_INVALID_KEY)
+                    // and EAS 14 style command status
+                    } else if (status == Eas.FOLDER_STATUS_INVALID_KEY ||
+                            CommandStatus.isBadSyncKey(status)) {
+                        mService.errorLog("Bad sync key; RESET and delete all folders");
+                        // Reset the sync key and save
+                        mAccount.mSyncKey = "0";
+                        ContentValues cv = new ContentValues();
+                        cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
+                        mContentResolver.update(ContentUris.withAppendedId(Account.CONTENT_URI,
+                                mAccount.mId), cv, null, null);
+                        // Delete PIM data
+                        ExchangeService.deleteAccountPIMData(mAccountId);
+                        // Save away any mailbox sync information that is NOT default
+                        saveMailboxSyncOptions();
+                        // And only then, delete mailboxes
+                        mContentResolver.delete(Mailbox.CONTENT_URI, ALL_BUT_ACCOUNT_MAILBOX,
+                                new String[] {Long.toString(mAccountId)});
+                        // Stop existing syncs and reconstruct _main
+                        ExchangeService.stopNonAccountMailboxSyncsForAccount(mAccountId);
+                        res = true;
+                        resetFolders = true;
+                    } else {
+                        // Other errors are at the server, so let's throw an error that will
+                        // cause this sync to be retried at a later time
+                        mService.errorLog("Throwing IOException; will retry later");
+                        throw new EasParserException("Folder status error");
+                    }
+                }
+            } else if (tag == Tags.FOLDER_SYNC_KEY) {
+                mAccount.mSyncKey = getValue();
+                userLog("New Account SyncKey: ", mAccount.mSyncKey);
+            } else if (tag == Tags.FOLDER_CHANGES) {
+                if (mStatusOnly) return res;
+                changesParser(mOperations, mInitialSync);
+            } else
+                skipTag();
+        }
+        if (mStatusOnly) return res;
+        synchronized (mService.getSynchronizer()) {
+            if (!mService.isStopped() || resetFolders) {
+                commit();
+                userLog("Leaving FolderSyncParser with Account syncKey=", mAccount.mSyncKey);
+            }
+        }
+        return res;
+    }
+
+    private Cursor getServerIdCursor(String serverId) {
+        mBindArguments[0] = serverId;
+        mBindArguments[1] = mAccountIdAsString;
+        return mContentResolver.query(Mailbox.CONTENT_URI, MAILBOX_ID_COLUMNS_PROJECTION,
+                WHERE_SERVER_ID_AND_ACCOUNT, mBindArguments, null);
+    }
+
+    public void deleteParser(ArrayList<ContentProviderOperation> ops) throws IOException {
+        while (nextTag(Tags.FOLDER_DELETE) != END) {
+            switch (tag) {
+                case Tags.FOLDER_SERVER_ID:
+                    String serverId = getValue();
+                    // Find the mailbox in this account with the given serverId
+                    Cursor c = getServerIdCursor(serverId);
+                    try {
+                        if (c.moveToFirst()) {
+                            userLog("Deleting ", serverId);
+                            ops.add(ContentProviderOperation.newDelete(
+                                    ContentUris.withAppendedId(Mailbox.CONTENT_URI,
+                                            c.getLong(MAILBOX_ID_COLUMNS_ID))).build());
+                            AttachmentUtilities.deleteAllMailboxAttachmentFiles(mContext,
+                                    mAccountId, mMailbox.mId);
+                            if (!mInitialSync) {
+                                String parentId = c.getString(MAILBOX_ID_COLUMNS_PARENT_SERVER_ID);
+                                if (!TextUtils.isEmpty(parentId)) {
+                                    mParentFixupsNeeded.add(parentId);
+                                }
+                            }
+                        }
+                    } finally {
+                        c.close();
+                    }
+                    break;
+                default:
+                    skipTag();
+            }
+        }
+    }
+
+    private static class SyncOptions {
+        private final int mInterval;
+        private final int mLookback;
+
+        private SyncOptions(int interval, int lookback) {
+            mInterval = interval;
+            mLookback = lookback;
+        }
+    }
+
+    private static final String MAILBOX_STATE_SELECTION =
+        MailboxColumns.ACCOUNT_KEY + "=? AND (" + MailboxColumns.SYNC_INTERVAL + "!=" +
+            Account.CHECK_INTERVAL_NEVER + " OR " + Mailbox.SYNC_LOOKBACK + "!=" +
+            SyncWindow.SYNC_WINDOW_UNKNOWN + ")";
+
+    private static final String[] MAILBOX_STATE_PROJECTION = new String[] {
+        MailboxColumns.SERVER_ID, MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_LOOKBACK};
+    private static final int MAILBOX_STATE_SERVER_ID = 0;
+    private static final int MAILBOX_STATE_INTERVAL = 1;
+    private static final int MAILBOX_STATE_LOOKBACK = 2;
+    @VisibleForTesting
+    final HashMap<String, SyncOptions> mSyncOptionsMap = new HashMap<String, SyncOptions>();
+
+    /**
+     * For every mailbox in this account that has a non-default interval or lookback, save those
+     * values.
+     */
+    @VisibleForTesting
+    void saveMailboxSyncOptions() {
+        // Shouldn't be necessary, but...
+        mSyncOptionsMap.clear();
+        Cursor c = mContentResolver.query(Mailbox.CONTENT_URI, MAILBOX_STATE_PROJECTION,
+                MAILBOX_STATE_SELECTION, new String[] {mAccountIdAsString}, null);
+        if (c != null) {
+            try {
+                while (c.moveToNext()) {
+                    mSyncOptionsMap.put(c.getString(MAILBOX_STATE_SERVER_ID),
+                            new SyncOptions(c.getInt(MAILBOX_STATE_INTERVAL),
+                                    c.getInt(MAILBOX_STATE_LOOKBACK)));
+                }
+            } finally {
+                c.close();
+            }
+        }
+    }
+
+    /**
+     * For every set of saved mailbox sync options, try to find and restore those values
+     */
+    @VisibleForTesting
+    void restoreMailboxSyncOptions() {
+        try {
+            ContentValues cv = new ContentValues();
+            mBindArguments[1] = mAccountIdAsString;
+            for (String serverId: mSyncOptionsMap.keySet()) {
+                SyncOptions options = mSyncOptionsMap.get(serverId);
+                cv.put(MailboxColumns.SYNC_INTERVAL, options.mInterval);
+                cv.put(MailboxColumns.SYNC_LOOKBACK, options.mLookback);
+                mBindArguments[0] = serverId;
+                // If we match account and server id, set the sync options
+                mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_SERVER_ID_AND_ACCOUNT,
+                        mBindArguments);
+            }
+        } finally {
+            mSyncOptionsMap.clear();
+        }
+    }
+
+    public Mailbox addParser() throws IOException {
+        String name = null;
+        String serverId = null;
+        String parentId = null;
+        int type = 0;
+
+        while (nextTag(Tags.FOLDER_ADD) != END) {
+            switch (tag) {
+                case Tags.FOLDER_DISPLAY_NAME: {
+                    name = getValue();
+                    break;
+                }
+                case Tags.FOLDER_TYPE: {
+                    type = getValueInt();
+                    break;
+                }
+                case Tags.FOLDER_PARENT_ID: {
+                    parentId = getValue();
+                    break;
+                }
+                case Tags.FOLDER_SERVER_ID: {
+                    serverId = getValue();
+                    break;
+                }
+                default:
+                    skipTag();
+            }
+        }
+
+        if (VALID_EAS_FOLDER_TYPES.contains(type)) {
+            Mailbox mailbox = new Mailbox();
+            mailbox.mDisplayName = name;
+            mailbox.mServerId = serverId;
+            mailbox.mAccountKey = mAccountId;
+            mailbox.mType = Mailbox.TYPE_MAIL;
+            // Note that all mailboxes default to checking "never" (i.e. manual sync only)
+            // We set specific intervals for inbox, contacts, and (eventually) calendar
+            mailbox.mSyncInterval = Mailbox.CHECK_INTERVAL_NEVER;
+            switch (type) {
+                case INBOX_TYPE:
+                    mailbox.mType = Mailbox.TYPE_INBOX;
+                    mailbox.mSyncInterval = mAccount.mSyncInterval;
+                    break;
+                case CONTACTS_TYPE:
+                    mailbox.mType = Mailbox.TYPE_CONTACTS;
+                    mailbox.mSyncInterval = mAccount.mSyncInterval;
+                    break;
+                case OUTBOX_TYPE:
+                    // TYPE_OUTBOX mailboxes are known by ExchangeService to sync whenever they
+                    // aren't empty.  The value of mSyncFrequency is ignored for this kind of
+                    // mailbox.
+                    mailbox.mType = Mailbox.TYPE_OUTBOX;
+                    break;
+                case SENT_TYPE:
+                    mailbox.mType = Mailbox.TYPE_SENT;
+                    break;
+                case DRAFTS_TYPE:
+                    mailbox.mType = Mailbox.TYPE_DRAFTS;
+                    break;
+                case DELETED_TYPE:
+                    mailbox.mType = Mailbox.TYPE_TRASH;
+                    break;
+                case CALENDAR_TYPE:
+                    mailbox.mType = Mailbox.TYPE_CALENDAR;
+                    mailbox.mSyncInterval = mAccount.mSyncInterval;
+                    break;
+                case USER_GENERIC_TYPE:
+                    mailbox.mType = Mailbox.TYPE_UNKNOWN;
+                    break;
+            }
+
+            // Make boxes like Contacts and Calendar invisible in the folder list
+            mailbox.mFlagVisible = (mailbox.mType < Mailbox.TYPE_NOT_EMAIL);
+
+            if (!parentId.equals("0")) {
+                mailbox.mParentServerId = parentId;
+                if (!mInitialSync) {
+                    mParentFixupsNeeded.add(parentId);
+                }
+            }
+            // At the least, we'll need to set flags
+            mFixupUninitializedNeeded = true;
+
+            return mailbox;
+        }
+        return null;
+    }
+
+    /**
+     * Determine whether a given mailbox holds mail, rather than other data.  We do this by first
+     * checking the type of the mailbox (if it's a known good type, great; if it's a known bad
+     * type, return false).  If it's unknown, we check the parent, first by trying to find it in
+     * the current set of newly synced items, and then by looking it up in EmailProvider.  If
+     * we can find the parent, we use the same rules to determine if it holds mail; if it does,
+     * then its children do as well, so that's a go.
+     *
+     * @param mailbox the mailbox we're checking
+     * @param mailboxMap a HashMap relating server id's of mailboxes in the current sync set to
+     * the corresponding mailbox structures
+     * @return whether or not the mailbox contains email (rather than PIM or unknown data)
+     */
+    /*package*/ boolean isValidMailFolder(Mailbox mailbox, HashMap<String, Mailbox> mailboxMap) {
+        int folderType = mailbox.mType;
+        // Automatically accept our email types
+        if (folderType < Mailbox.TYPE_NOT_EMAIL) return true;
+        // Automatically reject everything else but "unknown"
+        if (folderType != Mailbox.TYPE_UNKNOWN) return false;
+        // If this is TYPE_UNKNOWN, check the parent
+        Mailbox parent = mailboxMap.get(mailbox.mParentServerId);
+        // If the parent is in the map, then check it out; if not, it could be an existing saved
+        // Mailbox, so we'll have to query the database
+        if (parent == null) {
+            mBindArguments[0] = Long.toString(mAccount.mId);
+            mBindArguments[1] = mailbox.mParentServerId;
+            long parentId = Utility.getFirstRowInt(mContext, Mailbox.CONTENT_URI,
+                    EmailContent.ID_PROJECTION,
+                    MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.SERVER_ID + "=?",
+                    mBindArguments, null, EmailContent.ID_PROJECTION_COLUMN, -1);
+            if (parentId != -1) {
+                // Get the parent from the database
+                parent = Mailbox.restoreMailboxWithId(mContext, parentId);
+                if (parent == null) return false;
+            } else {
+                return false;
+            }
+        }
+        return isValidMailFolder(parent, mailboxMap);
+    }
+
+    public void updateParser(ArrayList<ContentProviderOperation> ops) throws IOException {
+        String serverId = null;
+        String displayName = null;
+        String parentId = null;
+        while (nextTag(Tags.FOLDER_UPDATE) != END) {
+            switch (tag) {
+                case Tags.FOLDER_SERVER_ID:
+                    serverId = getValue();
+                    break;
+                case Tags.FOLDER_DISPLAY_NAME:
+                    displayName = getValue();
+                    break;
+                case Tags.FOLDER_PARENT_ID:
+                    parentId = getValue();
+                    break;
+                default:
+                    skipTag();
+                    break;
+            }
+        }
+        // We'll make a change if one of parentId or displayName are specified
+        // serverId is required, but let's be careful just the same
+        if (serverId != null && (displayName != null || parentId != null)) {
+            Cursor c = getServerIdCursor(serverId);
+            try {
+                // If we find the mailbox (using serverId), make the change
+                if (c.moveToFirst()) {
+                    userLog("Updating ", serverId);
+                    // Fix up old and new parents, as needed
+                    if (!TextUtils.isEmpty(parentId)) {
+                        mParentFixupsNeeded.add(parentId);
+                    }
+                    String oldParentId = c.getString(MAILBOX_ID_COLUMNS_PARENT_SERVER_ID);
+                    if (!TextUtils.isEmpty(oldParentId)) {
+                        mParentFixupsNeeded.add(oldParentId);
+                    }
+                    // Set display name if we've got one
+                    ContentValues cv = new ContentValues();
+                    if (displayName != null) {
+                        cv.put(Mailbox.DISPLAY_NAME, displayName);
+                    }
+                    // Save away the server id and uninitialize the parent key
+                    cv.put(Mailbox.PARENT_SERVER_ID, parentId);
+                    // Clear the parent key; it will be fixed up after the commit
+                    cv.put(Mailbox.PARENT_KEY, Mailbox.PARENT_KEY_UNINITIALIZED);
+                    ops.add(ContentProviderOperation.newUpdate(
+                            ContentUris.withAppendedId(Mailbox.CONTENT_URI,
+                                    c.getLong(MAILBOX_ID_COLUMNS_ID))).withValues(cv).build());
+                    // Say we need to fixup uninitialized mailboxes
+                    mFixupUninitializedNeeded = true;
+                }
+            } finally {
+                c.close();
+            }
+        }
+    }
+
+    private boolean commitMailboxes(ArrayList<Mailbox> validMailboxes,
+            ArrayList<Mailbox> userMailboxes, HashMap<String, Mailbox> mailboxMap,
+            ArrayList<ContentProviderOperation> ops) {
+
+        // Go through the generic user mailboxes; we'll call them valid if any parent is valid
+        for (Mailbox m: userMailboxes) {
+            if (isValidMailFolder(m, mailboxMap)) {
+                m.mType = Mailbox.TYPE_MAIL;
+                validMailboxes.add(m);
+            } else {
+                userLog("Rejecting unknown type mailbox: " + m.mDisplayName);
+            }
+        }
+
+        // Add operations for all valid mailboxes
+        for (Mailbox m: validMailboxes) {
+            userLog("Adding mailbox: ", m.mDisplayName);
+            ops.add(ContentProviderOperation
+                    .newInsert(Mailbox.CONTENT_URI).withValues(m.toContentValues()).build());
+        }
+
+        // Commit the mailboxes
+        userLog("Applying ", mOperations.size(), " mailbox operations.");
+        // Execute the batch; throw IOExceptions if this fails, hoping the issue isn't repeatable
+        // If it IS repeatable, there's no good result, since the folder list will be invalid
+        try {
+            mContentResolver.applyBatch(EmailContent.AUTHORITY, mOperations);
+            return true;
+        } catch (RemoteException e) {
+            userLog("RemoteException in commitMailboxes");
+            return false;
+        } catch (OperationApplicationException e) {
+            userLog("OperationApplicationException in commitMailboxes");
+            return false;
+        }
+    }
+
+    public void changesParser(final ArrayList<ContentProviderOperation> ops,
+            final boolean initialSync) throws IOException {
+        // Array of added mailboxes
+        final ArrayList<Mailbox> addMailboxes = new ArrayList<Mailbox>();
+
+        // Indicate start of (potential) mailbox changes
+        MailboxUtilities.startMailboxChanges(mContext, mAccount.mId);
+
+        while (nextTag(Tags.FOLDER_CHANGES) != END) {
+            if (tag == Tags.FOLDER_ADD) {
+                Mailbox mailbox = addParser();
+                if (mailbox != null) {
+                    addMailboxes.add(mailbox);
+                }
+            } else if (tag == Tags.FOLDER_DELETE) {
+                deleteParser(ops);
+            } else if (tag == Tags.FOLDER_UPDATE) {
+                updateParser(ops);
+            } else if (tag == Tags.FOLDER_COUNT) {
+                getValueInt();
+            } else
+                skipTag();
+        }
+
+        EmailAsyncTask<?, ?, ?> task =
+                EmailAsyncTask.runAsyncParallel(new Runnable() {
+                    @Override
+                    public void run() {
+                        // Synchronize on the parser to prevent this being run concurrently
+                        // (an extremely unlikely event, but nonetheless possible)
+                        synchronized (FolderSyncParser.this) {
+                            // Mailboxes that we known contain email
+                            ArrayList<Mailbox> validMailboxes = new ArrayList<Mailbox>();
+                            // Mailboxes that we're unsure about
+                            ArrayList<Mailbox> userMailboxes = new ArrayList<Mailbox>();
+
+                            // Maps folder serverId to mailbox (used to validate user mailboxes)
+                            HashMap<String, Mailbox> mailboxMap = new HashMap<String, Mailbox>();
+                            for (Mailbox mailbox : addMailboxes) {
+                                mailboxMap.put(mailbox.mServerId, mailbox);
+                            }
+
+                            int mailboxCommitCount = 0;
+                            for (Mailbox mailbox : addMailboxes) {
+                                // And add the mailbox to the proper list
+                                if (type == USER_MAILBOX_TYPE) {
+                                    userMailboxes.add(mailbox);
+                                } else {
+                                    validMailboxes.add(mailbox);
+                                }
+                                // On initial sync, we commit what we have every 20 mailboxes
+                                if (initialSync && (++mailboxCommitCount == MAILBOX_COMMIT_SIZE)) {
+                                    if (!commitMailboxes(validMailboxes, userMailboxes, mailboxMap,
+                                            ops)) {
+                                        mService.stop();
+                                        return;
+                                    }
+                                    // Clear our arrays to prepare for more
+                                    userMailboxes.clear();
+                                    validMailboxes.clear();
+                                    ops.clear();
+                                    mailboxCommitCount = 0;
+                                }
+                            }
+                            // Commit the sync key and mailboxes
+                            ContentValues cv = new ContentValues();
+                            cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
+                            ops.add(ContentProviderOperation
+                                    .newUpdate(
+                                            ContentUris.withAppendedId(Account.CONTENT_URI,
+                                                    mAccount.mId))
+                                            .withValues(cv).build());
+                            if (!commitMailboxes(validMailboxes, userMailboxes, mailboxMap, ops)) {
+                                mService.stop();
+                                return;
+                            }
+                            String accountSelector = Mailbox.ACCOUNT_KEY + "=" + mAccount.mId;
+                            // For new boxes, setup the parent key and flags
+                            if (mFixupUninitializedNeeded) {
+                                MailboxUtilities.fixupUninitializedParentKeys(mContext,
+                                        accountSelector);
+                            }
+                            // For modified parents, reset the flags (and children's parent key)
+                            for (String parentServerId: mParentFixupsNeeded) {
+                                Cursor c = mContentResolver.query(Mailbox.CONTENT_URI,
+                                        Mailbox.CONTENT_PROJECTION, Mailbox.PARENT_SERVER_ID + "=?",
+                                        new String[] {parentServerId}, null);
+                                try {
+                                    if (c.moveToFirst()) {
+                                        MailboxUtilities.setFlagsAndChildrensParentKey(mContext, c,
+                                                accountSelector);
+                                    }
+                                } finally {
+                                    c.close();
+                                }
+                            }
+
+                            // Signal completion of mailbox changes
+                            MailboxUtilities.endMailboxChanges(mContext, mAccount.mId);
+                        }
+                    }});
+        // Make this synchronous if in a unit test
+        if (mInUnitTest) {
+            try {
+                task.get();
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    /**
+     * Not needed for FolderSync parsing; everything is done within changesParser
+     */
+    @Override
+    public void commandsParser() throws IOException {
+    }
+
+    /**
+     * Clean up after sync
+     */
+    @Override
+    public void commit() throws IOException {
+        // Look for sync issues and its children and delete them
+        // I'm not aware of any other way to deal with this properly
+        mBindArguments[0] = "Sync Issues";
+        mBindArguments[1] = mAccountIdAsString;
+        Cursor c = mContentResolver.query(Mailbox.CONTENT_URI,
+                MAILBOX_ID_COLUMNS_PROJECTION, WHERE_DISPLAY_NAME_AND_ACCOUNT,
+                mBindArguments, null);
+        String parentServerId = null;
+        long id = 0;
+        try {
+            if (c.moveToFirst()) {
+                id = c.getLong(MAILBOX_ID_COLUMNS_ID);
+                parentServerId = c.getString(MAILBOX_ID_COLUMNS_SERVER_ID);
+            }
+        } finally {
+            c.close();
+        }
+        if (parentServerId != null) {
+            mContentResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, id),
+                    null, null);
+            mBindArguments[0] = parentServerId;
+            mContentResolver.delete(Mailbox.CONTENT_URI, WHERE_PARENT_SERVER_ID_AND_ACCOUNT,
+                    mBindArguments);
+        }
+
+        // If we have saved options, restore them now
+        if (mInitialSync) {
+            restoreMailboxSyncOptions();
+        }
+    }
+
+    @Override
+    public void responsesParser() throws IOException {
+    }
+
+}
diff --git a/exchange2/src/com/android/exchange/adapter/GalParser.java b/exchange2/src/com/android/exchange/adapter/GalParser.java
new file mode 100644
index 0000000..94c8cdf
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/GalParser.java
@@ -0,0 +1,143 @@
+/* Copyright (C) 2010 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import com.android.exchange.EasSyncService;
+import com.android.exchange.provider.GalResult;
+import com.android.exchange.provider.GalResult.GalData;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parse the result of a GAL command.
+ */
+public class GalParser extends Parser {
+    private EasSyncService mService;
+    GalResult mGalResult = new GalResult();
+
+    public GalParser(InputStream in, EasSyncService service) throws IOException {
+        super(in);
+        mService = service;
+    }
+
+    public GalResult getGalResult() {
+        return mGalResult;
+    }
+
+    @Override
+    public boolean parse() throws IOException {
+        if (nextTag(START_DOCUMENT) != Tags.SEARCH_SEARCH) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.SEARCH_RESPONSE) {
+                parseResponse(mGalResult);
+            } else {
+                skipTag();
+            }
+         }
+         return mGalResult.total > 0;
+     }
+
+    public void parseProperties(GalResult galResult) throws IOException {
+        GalData galData = new GalData();
+        while (nextTag(Tags.SEARCH_STORE) != END) {
+            switch(tag) {
+                // Display name and email address use both legacy and new code for galData
+                case Tags.GAL_DISPLAY_NAME: 
+                    String displayName = getValue();
+                    galData.put(GalData.DISPLAY_NAME, displayName);
+                    galData.displayName = displayName;
+                    break;
+                case Tags.GAL_EMAIL_ADDRESS:
+                    String emailAddress = getValue();
+                    galData.put(GalData.EMAIL_ADDRESS, emailAddress);
+                    galData.emailAddress = emailAddress;
+                    break;
+                case Tags.GAL_PHONE:
+                    galData.put(GalData.WORK_PHONE, getValue());
+                    break;
+                case Tags.GAL_OFFICE:
+                    galData.put(GalData.OFFICE, getValue());
+                    break;
+                case Tags.GAL_TITLE:
+                    galData.put(GalData.TITLE, getValue());
+                    break;
+                case Tags.GAL_COMPANY:
+                    galData.put(GalData.COMPANY, getValue());
+                    break;
+                case Tags.GAL_ALIAS:
+                    galData.put(GalData.ALIAS, getValue());
+                    break;
+                case Tags.GAL_FIRST_NAME:
+                    galData.put(GalData.FIRST_NAME, getValue());
+                    break;
+                case Tags.GAL_LAST_NAME:
+                    galData.put(GalData.LAST_NAME, getValue());
+                    break;
+                case Tags.GAL_HOME_PHONE:
+                    galData.put(GalData.HOME_PHONE, getValue());
+                    break;
+                case Tags.GAL_MOBILE_PHONE:
+                    galData.put(GalData.MOBILE_PHONE, getValue());
+                    break;
+                default:
+                    skipTag();
+            }
+        }
+        galResult.addGalData(galData);
+    }
+
+     public void parseResult(GalResult galResult) throws IOException {
+         while (nextTag(Tags.SEARCH_STORE) != END) {
+             if (tag == Tags.SEARCH_PROPERTIES) {
+                 parseProperties(galResult);
+             } else {
+                 skipTag();
+             }
+         }
+     }
+
+     public void parseResponse(GalResult galResult) throws IOException {
+         while (nextTag(Tags.SEARCH_RESPONSE) != END) {
+             if (tag == Tags.SEARCH_STORE) {
+                 parseStore(galResult);
+             } else {
+                 skipTag();
+             }
+         }
+     }
+
+     public void parseStore(GalResult galResult) throws IOException {
+         while (nextTag(Tags.SEARCH_STORE) != END) {
+             if (tag == Tags.SEARCH_RESULT) {
+                 parseResult(galResult);
+             } else if (tag == Tags.SEARCH_RANGE) {
+                 // Retrieve value, even if we're not using it for debug logging
+                 String range = getValue();
+                 if (EasSyncService.DEBUG_GAL_SERVICE) {
+                     mService.userLog("GAL result range: " + range);
+                 }
+             } else if (tag == Tags.SEARCH_TOTAL) {
+                 galResult.total = getValueInt();
+             } else {
+                 skipTag();
+             }
+         }
+     }
+}
+
diff --git a/exchange2/src/com/android/exchange/adapter/ItemOperationsParser.java b/exchange2/src/com/android/exchange/adapter/ItemOperationsParser.java
new file mode 100644
index 0000000..5f412ad
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/ItemOperationsParser.java
@@ -0,0 +1,94 @@
+/* Copyright (C) 2011 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Parse the result of an ItemOperations command; we use this to load attachments in EAS 14.0
+ */
+public class ItemOperationsParser extends Parser {
+    private final AttachmentLoader mAttachmentLoader;
+    private int mStatusCode = 0;
+    private final OutputStream mAttachmentOutputStream;
+    private final int mAttachmentSize;
+
+    public ItemOperationsParser(AttachmentLoader loader, InputStream in, OutputStream out, int size)
+            throws IOException {
+        super(in);
+        mAttachmentLoader = loader;
+        mAttachmentOutputStream = out;
+        mAttachmentSize = size;
+    }
+
+    public int getStatusCode() {
+        return mStatusCode;
+    }
+
+    private void parseProperties() throws IOException {
+        while (nextTag(Tags.ITEMS_PROPERTIES) != END) {
+            if (tag == Tags.ITEMS_DATA) {
+                // Wrap the input stream in our custom base64 input stream
+                Base64InputStream bis = new Base64InputStream(getInput());
+                // Read the attachment
+                mAttachmentLoader.readChunked(bis, mAttachmentOutputStream, mAttachmentSize);
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    private void parseFetch() throws IOException {
+        while (nextTag(Tags.ITEMS_FETCH) != END) {
+            if (tag == Tags.ITEMS_PROPERTIES) {
+                parseProperties();
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    private void parseResponse() throws IOException {
+        while (nextTag(Tags.ITEMS_RESPONSE) != END) {
+            if (tag == Tags.ITEMS_FETCH) {
+                parseFetch();
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    @Override
+    public boolean parse() throws IOException {
+        boolean res = false;
+        if (nextTag(START_DOCUMENT) != Tags.ITEMS_ITEMS) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.ITEMS_STATUS) {
+                // Save the status code
+                mStatusCode = getValueInt();
+            } else if (tag == Tags.ITEMS_RESPONSE) {
+                parseResponse();
+            } else {
+                skipTag();
+            }
+        }
+        return res;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/MeetingResponseParser.java b/exchange2/src/com/android/exchange/adapter/MeetingResponseParser.java
new file mode 100644
index 0000000..142c419
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/MeetingResponseParser.java
@@ -0,0 +1,65 @@
+/* Copyright (C) 2010 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import com.android.exchange.EasSyncService;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parse the result of a MeetingRequest command.
+ */
+public class MeetingResponseParser extends Parser {
+    private EasSyncService mService;
+
+    public MeetingResponseParser(InputStream in, EasSyncService service) throws IOException {
+        super(in);
+        mService = service;
+    }
+
+    public void parseResult() throws IOException {
+        while (nextTag(Tags.MREQ_RESULT) != END) {
+            if (tag == Tags.MREQ_STATUS) {
+                int status = getValueInt();
+                if (status != 1) {
+                    mService.userLog("Error in meeting response: " + status);
+                }
+            } else if (tag == Tags.MREQ_CAL_ID) {
+                mService.userLog("Meeting response calendar id: " + getValue());
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    @Override
+    public boolean parse() throws IOException {
+        boolean res = false;
+        if (nextTag(START_DOCUMENT) != Tags.MREQ_MEETING_RESPONSE) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.MREQ_RESULT) {
+                parseResult();
+            } else {
+                skipTag();
+            }
+        }
+        return res;
+    }
+}
+
diff --git a/exchange2/src/com/android/exchange/adapter/MoveItemsParser.java b/exchange2/src/com/android/exchange/adapter/MoveItemsParser.java
new file mode 100644
index 0000000..542331d
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/MoveItemsParser.java
@@ -0,0 +1,113 @@
+/* Copyright (C) 2010 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import com.android.exchange.EasSyncService;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parse the result of a MoveItems command.
+ */
+public class MoveItemsParser extends Parser {
+    private final EasSyncService mService;
+    private int mStatusCode = 0;
+    private String mNewServerId;
+
+    // These are the EAS status codes for MoveItems
+    private static final int STATUS_NO_SOURCE_FOLDER = 1;
+    private static final int STATUS_NO_DESTINATION_FOLDER = 2;
+    private static final int STATUS_SUCCESS = 3;
+    private static final int STATUS_SOURCE_DESTINATION_SAME = 4;
+    private static final int STATUS_INTERNAL_ERROR = 5;
+    private static final int STATUS_ALREADY_EXISTS = 6;
+    private static final int STATUS_LOCKED = 7;
+
+    // These are the status values we return to callers
+    public static final int STATUS_CODE_SUCCESS = 1;
+    public static final int STATUS_CODE_REVERT = 2;
+    public static final int STATUS_CODE_RETRY = 3;
+
+    public MoveItemsParser(InputStream in, EasSyncService service) throws IOException {
+        super(in);
+        mService = service;
+    }
+
+    public int getStatusCode() {
+        return mStatusCode;
+    }
+
+    public String getNewServerId() {
+        return mNewServerId;
+    }
+
+    public void parseResponse() throws IOException {
+        while (nextTag(Tags.MOVE_RESPONSE) != END) {
+            if (tag == Tags.MOVE_STATUS) {
+                int status = getValueInt();
+                // Convert the EAS status code with our external codes
+                switch(status) {
+                    case STATUS_SUCCESS:
+                    case STATUS_SOURCE_DESTINATION_SAME:
+                    case STATUS_ALREADY_EXISTS:
+                        // Same destination and already exists are ok with us; we'll continue as
+                        // if the move succeeded
+                        mStatusCode = STATUS_CODE_SUCCESS;
+                        break;
+                    case STATUS_LOCKED:
+                        // This sounds like a transient error, so we can safely retry
+                        mStatusCode = STATUS_CODE_RETRY;
+                        break;
+                    case STATUS_NO_SOURCE_FOLDER:
+                    case STATUS_NO_DESTINATION_FOLDER:
+                    case STATUS_INTERNAL_ERROR:
+                    default:
+                        // These are non-recoverable, so we'll revert the message to its original
+                        // mailbox.  If there's an unknown response, revert
+                        mStatusCode = STATUS_CODE_REVERT;
+                        break;
+                }
+                if (status != STATUS_SUCCESS) {
+                    // There's not much to be done if this fails
+                    mService.userLog("Error in MoveItems: " + status);
+                }
+            } else if (tag == Tags.MOVE_DSTMSGID) {
+                mNewServerId = getValue();
+                mService.userLog("Moved message id is now: " + mNewServerId);
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    @Override
+    public boolean parse() throws IOException {
+        boolean res = false;
+        if (nextTag(START_DOCUMENT) != Tags.MOVE_MOVE_ITEMS) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.MOVE_RESPONSE) {
+                parseResponse();
+            } else {
+                skipTag();
+            }
+        }
+        return res;
+    }
+}
+
diff --git a/exchange2/src/com/android/exchange/adapter/Parser.java b/exchange2/src/com/android/exchange/adapter/Parser.java
new file mode 100644
index 0000000..d24e6c1
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/Parser.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.exchange.Eas;
+import com.android.exchange.EasException;
+import com.android.exchange.utility.FileLogger;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Extremely fast and lightweight WBXML parser, implementing only the subset of WBXML that
+ * EAS uses (as defined in the EAS specification)
+ *
+ */
+public abstract class Parser {
+    private static final boolean LOG_VERBOSE = false;
+
+    // The following constants are Wbxml standard
+    public static final int START_DOCUMENT = 0;
+    public static final int DONE = 1;
+    public static final int START = 2;
+    public static final int END = 3;
+    public static final int TEXT = 4;
+    public static final int END_DOCUMENT = 3;
+    private static final int NOT_FETCHED = Integer.MIN_VALUE;
+    private static final int NOT_ENDED = Integer.MIN_VALUE;
+    private static final int EOF_BYTE = -1;
+    private boolean logging = false;
+    private boolean capture = false;
+    private String logTag = "EAS Parser";
+
+    // Where tags start in a page
+    private static final int TAG_BASE = 5;
+
+    private ArrayList<Integer> captureArray;
+
+    // The input stream for this parser
+    private InputStream in;
+
+    // The current tag depth
+    private int depth;
+
+    // The upcoming (saved) id from the stream
+    private int nextId = NOT_FETCHED;
+
+    // The current tag table (i.e. the tag table for the current page)
+    private String[] tagTable;
+
+    // An array of tag tables, as defined in EasTags
+    static private String[][] tagTables = new String[Tags.pages.length + 1][];
+
+    // The stack of names of tags being processed; used when debug = true
+    private String[] nameArray = new String[32];
+
+    // The stack of tags being processed
+    private int[] startTagArray = new int[32];
+
+    // The following vars are available to all to avoid method calls that represent the state of
+    // the parser at any given time
+    public int endTag = NOT_ENDED;
+
+    public int startTag;
+
+    // The type of the last token read
+    public int type;
+
+    // The current page
+    public int page;
+
+    // The current tag
+    public int tag;
+
+    // The name of the current tag
+    public String name;
+
+    // Whether the current tag is associated with content (a value)
+    public boolean noContent;
+
+    // The value read, as a String.  Only one of text or num will be valid, depending on whether the
+    // value was requested as a String or an int (to avoid wasted effort in parsing)
+    public String text;
+
+    // The value read, as an int
+    public int num;
+
+    // The value read, as bytes
+    public byte[] bytes;
+
+    /**
+     * Generated when the parser comes to EOF prematurely during parsing (i.e. in error)
+     */
+    public class EofException extends IOException {
+        private static final long serialVersionUID = 1L;
+    }
+
+    /**
+     * An EmptyStreamException is an EofException that occurs reading the first byte in the parser's
+     * input stream; in other words, the stream had no content.
+     */
+    public class EmptyStreamException extends EofException {
+        private static final long serialVersionUID = 1L;
+    }
+
+    public class EodException extends IOException {
+        private static final long serialVersionUID = 1L;
+    }
+
+    public class EasParserException extends IOException {
+        private static final long serialVersionUID = 1L;
+
+        EasParserException() {
+            super("WBXML format error");
+        }
+
+        EasParserException(String reason) {
+            super(reason);
+        }
+    }
+
+    public boolean parse() throws IOException, EasException {
+        return false;
+    }
+
+    /**
+     * Initialize the tag tables; they are constant
+     *
+     */
+    {
+        String[][] pages = Tags.pages;
+        for (int i = 0; i < pages.length; i++) {
+            String[] page = pages[i];
+            if (page.length > 0) {
+                tagTables[i] = page;
+            }
+        }
+    }
+
+    public Parser(InputStream in) throws IOException {
+        setInput(in, true);
+        logging = Eas.PARSER_LOG;
+    }
+
+    /**
+     * Constructor for use when switching parsers within a input stream
+     * @param parser an existing, initialized parser
+     * @throws IOException
+     */
+    public Parser(Parser parser) throws IOException {
+        setInput(parser.in, false);
+        logging = Eas.PARSER_LOG;
+    }
+
+    /**
+     * Set the debug state of the parser.  When debugging is on, every token is logged (Log.v) to
+     * the console.
+     *
+     * @param val the desired state for debug output
+     */
+    public void setDebug(boolean val) {
+        logging = val;
+    }
+
+    protected InputStream getInput() {
+        return in;
+    }
+
+    /**
+     * Set the tag used for logging.  When debugging is on, every token is logged (Log.v) to
+     * the console.
+     *
+     * @param val the logging tag
+     */
+    public void setLoggingTag(String val) {
+        logTag = val;
+    }
+
+    /**
+     * Turns on data capture; this is used to create test streams that represent "live" data and
+     * can be used against the various parsers.
+     */
+    public void captureOn() {
+        capture = true;
+        captureArray = new ArrayList<Integer>();
+    }
+
+    /**
+     * Turns off data capture; writes the captured data to a specified file.
+     */
+    public void captureOff(Context context, String file) {
+        try {
+            FileOutputStream out = context.openFileOutput(file, Context.MODE_WORLD_WRITEABLE);
+            out.write(captureArray.toString().getBytes());
+            out.close();
+        } catch (FileNotFoundException e) {
+            // This is debug code; exceptions aren't interesting.
+        } catch (IOException e) {
+            // This is debug code; exceptions aren't interesting.
+        }
+    }
+
+    /**
+     * Return the value of the current tag, as a byte array.  Note that the result of this call
+     * is indeterminate, and possibly null, if the value of the tag is not a byte array
+     *
+     * @return the byte array value of the current tag
+     * @throws IOException
+     */
+    public byte[] getValueBytes() throws IOException {
+        getValue();
+        return bytes;
+    }
+
+    /**
+     * Return the value of the current tag, as a String.  Note that the result of this call is
+     * indeterminate, and possibly null, if the value of the tag is not an immediate string
+     *
+     * @return the String value of the current tag
+     * @throws IOException
+     */
+    public String getValue() throws IOException {
+        // The false argument tells getNext to return the value as a String
+        getNext(false);
+        // This means there was no value given, just <Foo/>; we'll return empty string for now
+        if (type == END) {
+            if (logging) {
+                log("No value for tag: " + tagTable[startTag - TAG_BASE]);
+            }
+            return "";
+        }
+        // Save the value
+        String val = text;
+        // Read the next token; it had better be the end of the current tag
+        getNext(false);
+        // If not, throw an exception
+        if (type != END) {
+            throw new IOException("No END found!");
+        }
+        return val;
+    }
+
+    /**
+     * Return the value of the current tag, as an integer.  Note that the value of this call is
+     * indeterminate if the value of this tag is not an immediate string parsed as an integer
+     *
+     * @return the integer value of the current tag
+     * @throws IOException
+     */
+   public int getValueInt() throws IOException {
+        // The true argument to getNext indicates the desire for an integer return value
+        getNext(true);
+        if (type == END) {
+            return 0;
+        }
+        // Save the value
+        int val = num;
+        // Read the next token; it had better be the end of the current tag
+        getNext(false);
+        // If not, throw an exception
+        if (type != END) {
+            throw new IOException("No END found!");
+        }
+        return val;
+    }
+
+    /**
+     * Return the next tag found in the stream; special tags END and END_DOCUMENT are used to
+     * mark the end of the current tag and end of document.  If we hit end of document without
+     * looking for it, generate an EodException.  The tag returned consists of the page number
+     * shifted PAGE_SHIFT bits OR'd with the tag retrieved from the stream.  Thus, all tags returned
+     * are unique.
+     *
+     * @param endingTag the tag that would represent the end of the tag we're processing
+     * @return the next tag found
+     * @throws IOException
+     */
+    public int nextTag(int endingTag) throws IOException {
+        // Lose the page information
+        endTag = endingTag &= Tags.PAGE_MASK;
+        while (getNext(false) != DONE) {
+            // If we're a start, set tag to include the page and return it
+            if (type == START) {
+                tag = page | startTag;
+                return tag;
+            // If we're at the ending tag we're looking for, return the END signal
+            } else if (type == END && startTag == endTag) {
+                return END;
+            }
+        }
+        // We're at end of document here.  If we're looking for it, return END_DOCUMENT
+        if (endTag == START_DOCUMENT) {
+            return END_DOCUMENT;
+        }
+        // Otherwise, we've prematurely hit end of document, so exception out
+        // EodException is a subclass of IOException; this will be treated as an IO error by
+        // ExchangeService
+        throw new EodException();
+    }
+
+    /**
+     * Skip anything found in the stream until the end of the current tag is reached.  This can be
+     * used to ignore stretches of xml that aren't needed by the parser.
+     *
+     * @throws IOException
+     */
+    public void skipTag() throws IOException {
+        int thisTag = startTag;
+        // Just loop until we hit the end of the current tag
+        while (getNext(false) != DONE) {
+            if (type == END && startTag == thisTag) {
+                return;
+            }
+        }
+
+        // If we're at end of document, that's bad
+        throw new EofException();
+    }
+
+    /**
+     * Retrieve the next token from the input stream
+     *
+     * @return the token found
+     * @throws IOException
+     */
+    public int nextToken() throws IOException {
+        getNext(false);
+        return type;
+    }
+
+    /**
+     * Initializes the parser with an input stream; reads the first 4 bytes (which are always the
+     * same in EAS, and then sets the tag table to point to page 0 (by definition, the starting
+     * page).
+     *
+     * @param in the InputStream associated with this parser
+     * @throws IOException
+     */
+    public void setInput(InputStream in, boolean initialize) throws IOException {
+        this.in = in;
+        if ((in != null) && initialize) {
+            // If we fail on the very first byte, report an empty stream
+            try {
+                readByte(); // version
+            } catch (EofException e) {
+                throw new EmptyStreamException();
+            }
+            readInt();  // ?
+            readInt();  // 106 (UTF-8)
+            readInt();  // string table length
+        }
+        tagTable = tagTables[0];
+    }
+
+    @VisibleForTesting
+    void resetInput(InputStream in) {
+        this.in = in;
+        try {
+            // Read leading zero
+            read();
+        } catch (IOException e) {
+        }
+    }
+
+    void log(String str) {
+        int cr = str.indexOf('\n');
+        if (cr > 0) {
+            str = str.substring(0, cr);
+        }
+        Log.v(logTag, str);
+        if (Eas.FILE_LOG) {
+            FileLogger.log(logTag, str);
+        }
+    }
+
+    protected void pushTag(int id) {
+        page = id >> Tags.PAGE_SHIFT;
+        tagTable = tagTables[page];
+        push(id);
+    }
+
+    private void pop() {
+        if (logging) {
+            name = nameArray[depth];
+            log("</" + name + '>');
+        }
+        // Retrieve the now-current startTag from our stack
+        startTag = endTag = startTagArray[depth];
+        depth--;
+    }
+
+    private void push(int id) {
+        // The tag is in the low 6 bits
+        startTag = id & 0x3F;
+        // If the high bit is set, there is content (a value) to be read
+        noContent = (id & 0x40) == 0;
+        depth++;
+        if (logging) {
+            name = tagTable[startTag - TAG_BASE];
+            nameArray[depth] = name;
+            log("<" + name + (noContent ? '/' : "") + '>');
+        }
+        // Save the startTag to our stack
+        startTagArray[depth] = startTag;
+    }
+
+    /**
+     * Return the next piece of data from the stream.  The return value indicates the type of data
+     * that has been retrieved - START (start of tag), END (end of tag), DONE (end of stream), or
+     * TEXT (the value of a tag)
+     *
+     * @param asInt whether a TEXT value should be parsed as a String or an int.
+     * @return the type of data retrieved
+     * @throws IOException
+     */
+    private final int getNext(boolean asInt) throws IOException {
+        if (noContent) {
+            nameArray[depth--] = null;
+            type = END;
+            noContent = false;
+            return type;
+        }
+
+        text = null;
+        name = null;
+
+        int id = nextId ();
+        while (id == Wbxml.SWITCH_PAGE) {
+            nextId = NOT_FETCHED;
+            // Get the new page number
+            int pg = readByte();
+            // Save the shifted page to add into the startTag in nextTag
+            page = pg << Tags.PAGE_SHIFT;
+            if (LOG_VERBOSE) {
+                log("Page: " + page);
+            }
+            // Retrieve the current tag table
+            tagTable = tagTables[pg];
+            id = nextId();
+        }
+        nextId = NOT_FETCHED;
+
+        switch (id) {
+            case EOF_BYTE:
+                // End of document
+                type = DONE;
+                break;
+
+            case Wbxml.END:
+                type = END;
+                pop();
+                break;
+
+            case Wbxml.STR_I:
+                // Inline string
+                type = TEXT;
+                if (asInt) {
+                    num = readInlineInt();
+                } else {
+                    text = readInlineString();
+                }
+                if (logging) {
+                    name = tagTable[startTag - TAG_BASE];
+                    log(name + ": " + (asInt ? Integer.toString(num) : text));
+                }
+                break;
+
+            case Wbxml.OPAQUE:
+                // Integer length + opaque data
+                int length = readInt();
+                bytes = new byte[length];
+                for (int i = 0; i < length; i++) {
+                    bytes[i] = (byte)readByte();
+                }
+                if (logging) {
+                    name = tagTable[startTag - TAG_BASE];
+                    log(name + ": (opaque:" + length + ") ");
+                }
+                break;
+
+            default:
+                type = START;
+                push(id);
+        }
+
+        // Return the type of data we're dealing with
+        return type;
+    }
+
+    /**
+     * Read an int from the input stream, and capture it if necessary for debugging.  Seems a small
+     * price to pay...
+     *
+     * @return the int read
+     * @throws IOException
+     */
+    private int read() throws IOException {
+        int i;
+        i = in.read();
+        if (capture) {
+            captureArray.add(i);
+        }
+        if (LOG_VERBOSE) {
+            log("Byte: " + i);
+        }
+        return i;
+    }
+
+    private int nextId() throws IOException {
+        if (nextId == NOT_FETCHED) {
+            nextId = read();
+        }
+        return nextId;
+    }
+
+    private int readByte() throws IOException {
+        int i = read();
+        if (i == EOF_BYTE) {
+            throw new EofException();
+        }
+        return i;
+    }
+
+    /**
+     * Read an integer from the stream; this is called when the parser knows that what follows is
+     * an inline string representing an integer (e.g. the Read tag in Email has a value known to
+     * be either "0" or "1")
+     *
+     * @return the integer as parsed from the stream
+     * @throws IOException
+     */
+    private int readInlineInt() throws IOException {
+        int result = 0;
+
+        while (true) {
+            int i = readByte();
+            // Inline strings are always terminated with a zero byte
+            if (i == 0) {
+                return result;
+            }
+            if (i >= '0' && i <= '9') {
+                result = (result * 10) + (i - '0');
+            } else {
+                throw new IOException("Non integer");
+            }
+        }
+    }
+
+    private int readInt() throws IOException {
+        int result = 0;
+        int i;
+
+        do {
+            i = readByte();
+            result = (result << 7) | (i & 0x7f);
+        } while ((i & 0x80) != 0);
+
+        return result;
+    }
+
+    /**
+     * Read an inline string from the stream
+     *
+     * @return the String as parsed from the stream
+     * @throws IOException
+     */
+    private String readInlineString() throws IOException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(256);
+        while (true) {
+            int i = read();
+            if (i == 0) {
+                break;
+            } else if (i == EOF_BYTE) {
+                throw new EofException();
+            }
+            outputStream.write(i);
+        }
+        outputStream.flush();
+        String res = outputStream.toString("UTF-8");
+        outputStream.close();
+        return res;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/PingParser.java b/exchange2/src/com/android/exchange/adapter/PingParser.java
new file mode 100644
index 0000000..f061472
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/PingParser.java
@@ -0,0 +1,97 @@
+/* Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+import com.android.exchange.EasSyncService;
+import com.android.exchange.IllegalHeartbeatException;
+import com.android.exchange.StaleFolderListException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Parse the result of a Ping command.
+ *
+ * If there are folders with changes, add the serverId of those folders to the syncList array.
+ * If the folder list needs to be reloaded, throw a StaleFolderListException, which will be caught
+ * by the sync server, which will sync the updated folder list.
+ */
+public class PingParser extends Parser {
+    private ArrayList<String> syncList = new ArrayList<String>();
+    private EasSyncService mService;
+    private int mSyncStatus = 0;
+
+    public ArrayList<String> getSyncList() {
+        return syncList;
+    }
+
+    public int getSyncStatus() {
+        return mSyncStatus;
+    }
+
+    public PingParser(InputStream in, EasSyncService service) throws IOException {
+        super(in);
+        mService = service;
+    }
+
+    public void parsePingFolders(ArrayList<String> syncList) throws IOException {
+        while (nextTag(Tags.PING_FOLDERS) != END) {
+            if (tag == Tags.PING_FOLDER) {
+                // Here we'll keep track of which mailboxes need syncing
+                String serverId = getValue();
+                syncList.add(serverId);
+                mService.userLog("Changes found in: ", serverId);
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    @Override
+    public boolean parse() throws IOException, StaleFolderListException, IllegalHeartbeatException {
+        boolean res = false;
+        if (nextTag(START_DOCUMENT) != Tags.PING_PING) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.PING_STATUS) {
+                int status = getValueInt();
+                mSyncStatus = status;
+                mService.userLog("Ping completed, status = ", status);
+                if (status == 2) {
+                    res = true;
+                } else if (status == 7 || status == 4) {
+                    // Status of 7 or 4 indicate a stale folder list
+                    throw new StaleFolderListException();
+                } else if (status == 5) {
+                    // Status 5 means our heartbeat is beyond allowable limits
+                    // In this case, there will be a heartbeat interval set
+                }
+            } else if (tag == Tags.PING_FOLDERS) {
+                parsePingFolders(syncList);
+            } else if (tag == Tags.PING_HEARTBEAT_INTERVAL) {
+                // Throw an exception, saving away the legal heartbeat interval specified
+                throw new IllegalHeartbeatException(getValueInt());
+            } else {
+                skipTag();
+            }
+        }
+        return res;
+    }
+}
+
diff --git a/exchange2/src/com/android/exchange/adapter/ProvisionParser.java b/exchange2/src/com/android/exchange/adapter/ProvisionParser.java
new file mode 100644
index 0000000..de30111
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/ProvisionParser.java
@@ -0,0 +1,616 @@
+/* Copyright (C) 2010 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+
+import com.android.emailcommon.provider.Policy;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Parse the result of the Provision command
+ */
+public class ProvisionParser extends Parser {
+    private final EasSyncService mService;
+    private Policy mPolicy = null;
+    private String mSecuritySyncKey = null;
+    private boolean mRemoteWipe = false;
+    private boolean mIsSupportable = true;
+    private boolean smimeRequired = false;
+    private final Resources mResources;
+
+    public ProvisionParser(InputStream in, EasSyncService service) throws IOException {
+        super(in);
+        mService = service;
+        mResources = service.mContext.getResources();
+    }
+
+    public Policy getPolicy() {
+        return mPolicy;
+    }
+
+    public String getSecuritySyncKey() {
+        return mSecuritySyncKey;
+    }
+
+    public void setSecuritySyncKey(String securitySyncKey) {
+        mSecuritySyncKey = securitySyncKey;
+    }
+
+    public boolean getRemoteWipe() {
+        return mRemoteWipe;
+    }
+
+    public boolean hasSupportablePolicySet() {
+        return (mPolicy != null) && mIsSupportable;
+    }
+
+    public void clearUnsupportablePolicies() {
+        mIsSupportable = true;
+        mPolicy.mProtocolPoliciesUnsupported = null;
+    }
+
+    private void addPolicyString(StringBuilder sb, int res) {
+        sb.append(mResources.getString(res));
+        sb.append(Policy.POLICY_STRING_DELIMITER);
+    }
+
+    /**
+     * Complete setup of a Policy; we normalize it first (removing inconsistencies, etc.) and then
+     * generate the tokenized "protocol policies enforced" string.  Note that unsupported policies
+     * must have been added prior to calling this method (this is only a possibility with wbxml
+     * policy documents, as all versions of the OS support the policies in xml documents).
+     */
+    private void setPolicy(Policy policy) {
+        policy.normalize();
+        StringBuilder sb = new StringBuilder();
+        if (policy.mDontAllowAttachments) {
+            addPolicyString(sb, R.string.policy_dont_allow_attachments);
+        }
+        if (policy.mRequireManualSyncWhenRoaming) {
+            addPolicyString(sb, R.string.policy_require_manual_sync_roaming);
+        }
+        policy.mProtocolPoliciesEnforced = sb.toString();
+        mPolicy = policy;
+    }
+
+    private boolean deviceSupportsEncryption() {
+        DevicePolicyManager dpm = (DevicePolicyManager)
+                mService.mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        int status = dpm.getStorageEncryptionStatus();
+        return status != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
+    }
+
+    private void parseProvisionDocWbxml() throws IOException {
+        Policy policy = new Policy();
+        ArrayList<Integer> unsupportedList = new ArrayList<Integer>();
+        boolean passwordEnabled = false;
+
+        while (nextTag(Tags.PROVISION_EAS_PROVISION_DOC) != END) {
+            boolean tagIsSupported = true;
+            int res = 0;
+            switch (tag) {
+                case Tags.PROVISION_DEVICE_PASSWORD_ENABLED:
+                    if (getValueInt() == 1) {
+                        passwordEnabled = true;
+                        if (policy.mPasswordMode == Policy.PASSWORD_MODE_NONE) {
+                            policy.mPasswordMode = Policy.PASSWORD_MODE_SIMPLE;
+                        }
+                    }
+                    break;
+                case Tags.PROVISION_MIN_DEVICE_PASSWORD_LENGTH:
+                    policy.mPasswordMinLength = getValueInt();
+                    break;
+                case Tags.PROVISION_ALPHA_DEVICE_PASSWORD_ENABLED:
+                    if (getValueInt() == 1) {
+                        policy.mPasswordMode = Policy.PASSWORD_MODE_STRONG;
+                    }
+                    break;
+                case Tags.PROVISION_MAX_INACTIVITY_TIME_DEVICE_LOCK:
+                    // EAS gives us seconds, which is, happily, what the PolicySet requires
+                    policy.mMaxScreenLockTime = getValueInt();
+                    break;
+                case Tags.PROVISION_MAX_DEVICE_PASSWORD_FAILED_ATTEMPTS:
+                    policy.mPasswordMaxFails = getValueInt();
+                    break;
+                case Tags.PROVISION_DEVICE_PASSWORD_EXPIRATION:
+                    policy.mPasswordExpirationDays = getValueInt();
+                    break;
+                case Tags.PROVISION_DEVICE_PASSWORD_HISTORY:
+                    policy.mPasswordHistory = getValueInt();
+                    break;
+                case Tags.PROVISION_ALLOW_CAMERA:
+                    policy.mDontAllowCamera = (getValueInt() == 0);
+                    break;
+                case Tags.PROVISION_ALLOW_SIMPLE_DEVICE_PASSWORD:
+                    // Ignore this unless there's any MSFT documentation for what this means
+                    // Hint: I haven't seen any that's more specific than "simple"
+                    getValue();
+                    break;
+                // The following policies, if false, can't be supported at the moment
+                case Tags.PROVISION_ALLOW_STORAGE_CARD:
+                case Tags.PROVISION_ALLOW_UNSIGNED_APPLICATIONS:
+                case Tags.PROVISION_ALLOW_UNSIGNED_INSTALLATION_PACKAGES:
+                case Tags.PROVISION_ALLOW_WIFI:
+                case Tags.PROVISION_ALLOW_TEXT_MESSAGING:
+                case Tags.PROVISION_ALLOW_POP_IMAP_EMAIL:
+                case Tags.PROVISION_ALLOW_IRDA:
+                case Tags.PROVISION_ALLOW_HTML_EMAIL:
+                case Tags.PROVISION_ALLOW_BROWSER:
+                case Tags.PROVISION_ALLOW_CONSUMER_EMAIL:
+                case Tags.PROVISION_ALLOW_INTERNET_SHARING:
+                    if (getValueInt() == 0) {
+                        tagIsSupported = false;
+                        switch(tag) {
+                            case Tags.PROVISION_ALLOW_STORAGE_CARD:
+                                res = R.string.policy_dont_allow_storage_cards;
+                                break;
+                            case Tags.PROVISION_ALLOW_UNSIGNED_APPLICATIONS:
+                                res = R.string.policy_dont_allow_unsigned_apps;
+                                break;
+                            case Tags.PROVISION_ALLOW_UNSIGNED_INSTALLATION_PACKAGES:
+                                res = R.string.policy_dont_allow_unsigned_installers;
+                                break;
+                            case Tags.PROVISION_ALLOW_WIFI:
+                                res = R.string.policy_dont_allow_wifi;
+                                break;
+                            case Tags.PROVISION_ALLOW_TEXT_MESSAGING:
+                                res = R.string.policy_dont_allow_text_messaging;
+                                break;
+                            case Tags.PROVISION_ALLOW_POP_IMAP_EMAIL:
+                                res = R.string.policy_dont_allow_pop_imap;
+                                break;
+                            case Tags.PROVISION_ALLOW_IRDA:
+                                res = R.string.policy_dont_allow_irda;
+                                break;
+                            case Tags.PROVISION_ALLOW_HTML_EMAIL:
+                                res = R.string.policy_dont_allow_html;
+                                policy.mDontAllowHtml = true;
+                                break;
+                            case Tags.PROVISION_ALLOW_BROWSER:
+                                res = R.string.policy_dont_allow_browser;
+                                break;
+                            case Tags.PROVISION_ALLOW_CONSUMER_EMAIL:
+                                res = R.string.policy_dont_allow_consumer_email;
+                                break;
+                            case Tags.PROVISION_ALLOW_INTERNET_SHARING:
+                                res = R.string.policy_dont_allow_internet_sharing;
+                                break;
+                        }
+                        if (res > 0) {
+                            unsupportedList.add(res);
+                        }
+                    }
+                    break;
+                case Tags.PROVISION_ATTACHMENTS_ENABLED:
+                    policy.mDontAllowAttachments = getValueInt() != 1;
+                    break;
+                // Bluetooth: 0 = no bluetooth; 1 = only hands-free; 2 = allowed
+                case Tags.PROVISION_ALLOW_BLUETOOTH:
+                    if (getValueInt() != 2) {
+                        tagIsSupported = false;
+                        unsupportedList.add(R.string.policy_bluetooth_restricted);
+                    }
+                    break;
+                // We may now support device (internal) encryption; we'll check this capability
+                // below with the call to SecurityPolicy.isSupported()
+                case Tags.PROVISION_REQUIRE_DEVICE_ENCRYPTION:
+                    if (getValueInt() == 1) {
+                         if (!deviceSupportsEncryption()) {
+                            tagIsSupported = false;
+                            unsupportedList.add(R.string.policy_require_encryption);
+                        } else {
+                            policy.mRequireEncryption = true;
+                        }
+                    }
+                    break;
+                // Note that DEVICE_ENCRYPTION_ENABLED refers to SD card encryption, which the OS
+                // does not yet support.
+                case Tags.PROVISION_DEVICE_ENCRYPTION_ENABLED:
+                    if (getValueInt() == 1) {
+                        log("Policy requires SD card encryption");
+                        // Let's see if this can be supported on our device...
+                        if (deviceSupportsEncryption()) {
+                            StorageManager sm = (StorageManager)mService.mContext.getSystemService(
+                                    Context.STORAGE_SERVICE);
+                            // NOTE: Private API!
+                            // Go through volumes; if ANY are removable, we can't support this
+                            // policy.
+                            StorageVolume[] volumeList = sm.getVolumeList();
+                            for (StorageVolume volume: volumeList) {
+                                if (volume.isRemovable()) {
+                                    tagIsSupported = false;
+                                    log("Removable: " + volume.getDescription());
+                                    break;  // Break only from the storage volume loop
+                                } else {
+                                    log("Not Removable: " + volume.getDescription());
+                                }
+                            }
+                            if (tagIsSupported) {
+                                // If this policy is requested, we MUST also require encryption
+                                log("Device supports SD card encryption");
+                                policy.mRequireEncryption = true;
+                                break;
+                            }
+                        } else {
+                            log("Device doesn't support encryption; failing");
+                            tagIsSupported = false;
+                        }
+                        // If we fall through, we can't support the policy
+                        unsupportedList.add(R.string.policy_require_sd_encryption);
+                    }
+                    break;
+                    // Note this policy; we enforce it in ExchangeService
+                case Tags.PROVISION_REQUIRE_MANUAL_SYNC_WHEN_ROAMING:
+                    policy.mRequireManualSyncWhenRoaming = getValueInt() == 1;
+                    break;
+                // We are allowed to accept policies, regardless of value of this tag
+                // TODO: When we DO support a recovery password, we need to store the value in
+                // the account (so we know to utilize it)
+                case Tags.PROVISION_PASSWORD_RECOVERY_ENABLED:
+                    // Read, but ignore, value
+                    policy.mPasswordRecoveryEnabled = getValueInt() == 1;
+                    break;
+                // The following policies, if true, can't be supported at the moment
+                case Tags.PROVISION_REQUIRE_SIGNED_SMIME_MESSAGES:
+                case Tags.PROVISION_REQUIRE_ENCRYPTED_SMIME_MESSAGES:
+                case Tags.PROVISION_REQUIRE_SIGNED_SMIME_ALGORITHM:
+                case Tags.PROVISION_REQUIRE_ENCRYPTION_SMIME_ALGORITHM:
+                    if (getValueInt() == 1) {
+                        tagIsSupported = false;
+                        if (!smimeRequired) {
+                            unsupportedList.add(R.string.policy_require_smime);
+                            smimeRequired = true;
+                        }
+                    }
+                    break;
+                case Tags.PROVISION_MAX_ATTACHMENT_SIZE:
+                    int max = getValueInt();
+                    if (max > 0) {
+                        policy.mMaxAttachmentSize = max;
+                    }
+                    break;
+                // Complex characters are supported
+                case Tags.PROVISION_MIN_DEVICE_PASSWORD_COMPLEX_CHARS:
+                    policy.mPasswordComplexChars = getValueInt();
+                    break;
+                // The following policies are moot; they allow functionality that we don't support
+                case Tags.PROVISION_ALLOW_DESKTOP_SYNC:
+                case Tags.PROVISION_ALLOW_SMIME_ENCRYPTION_NEGOTIATION:
+                case Tags.PROVISION_ALLOW_SMIME_SOFT_CERTS:
+                case Tags.PROVISION_ALLOW_REMOTE_DESKTOP:
+                    skipTag();
+                    break;
+                // We don't handle approved/unapproved application lists
+                case Tags.PROVISION_UNAPPROVED_IN_ROM_APPLICATION_LIST:
+                case Tags.PROVISION_APPROVED_APPLICATION_LIST:
+                    // Parse and throw away the content
+                    if (specifiesApplications(tag)) {
+                        tagIsSupported = false;
+                        if (tag == Tags.PROVISION_UNAPPROVED_IN_ROM_APPLICATION_LIST) {
+                            unsupportedList.add(R.string.policy_app_blacklist);
+                        } else {
+                            unsupportedList.add(R.string.policy_app_whitelist);
+                        }
+                    }
+                    break;
+                // We accept calendar age, since we never ask for more than two weeks, and that's
+                // the most restrictive policy
+                case Tags.PROVISION_MAX_CALENDAR_AGE_FILTER:
+                    policy.mMaxCalendarLookback = getValueInt();
+                    break;
+                // We handle max email lookback
+                case Tags.PROVISION_MAX_EMAIL_AGE_FILTER:
+                    policy.mMaxEmailLookback = getValueInt();
+                    break;
+                // We currently reject these next two policies
+                case Tags.PROVISION_MAX_EMAIL_BODY_TRUNCATION_SIZE:
+                case Tags.PROVISION_MAX_EMAIL_HTML_BODY_TRUNCATION_SIZE:
+                    String value = getValue();
+                    // -1 indicates no required truncation
+                    if (!value.equals("-1")) {
+                        max = Integer.parseInt(value);
+                        if (tag == Tags.PROVISION_MAX_EMAIL_BODY_TRUNCATION_SIZE) {
+                            policy.mMaxTextTruncationSize = max;
+                            unsupportedList.add(R.string.policy_text_truncation);
+                        } else {
+                            policy.mMaxHtmlTruncationSize = max;
+                            unsupportedList.add(R.string.policy_html_truncation);
+                        }
+                        tagIsSupported = false;
+                    }
+                    break;
+                default:
+                    skipTag();
+            }
+
+            if (!tagIsSupported) {
+                log("Policy not supported: " + tag);
+                mIsSupportable = false;
+            }
+        }
+
+        // Make sure policy settings are valid; password not enabled trumps other password settings
+        if (!passwordEnabled) {
+            policy.mPasswordMode = Policy.PASSWORD_MODE_NONE;
+        }
+
+        if (!unsupportedList.isEmpty()) {
+            StringBuilder sb = new StringBuilder();
+            for (int res: unsupportedList) {
+                addPolicyString(sb, res);
+            }
+            policy.mProtocolPoliciesUnsupported = sb.toString();
+        }
+
+        setPolicy(policy);
+    }
+
+    /**
+     * Return whether or not either of the application list tags specifies any applications
+     * @param endTag the tag whose children we're walking through
+     * @return whether any applications were specified (by name or by hash)
+     * @throws IOException
+     */
+    private boolean specifiesApplications(int endTag) throws IOException {
+        boolean specifiesApplications = false;
+        while (nextTag(endTag) != END) {
+            switch (tag) {
+                case Tags.PROVISION_APPLICATION_NAME:
+                case Tags.PROVISION_HASH:
+                    specifiesApplications = true;
+                    break;
+                default:
+                    skipTag();
+            }
+        }
+        return specifiesApplications;
+    }
+
+    /*package*/ void parseProvisionDocXml(String doc) throws IOException {
+        Policy policy = new Policy();
+
+        try {
+            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+            XmlPullParser parser = factory.newPullParser();
+            parser.setInput(new ByteArrayInputStream(doc.getBytes()), "UTF-8");
+            int type = parser.getEventType();
+            if (type == XmlPullParser.START_DOCUMENT) {
+                type = parser.next();
+                if (type == XmlPullParser.START_TAG) {
+                    String tagName = parser.getName();
+                    if (tagName.equals("wap-provisioningdoc")) {
+                        parseWapProvisioningDoc(parser, policy);
+                    }
+                }
+            }
+        } catch (XmlPullParserException e) {
+           throw new IOException();
+        }
+
+        setPolicy(policy);
+    }
+
+    /**
+     * Return true if password is required; otherwise false.
+     */
+    private boolean parseSecurityPolicy(XmlPullParser parser, Policy policy)
+            throws XmlPullParserException, IOException {
+        boolean passwordRequired = true;
+        while (true) {
+            int type = parser.nextTag();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("characteristic")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String tagName = parser.getName();
+                if (tagName.equals("parm")) {
+                    String name = parser.getAttributeValue(null, "name");
+                    if (name.equals("4131")) {
+                        String value = parser.getAttributeValue(null, "value");
+                        if (value.equals("1")) {
+                            passwordRequired = false;
+                        }
+                    }
+                }
+            }
+        }
+        return passwordRequired;
+    }
+
+    private void parseCharacteristic(XmlPullParser parser, Policy policy)
+            throws XmlPullParserException, IOException {
+        boolean enforceInactivityTimer = true;
+        while (true) {
+            int type = parser.nextTag();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("characteristic")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("parm")) {
+                    String name = parser.getAttributeValue(null, "name");
+                    String value = parser.getAttributeValue(null, "value");
+                    if (name.equals("AEFrequencyValue")) {
+                        if (enforceInactivityTimer) {
+                            if (value.equals("0")) {
+                                policy.mMaxScreenLockTime = 1;
+                            } else {
+                                policy.mMaxScreenLockTime = 60*Integer.parseInt(value);
+                            }
+                        }
+                    } else if (name.equals("AEFrequencyType")) {
+                        // "0" here means we don't enforce an inactivity timeout
+                        if (value.equals("0")) {
+                            enforceInactivityTimer = false;
+                        }
+                    } else if (name.equals("DeviceWipeThreshold")) {
+                        policy.mPasswordMaxFails = Integer.parseInt(value);
+                    } else if (name.equals("CodewordFrequency")) {
+                        // Ignore; has no meaning for us
+                    } else if (name.equals("MinimumPasswordLength")) {
+                        policy.mPasswordMinLength = Integer.parseInt(value);
+                    } else if (name.equals("PasswordComplexity")) {
+                        if (value.equals("0")) {
+                            policy.mPasswordMode = Policy.PASSWORD_MODE_STRONG;
+                        } else {
+                            policy.mPasswordMode = Policy.PASSWORD_MODE_SIMPLE;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void parseRegistry(XmlPullParser parser, Policy policy)
+            throws XmlPullParserException, IOException {
+      while (true) {
+          int type = parser.nextTag();
+          if (type == XmlPullParser.END_TAG && parser.getName().equals("characteristic")) {
+              break;
+          } else if (type == XmlPullParser.START_TAG) {
+              String name = parser.getName();
+              if (name.equals("characteristic")) {
+                  parseCharacteristic(parser, policy);
+              }
+          }
+      }
+    }
+
+    private void parseWapProvisioningDoc(XmlPullParser parser, Policy policy)
+            throws XmlPullParserException, IOException {
+        while (true) {
+            int type = parser.nextTag();
+            if (type == XmlPullParser.END_TAG && parser.getName().equals("wap-provisioningdoc")) {
+                break;
+            } else if (type == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (name.equals("characteristic")) {
+                    String atype = parser.getAttributeValue(null, "type");
+                    if (atype.equals("SecurityPolicy")) {
+                        // If a password isn't required, stop here
+                        if (!parseSecurityPolicy(parser, policy)) {
+                            return;
+                        }
+                    } else if (atype.equals("Registry")) {
+                        parseRegistry(parser, policy);
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    private void parseProvisionData() throws IOException {
+        while (nextTag(Tags.PROVISION_DATA) != END) {
+            if (tag == Tags.PROVISION_EAS_PROVISION_DOC) {
+                parseProvisionDocWbxml();
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    private void parsePolicy() throws IOException {
+        String policyType = null;
+        while (nextTag(Tags.PROVISION_POLICY) != END) {
+            switch (tag) {
+                case Tags.PROVISION_POLICY_TYPE:
+                    policyType = getValue();
+                    mService.userLog("Policy type: ", policyType);
+                    break;
+                case Tags.PROVISION_POLICY_KEY:
+                    mSecuritySyncKey = getValue();
+                    break;
+                case Tags.PROVISION_STATUS:
+                    mService.userLog("Policy status: ", getValue());
+                    break;
+                case Tags.PROVISION_DATA:
+                    if (policyType.equalsIgnoreCase(EasSyncService.EAS_2_POLICY_TYPE)) {
+                        // Parse the old style XML document
+                        parseProvisionDocXml(getValue());
+                    } else {
+                        // Parse the newer WBXML data
+                        parseProvisionData();
+                    }
+                    break;
+                default:
+                    skipTag();
+            }
+        }
+    }
+
+    private void parsePolicies() throws IOException {
+        while (nextTag(Tags.PROVISION_POLICIES) != END) {
+            if (tag == Tags.PROVISION_POLICY) {
+                parsePolicy();
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    private void parseDeviceInformation() throws IOException {
+        while (nextTag(Tags.SETTINGS_DEVICE_INFORMATION) != END) {
+            if (tag == Tags.SETTINGS_STATUS) {
+                mService.userLog("DeviceInformation status: " + getValue());
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    @Override
+    public boolean parse() throws IOException {
+        boolean res = false;
+        if (nextTag(START_DOCUMENT) != Tags.PROVISION_PROVISION) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            switch (tag) {
+                case Tags.PROVISION_STATUS:
+                    int status = getValueInt();
+                    mService.userLog("Provision status: ", status);
+                    res = (status == 1);
+                    break;
+                case Tags.SETTINGS_DEVICE_INFORMATION:
+                    parseDeviceInformation();
+                    break;
+                case Tags.PROVISION_POLICIES:
+                    parsePolicies();
+                    break;
+                case Tags.PROVISION_REMOTE_WIPE:
+                    // Indicate remote wipe command received
+                    mRemoteWipe = true;
+                    break;
+                default:
+                    skipTag();
+            }
+        }
+        return res;
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/Search.java b/exchange2/src/com/android/exchange/adapter/Search.java
new file mode 100644
index 0000000..62cda19
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/Search.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.emailcommon.Logging;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.service.EmailServiceStatus;
+import com.android.emailcommon.service.SearchParams;
+import com.android.emailcommon.utility.TextUtilities;
+import com.android.exchange.Eas;
+import com.android.exchange.EasResponse;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.ExchangeService;
+import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
+import com.android.mail.providers.UIProvider;
+
+import org.apache.http.HttpStatus;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Implementation of server-side search for EAS using the EmailService API
+ */
+public class Search {
+    // The shortest search query we'll accept
+    // TODO Check with UX whether this is correct
+    private static final int MIN_QUERY_LENGTH = 3;
+    // The largest number of results we'll ask for per server request
+    private static final int MAX_SEARCH_RESULTS = 100;
+
+    public static int searchMessages(Context context, long accountId, SearchParams searchParams,
+            long destMailboxId) {
+        // Sanity check for arguments
+        int offset = searchParams.mOffset;
+        int limit = searchParams.mLimit;
+        String filter = searchParams.mFilter;
+        if (limit < 0 || limit > MAX_SEARCH_RESULTS || offset < 0) return 0;
+        // TODO Should this be checked in UI?  Are there guidelines for minimums?
+        if (filter == null || filter.length() < MIN_QUERY_LENGTH) return 0;
+
+        int res = 0;
+        Account account = Account.restoreAccountWithId(context, accountId);
+        if (account == null) return res;
+        EasSyncService svc = EasSyncService.setupServiceForAccount(context, account);
+        if (svc == null) return res;
+        Mailbox searchMailbox = Mailbox.restoreMailboxWithId(context, destMailboxId);
+        // Sanity check; account might have been deleted?
+        if (searchMailbox == null) return res;
+        ContentValues statusValues = new ContentValues();
+        try {
+            // Set the status of this mailbox to indicate query
+            statusValues.put(Mailbox.UI_SYNC_STATUS, UIProvider.SyncStatus.USER_QUERY);
+            searchMailbox.update(context, statusValues);
+
+            svc.mMailbox = searchMailbox;
+            svc.mAccount = account;
+            Serializer s = new Serializer();
+            s.start(Tags.SEARCH_SEARCH).start(Tags.SEARCH_STORE);
+            s.data(Tags.SEARCH_NAME, "Mailbox");
+            s.start(Tags.SEARCH_QUERY).start(Tags.SEARCH_AND);
+            s.data(Tags.SYNC_CLASS, "Email");
+
+            // If this isn't an inbox search, then include the collection id
+            Mailbox inbox = Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_INBOX);
+            if (inbox == null) return 0;
+            if (searchParams.mMailboxId != inbox.mId) {
+                s.data(Tags.SYNC_COLLECTION_ID, inbox.mServerId);
+            }
+
+            s.data(Tags.SEARCH_FREE_TEXT, filter);
+            s.end().end();              // SEARCH_AND, SEARCH_QUERY
+            s.start(Tags.SEARCH_OPTIONS);
+            if (offset == 0) {
+                s.tag(Tags.SEARCH_REBUILD_RESULTS);
+            }
+            if (searchParams.mIncludeChildren) {
+                s.tag(Tags.SEARCH_DEEP_TRAVERSAL);
+            }
+            // Range is sent in the form first-last (e.g. 0-9)
+            s.data(Tags.SEARCH_RANGE, offset + "-" + (offset + limit - 1));
+            s.start(Tags.BASE_BODY_PREFERENCE);
+            s.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_HTML);
+            s.data(Tags.BASE_TRUNCATION_SIZE, "20000");
+            s.end();                    // BASE_BODY_PREFERENCE
+            s.end().end().end().done(); // SEARCH_OPTIONS, SEARCH_STORE, SEARCH_SEARCH
+            EasResponse resp = svc.sendHttpClientPost("Search", s.toByteArray());
+            try {
+                int code = resp.getStatus();
+                if (code == HttpStatus.SC_OK) {
+                    InputStream is = resp.getInputStream();
+                    try {
+                        SearchParser sp = new SearchParser(is, svc, filter);
+                        sp.parse();
+                        res = sp.getTotalResults();
+                    } finally {
+                        is.close();
+                    }
+                } else {
+                    svc.userLog("Search returned " + code);
+                }
+            } finally {
+                resp.close();
+            }
+        } catch (IOException e) {
+            svc.userLog("Search exception " + e);
+        } finally {
+            try {
+                // TODO: Handle error states
+                // Set the status of this mailbox to indicate query over
+                statusValues.put(Mailbox.UI_SYNC_STATUS, UIProvider.SyncStatus.NO_SYNC);
+                searchMailbox.update(context, statusValues);
+                ExchangeService.callback().syncMailboxStatus(destMailboxId,
+                        EmailServiceStatus.SUCCESS, 100);
+            } catch (RemoteException e) {
+            }
+        }
+        // Return the total count
+        return res;
+    }
+
+    /**
+     * Parse the result of a Search command
+     */
+    static class SearchParser extends Parser {
+        private final EasSyncService mService;
+        private final String mQuery;
+        private int mTotalResults;
+
+        private SearchParser(InputStream in, EasSyncService service, String query)
+                throws IOException {
+            super(in);
+            mService = service;
+            mQuery = query;
+        }
+
+        protected int getTotalResults() {
+            return mTotalResults;
+        }
+
+        @Override
+        public boolean parse() throws IOException {
+            boolean res = false;
+            if (nextTag(START_DOCUMENT) != Tags.SEARCH_SEARCH) {
+                throw new IOException();
+            }
+            while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+                if (tag == Tags.SEARCH_STATUS) {
+                    String status = getValue();
+                    if (Eas.USER_LOG) {
+                        Log.d(Logging.LOG_TAG, "Search status: " + status);
+                    }
+                } else if (tag == Tags.SEARCH_RESPONSE) {
+                    parseResponse();
+                } else {
+                    skipTag();
+                }
+            }
+            return res;
+        }
+
+        private boolean parseResponse() throws IOException {
+            boolean res = false;
+            while (nextTag(Tags.SEARCH_RESPONSE) != END) {
+                if (tag == Tags.SEARCH_STORE) {
+                    parseStore();
+                } else {
+                    skipTag();
+                }
+            }
+            return res;
+        }
+
+        private boolean parseStore() throws IOException {
+            EmailSyncAdapter adapter = new EmailSyncAdapter(mService);
+            EasEmailSyncParser parser = adapter.new EasEmailSyncParser(this, adapter);
+            ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+            boolean res = false;
+
+            while (nextTag(Tags.SEARCH_STORE) != END) {
+                if (tag == Tags.SEARCH_STATUS) {
+                    String status = getValue();
+                } else if (tag == Tags.SEARCH_TOTAL) {
+                    mTotalResults = getValueInt();
+                } else if (tag == Tags.SEARCH_RESULT) {
+                    parseResult(parser, ops);
+                } else {
+                    skipTag();
+                }
+            }
+
+            try {
+                adapter.mContentResolver.applyBatch(EmailContent.AUTHORITY, ops);
+                if (Eas.USER_LOG) {
+                    mService.userLog("Saved " + ops.size() + " search results");
+                }
+            } catch (RemoteException e) {
+                Log.d(Logging.LOG_TAG, "RemoteException while saving search results.");
+            } catch (OperationApplicationException e) {
+            }
+
+            return res;
+        }
+
+        private boolean parseResult(EasEmailSyncParser parser,
+                ArrayList<ContentProviderOperation> ops) throws IOException {
+            // Get an email sync parser for our incoming message data
+            boolean res = false;
+            Message msg = new Message();
+            while (nextTag(Tags.SEARCH_RESULT) != END) {
+                if (tag == Tags.SYNC_CLASS) {
+                    getValue();
+                } else if (tag == Tags.SYNC_COLLECTION_ID) {
+                    getValue();
+                } else if (tag == Tags.SEARCH_LONG_ID) {
+                    msg.mProtocolSearchInfo = getValue();
+                } else if (tag == Tags.SEARCH_PROPERTIES) {
+                    msg.mAccountKey = mService.mAccount.mId;
+                    msg.mMailboxKey = mService.mMailbox.mId;
+                    msg.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;
+                    parser.pushTag(tag);
+                    parser.addData(msg, tag);
+                    if (msg.mHtml != null) {
+                        msg.mHtml = TextUtilities.highlightTermsInHtml(msg.mHtml, mQuery);
+                    }
+                    msg.addSaveOps(ops);
+                } else {
+                    skipTag();
+                }
+            }
+            return res;
+        }
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/Serializer.java b/exchange2/src/com/android/exchange/adapter/Serializer.java
new file mode 100644
index 0000000..bc79603
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/Serializer.java
@@ -0,0 +1,250 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+//Contributors: Jonathan Cox, Bogdan Onoiu, Jerry Tian
+// Greatly simplified for Google, Inc. by Marc Blank
+
+package com.android.exchange.adapter;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import com.android.exchange.Eas;
+import com.android.exchange.utility.FileLogger;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class Serializer {
+    private static final String TAG = "Serializer";
+    private static final int BUFFER_SIZE = 16*1024;
+    private static final int NOT_PENDING = -1;
+
+    private final OutputStream mOutput;
+    private int mPendingTag = NOT_PENDING;
+    private int mDepth;
+    private String[] mNameStack = new String[20];
+    private int mTagPage = 0;
+    private boolean mLogging = Log.isLoggable(TAG, Log.VERBOSE);
+
+    public Serializer() throws IOException {
+        this(new ByteArrayOutputStream(), true);
+    }
+
+    public Serializer(OutputStream os) throws IOException {
+        this(os, true);
+    }
+
+    @VisibleForTesting
+    public Serializer(boolean startDocument) throws IOException {
+        this(new ByteArrayOutputStream(), startDocument);
+    }
+
+    /**
+     * Base constructor
+     * @param outputStream the stream we're serializing to
+     * @param startDocument whether or not to start a document
+     * @param _logging whether or not to log our output
+     * @throws IOException
+     */
+    public Serializer(OutputStream outputStream, boolean startDocument) throws IOException {
+        super();
+        mOutput = outputStream;
+        if (startDocument) {
+            startDocument();
+        } else {
+            mOutput.write(0);
+        }
+    }
+
+    void log(String str) {
+        int cr = str.indexOf('\n');
+        if (cr > 0) {
+            str = str.substring(0, cr);
+        }
+        Log.v(TAG, str);
+        if (Eas.FILE_LOG) {
+            FileLogger.log(TAG, str);
+        }
+    }
+
+    public void done() throws IOException {
+        if (mDepth != 0) {
+            throw new IOException("Done received with unclosed tags");
+        }
+        mOutput.flush();
+    }
+
+    public void startDocument() throws IOException{
+        mOutput.write(0x03); // version 1.3
+        mOutput.write(0x01); // unknown or missing public identifier
+        mOutput.write(106);  // UTF-8
+        mOutput.write(0);    // 0 length string array
+    }
+
+    public void checkPendingTag(boolean degenerated) throws IOException {
+        if (mPendingTag == NOT_PENDING)
+            return;
+
+        int page = mPendingTag >> Tags.PAGE_SHIFT;
+        int tag = mPendingTag & Tags.PAGE_MASK;
+        if (page != mTagPage) {
+            mTagPage = page;
+            mOutput.write(Wbxml.SWITCH_PAGE);
+            mOutput.write(page);
+        }
+
+        mOutput.write(degenerated ? tag : tag | Wbxml.WITH_CONTENT);
+        if (mLogging) {
+            String name = Tags.pages[page][tag - 5];
+            mNameStack[mDepth] = name;
+            log("<" + name + '>');
+        }
+        mPendingTag = NOT_PENDING;
+    }
+
+    public Serializer start(int tag) throws IOException {
+        checkPendingTag(false);
+        mPendingTag = tag;
+        mDepth++;
+        return this;
+    }
+
+    public Serializer end() throws IOException {
+        if (mPendingTag >= 0) {
+            checkPendingTag(true);
+        } else {
+            mOutput.write(Wbxml.END);
+            if (mLogging) {
+                log("</" + mNameStack[mDepth] + '>');
+            }
+        }
+        mDepth--;
+        return this;
+    }
+
+    public Serializer tag(int t) throws IOException {
+        start(t);
+        end();
+        return this;
+    }
+
+    public Serializer data(int tag, String value) throws IOException {
+        if (value == null) {
+            Log.e(TAG, "Writing null data for tag: " + tag);
+        }
+        start(tag);
+        text(value);
+        end();
+        return this;
+    }
+
+    public Serializer text(String text) throws IOException {
+        if (text == null) {
+            Log.e(TAG, "Writing null text for pending tag: " + mPendingTag);
+        }
+        checkPendingTag(false);
+        mOutput.write(Wbxml.STR_I);
+        writeLiteralString(mOutput, text);
+        if (mLogging) {
+            log(text);
+        }
+        return this;
+    }
+
+    public Serializer opaque(InputStream is, int length) throws IOException {
+        checkPendingTag(false);
+        mOutput.write(Wbxml.OPAQUE);
+        writeInteger(mOutput, length);
+        if (mLogging) {
+            log("Opaque, length: " + length);
+        }
+        // Now write out the opaque data in batches
+        byte[] buffer = new byte[BUFFER_SIZE];
+        while (length > 0) {
+            int bytesRead = is.read(buffer, 0, (int)Math.min(BUFFER_SIZE, length));
+            if (bytesRead == -1) {
+                break;
+            }
+            mOutput.write(buffer, 0, bytesRead);
+            length -= bytesRead;
+        }
+        return this;
+    }
+
+    public Serializer opaqueWithoutData(int length) throws IOException {
+        checkPendingTag(false);
+        mOutput.write(Wbxml.OPAQUE);
+        writeInteger(mOutput, length);
+        return this;
+    }
+
+    void writeInteger(OutputStream out, int i) throws IOException {
+        byte[] buf = new byte[5];
+        int idx = 0;
+
+        do {
+            buf[idx++] = (byte) (i & 0x7f);
+            i = i >> 7;
+        } while (i != 0);
+
+        while (idx > 1) {
+            out.write(buf[--idx] | 0x80);
+        }
+        out.write(buf[0]);
+        if (mLogging) {
+            log(Integer.toString(i));
+        }
+    }
+
+    void writeLiteralString(OutputStream out, String s) throws IOException {
+        byte[] data = s.getBytes("UTF-8");
+        out.write(data);
+        out.write(0);
+    }
+
+    void writeStringValue (ContentValues cv, String key, int tag) throws IOException {
+        String value = cv.getAsString(key);
+        if (value != null && value.length() > 0) {
+            data(tag, value);
+        } else {
+            tag(tag);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (mOutput instanceof ByteArrayOutputStream) {
+            return ((ByteArrayOutputStream)mOutput).toString();
+        }
+        throw new IllegalStateException();
+    }
+
+    public byte[] toByteArray() {
+        if (mOutput instanceof ByteArrayOutputStream) {
+            return ((ByteArrayOutputStream)mOutput).toByteArray();
+        }
+        throw new IllegalStateException();
+    }
+
+}
diff --git a/exchange2/src/com/android/exchange/adapter/SettingsParser.java b/exchange2/src/com/android/exchange/adapter/SettingsParser.java
new file mode 100644
index 0000000..2cbc753
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/SettingsParser.java
@@ -0,0 +1,82 @@
+/* Copyright (C) 2011 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import com.android.exchange.EasSyncService;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parse the result of a Settings command.
+ *
+ * We only send the Settings command in EAS 14.0 after sending a Provision command for the first
+ * time.  parse() returns true in the normal case; false if access to the account is denied due
+ * to the actual settings (e.g. if a particular device type isn't allowed by the server)
+ */
+public class SettingsParser extends Parser {
+    private final EasSyncService mService;
+
+    public SettingsParser(InputStream in, EasSyncService service) throws IOException {
+        super(in);
+        mService = service;
+    }
+
+    @Override
+    public boolean parse() throws IOException {
+        boolean res = false;
+        if (nextTag(START_DOCUMENT) != Tags.SETTINGS_SETTINGS) {
+            throw new IOException();
+        }
+        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
+            if (tag == Tags.SETTINGS_STATUS) {
+                int status = getValueInt();
+                mService.userLog("Settings status = ", status);
+                if (status == 1) {
+                    res = true;
+                } else {
+                    // Access denied = 3; others should never be seen
+                    res = false;
+                }
+            } else if (tag == Tags.SETTINGS_DEVICE_INFORMATION) {
+                parseDeviceInformation();
+            } else {
+                skipTag();
+            }
+        }
+        return res;
+    }
+
+    public void parseDeviceInformation() throws IOException {
+        while (nextTag(Tags.SETTINGS_DEVICE_INFORMATION) != END) {
+            if (tag == Tags.SETTINGS_SET) {
+                parseSet();
+            } else {
+                skipTag();
+            }
+        }
+    }
+
+    public void parseSet() throws IOException {
+        while (nextTag(Tags.SETTINGS_SET) != END) {
+            if (tag == Tags.SETTINGS_STATUS) {
+                mService.userLog("Set status = ", getValueInt());
+            } else {
+                skipTag();
+            }
+        }
+    }
+}
diff --git a/exchange2/src/com/android/exchange/adapter/Tags.java b/exchange2/src/com/android/exchange/adapter/Tags.java
new file mode 100644
index 0000000..183a103
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/Tags.java
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.adapter;
+
+/**
+ * The wbxml tags for EAS are all defined here.
+ *
+ * The static final int's, of the form <page>_<tag> = <constant> are used in parsing incoming
+ * responses from the server (i.e. EasParser and its subclasses) and sending requests to the
+ * server (via Serializer)
+ *
+ * The array of string arrays is used only for generating logging output
+ */
+public class Tags {
+
+    // Wbxml page definitions for EAS
+    public static final int AIRSYNC = 0x00;
+    public static final int CONTACTS = 0x01;
+    public static final int EMAIL = 0x02;
+    public static final int CALENDAR = 0x04;
+    public static final int MOVE = 0x05;
+    public static final int GIE = 0x06;
+    public static final int FOLDER = 0x07;
+    public static final int MREQ = 0x08;
+    public static final int TASK = 0x09;
+    public static final int CONTACTS2 = 0x0C;
+    public static final int PING = 0x0D;
+    public static final int PROVISION = 0x0E;
+    public static final int SEARCH = 0x0F;
+    public static final int GAL = 0x10;
+    public static final int BASE = 0x11;
+    public static final int SETTINGS = 0x12;
+    public static final int DOCS = 0x13;
+    public static final int ITEMS = 0x14;
+    // 14.0
+    public static final int COMPOSE = 0x15;
+    public static final int EMAIL2 = 0x16;
+    // 14.1
+    public static final int NOTES = 0x17;
+    public static final int RIGHTS = 0x18;
+
+    // Shift applied to page numbers to generate tag
+    public static final int PAGE_SHIFT = 6;
+    public static final int PAGE_MASK = 0x3F;  // 6 bits
+
+    public static final int SYNC_PAGE = 0 << PAGE_SHIFT;
+    public static final int SYNC_SYNC = SYNC_PAGE + 5;
+    public static final int SYNC_RESPONSES = SYNC_PAGE + 6;
+    public static final int SYNC_ADD = SYNC_PAGE + 7;
+    public static final int SYNC_CHANGE = SYNC_PAGE + 8;
+    public static final int SYNC_DELETE = SYNC_PAGE + 9;
+    public static final int SYNC_FETCH = SYNC_PAGE + 0xA;
+    public static final int SYNC_SYNC_KEY = SYNC_PAGE + 0xB;
+    public static final int SYNC_CLIENT_ID = SYNC_PAGE + 0xC;
+    public static final int SYNC_SERVER_ID = SYNC_PAGE + 0xD;
+    public static final int SYNC_STATUS = SYNC_PAGE + 0xE;
+    public static final int SYNC_COLLECTION = SYNC_PAGE + 0xF;
+    public static final int SYNC_CLASS = SYNC_PAGE + 0x10;
+    public static final int SYNC_VERSION = SYNC_PAGE + 0x11;
+    public static final int SYNC_COLLECTION_ID = SYNC_PAGE + 0x12;
+    public static final int SYNC_GET_CHANGES = SYNC_PAGE + 0x13;
+    public static final int SYNC_MORE_AVAILABLE = SYNC_PAGE + 0x14;
+    public static final int SYNC_WINDOW_SIZE = SYNC_PAGE + 0x15;
+    public static final int SYNC_COMMANDS = SYNC_PAGE + 0x16;
+    public static final int SYNC_OPTIONS = SYNC_PAGE + 0x17;
+    public static final int SYNC_FILTER_TYPE = SYNC_PAGE + 0x18;
+    public static final int SYNC_TRUNCATION = SYNC_PAGE + 0x19;
+    public static final int SYNC_RTF_TRUNCATION = SYNC_PAGE + 0x1A;
+    public static final int SYNC_CONFLICT = SYNC_PAGE + 0x1B;
+    public static final int SYNC_COLLECTIONS = SYNC_PAGE + 0x1C;
+    public static final int SYNC_APPLICATION_DATA = SYNC_PAGE + 0x1D;
+    public static final int SYNC_DELETES_AS_MOVES = SYNC_PAGE + 0x1E;
+    public static final int SYNC_NOTIFY_GUID = SYNC_PAGE + 0x1F;
+    public static final int SYNC_SUPPORTED = SYNC_PAGE + 0x20;
+    public static final int SYNC_SOFT_DELETE = SYNC_PAGE + 0x21;
+    public static final int SYNC_MIME_SUPPORT = SYNC_PAGE + 0x22;
+    public static final int SYNC_MIME_TRUNCATION = SYNC_PAGE + 0x23;
+    public static final int SYNC_WAIT = SYNC_PAGE + 0x24;
+    public static final int SYNC_LIMIT = SYNC_PAGE + 0x25;
+    public static final int SYNC_PARTIAL = SYNC_PAGE + 0x26;
+
+    public static final int GIE_PAGE = GIE << PAGE_SHIFT;
+    public static final int GIE_GET_ITEM_ESTIMATE = GIE_PAGE + 5;
+    public static final int GIE_VERSION = GIE_PAGE + 6;
+    public static final int GIE_COLLECTIONS = GIE_PAGE + 7;
+    public static final int GIE_COLLECTION = GIE_PAGE + 8;
+    public static final int GIE_CLASS = GIE_PAGE + 9;
+    public static final int GIE_COLLECTION_ID = GIE_PAGE + 0xA;
+    public static final int GIE_DATE_TIME = GIE_PAGE + 0xB;
+    public static final int GIE_ESTIMATE = GIE_PAGE + 0xC;
+    public static final int GIE_RESPONSE = GIE_PAGE + 0xD;
+    public static final int GIE_STATUS = GIE_PAGE + 0xE;
+
+    public static final int CONTACTS_PAGE = CONTACTS << PAGE_SHIFT;
+    public static final int CONTACTS_ANNIVERSARY = CONTACTS_PAGE + 5;
+    public static final int CONTACTS_ASSISTANT_NAME = CONTACTS_PAGE + 6;
+    public static final int CONTACTS_ASSISTANT_TELEPHONE_NUMBER = CONTACTS_PAGE + 7;
+    public static final int CONTACTS_BIRTHDAY = CONTACTS_PAGE + 8;
+    public static final int CONTACTS_BODY = CONTACTS_PAGE + 9;
+    public static final int CONTACTS_BODY_SIZE = CONTACTS_PAGE + 0xA;
+    public static final int CONTACTS_BODY_TRUNCATED = CONTACTS_PAGE + 0xB;
+    public static final int CONTACTS_BUSINESS2_TELEPHONE_NUMBER = CONTACTS_PAGE + 0xC;
+    public static final int CONTACTS_BUSINESS_ADDRESS_CITY = CONTACTS_PAGE + 0xD;
+    public static final int CONTACTS_BUSINESS_ADDRESS_COUNTRY = CONTACTS_PAGE + 0xE;
+    public static final int CONTACTS_BUSINESS_ADDRESS_POSTAL_CODE = CONTACTS_PAGE + 0xF;
+    public static final int CONTACTS_BUSINESS_ADDRESS_STATE = CONTACTS_PAGE + 0x10;
+    public static final int CONTACTS_BUSINESS_ADDRESS_STREET = CONTACTS_PAGE + 0x11;
+    public static final int CONTACTS_BUSINESS_FAX_NUMBER = CONTACTS_PAGE + 0x12;
+    public static final int CONTACTS_BUSINESS_TELEPHONE_NUMBER = CONTACTS_PAGE + 0x13;
+    public static final int CONTACTS_CAR_TELEPHONE_NUMBER = CONTACTS_PAGE + 0x14;
+    public static final int CONTACTS_CATEGORIES = CONTACTS_PAGE + 0x15;
+    public static final int CONTACTS_CATEGORY = CONTACTS_PAGE + 0x16;
+    public static final int CONTACTS_CHILDREN = CONTACTS_PAGE + 0x17;
+    public static final int CONTACTS_CHILD = CONTACTS_PAGE + 0x18;
+    public static final int CONTACTS_COMPANY_NAME = CONTACTS_PAGE + 0x19;
+    public static final int CONTACTS_DEPARTMENT = CONTACTS_PAGE + 0x1A;
+    public static final int CONTACTS_EMAIL1_ADDRESS = CONTACTS_PAGE + 0x1B;
+    public static final int CONTACTS_EMAIL2_ADDRESS = CONTACTS_PAGE + 0x1C;
+    public static final int CONTACTS_EMAIL3_ADDRESS = CONTACTS_PAGE + 0x1D;
+    public static final int CONTACTS_FILE_AS = CONTACTS_PAGE + 0x1E;
+    public static final int CONTACTS_FIRST_NAME = CONTACTS_PAGE + 0x1F;
+    public static final int CONTACTS_HOME2_TELEPHONE_NUMBER = CONTACTS_PAGE + 0x20;
+    public static final int CONTACTS_HOME_ADDRESS_CITY = CONTACTS_PAGE + 0x21;
+    public static final int CONTACTS_HOME_ADDRESS_COUNTRY = CONTACTS_PAGE + 0x22;
+    public static final int CONTACTS_HOME_ADDRESS_POSTAL_CODE = CONTACTS_PAGE + 0x23;
+    public static final int CONTACTS_HOME_ADDRESS_STATE = CONTACTS_PAGE + 0x24;
+    public static final int CONTACTS_HOME_ADDRESS_STREET = CONTACTS_PAGE + 0x25;
+    public static final int CONTACTS_HOME_FAX_NUMBER = CONTACTS_PAGE + 0x26;
+    public static final int CONTACTS_HOME_TELEPHONE_NUMBER = CONTACTS_PAGE + 0x27;
+    public static final int CONTACTS_JOB_TITLE = CONTACTS_PAGE + 0x28;
+    public static final int CONTACTS_LAST_NAME = CONTACTS_PAGE + 0x29;
+    public static final int CONTACTS_MIDDLE_NAME = CONTACTS_PAGE + 0x2A;
+    public static final int CONTACTS_MOBILE_TELEPHONE_NUMBER = CONTACTS_PAGE + 0x2B;
+    public static final int CONTACTS_OFFICE_LOCATION = CONTACTS_PAGE + 0x2C;
+    public static final int CONTACTS_OTHER_ADDRESS_CITY = CONTACTS_PAGE + 0x2D;
+    public static final int CONTACTS_OTHER_ADDRESS_COUNTRY = CONTACTS_PAGE + 0x2E;
+    public static final int CONTACTS_OTHER_ADDRESS_POSTAL_CODE = CONTACTS_PAGE + 0x2F;
+    public static final int CONTACTS_OTHER_ADDRESS_STATE = CONTACTS_PAGE + 0x30;
+    public static final int CONTACTS_OTHER_ADDRESS_STREET = CONTACTS_PAGE + 0x31;
+    public static final int CONTACTS_PAGER_NUMBER = CONTACTS_PAGE + 0x32;
+    public static final int CONTACTS_RADIO_TELEPHONE_NUMBER = CONTACTS_PAGE + 0x33;
+    public static final int CONTACTS_SPOUSE = CONTACTS_PAGE + 0x34;
+    public static final int CONTACTS_SUFFIX = CONTACTS_PAGE + 0x35;
+    public static final int CONTACTS_TITLE = CONTACTS_PAGE + 0x36;
+    public static final int CONTACTS_WEBPAGE = CONTACTS_PAGE + 0x37;
+    public static final int CONTACTS_YOMI_COMPANY_NAME = CONTACTS_PAGE + 0x38;
+    public static final int CONTACTS_YOMI_FIRST_NAME = CONTACTS_PAGE + 0x39;
+    public static final int CONTACTS_YOMI_LAST_NAME = CONTACTS_PAGE + 0x3A;
+    public static final int CONTACTS_COMPRESSED_RTF = CONTACTS_PAGE + 0x3B;
+    public static final int CONTACTS_PICTURE = CONTACTS_PAGE + 0x3C;
+
+    public static final int CALENDAR_PAGE = CALENDAR << PAGE_SHIFT;
+    public static final int CALENDAR_TIME_ZONE = CALENDAR_PAGE + 5;
+    public static final int CALENDAR_ALL_DAY_EVENT = CALENDAR_PAGE + 6;
+    public static final int CALENDAR_ATTENDEES = CALENDAR_PAGE + 7;
+    public static final int CALENDAR_ATTENDEE = CALENDAR_PAGE + 8;
+    public static final int CALENDAR_ATTENDEE_EMAIL = CALENDAR_PAGE + 9;
+    public static final int CALENDAR_ATTENDEE_NAME = CALENDAR_PAGE + 0xA;
+    public static final int CALENDAR_BODY = CALENDAR_PAGE + 0xB;
+    public static final int CALENDAR_BODY_TRUNCATED = CALENDAR_PAGE + 0xC;
+    public static final int CALENDAR_BUSY_STATUS = CALENDAR_PAGE + 0xD;
+    public static final int CALENDAR_CATEGORIES = CALENDAR_PAGE + 0xE;
+    public static final int CALENDAR_CATEGORY = CALENDAR_PAGE + 0xF;
+    public static final int CALENDAR_COMPRESSED_RTF = CALENDAR_PAGE + 0x10;
+    public static final int CALENDAR_DTSTAMP = CALENDAR_PAGE + 0x11;
+    public static final int CALENDAR_END_TIME = CALENDAR_PAGE + 0x12;
+    public static final int CALENDAR_EXCEPTION = CALENDAR_PAGE + 0x13;
+    public static final int CALENDAR_EXCEPTIONS = CALENDAR_PAGE + 0x14;
+    public static final int CALENDAR_EXCEPTION_IS_DELETED = CALENDAR_PAGE + 0x15;
+    public static final int CALENDAR_EXCEPTION_START_TIME = CALENDAR_PAGE + 0x16;
+    public static final int CALENDAR_LOCATION = CALENDAR_PAGE + 0x17;
+    public static final int CALENDAR_MEETING_STATUS = CALENDAR_PAGE + 0x18;
+    public static final int CALENDAR_ORGANIZER_EMAIL = CALENDAR_PAGE + 0x19;
+    public static final int CALENDAR_ORGANIZER_NAME = CALENDAR_PAGE + 0x1A;
+    public static final int CALENDAR_RECURRENCE = CALENDAR_PAGE + 0x1B;
+    public static final int CALENDAR_RECURRENCE_TYPE = CALENDAR_PAGE + 0x1C;
+    public static final int CALENDAR_RECURRENCE_UNTIL = CALENDAR_PAGE + 0x1D;
+    public static final int CALENDAR_RECURRENCE_OCCURRENCES = CALENDAR_PAGE + 0x1E;
+    public static final int CALENDAR_RECURRENCE_INTERVAL = CALENDAR_PAGE + 0x1F;
+    public static final int CALENDAR_RECURRENCE_DAYOFWEEK = CALENDAR_PAGE + 0x20;
+    public static final int CALENDAR_RECURRENCE_DAYOFMONTH = CALENDAR_PAGE + 0x21;
+    public static final int CALENDAR_RECURRENCE_WEEKOFMONTH = CALENDAR_PAGE + 0x22;
+    public static final int CALENDAR_RECURRENCE_MONTHOFYEAR = CALENDAR_PAGE + 0x23;
+    public static final int CALENDAR_REMINDER_MINS_BEFORE = CALENDAR_PAGE + 0x24;
+    public static final int CALENDAR_SENSITIVITY = CALENDAR_PAGE + 0x25;
+    public static final int CALENDAR_SUBJECT = CALENDAR_PAGE + 0x26;
+    public static final int CALENDAR_START_TIME = CALENDAR_PAGE + 0x27;
+    public static final int CALENDAR_UID = CALENDAR_PAGE + 0x28;
+    public static final int CALENDAR_ATTENDEE_STATUS = CALENDAR_PAGE + 0x29;
+    public static final int CALENDAR_ATTENDEE_TYPE = CALENDAR_PAGE + 0x2A;
+    public static final int CALENDAR_ATTACHMENT = CALENDAR_PAGE + 0x2B;
+    public static final int CALENDAR_ATTACHMENTS = CALENDAR_PAGE + 0x2C;
+    public static final int CALENDAR_ATT_NAME = CALENDAR_PAGE + 0x2D;
+    public static final int CALENDAR_ATT_SIZE = CALENDAR_PAGE + 0x2E;
+    public static final int CALENDAR_ATT_OID = CALENDAR_PAGE + 0x2F;
+    public static final int CALENDAR_ATT_METHOD = CALENDAR_PAGE + 0x30;
+    public static final int CALENDAR_ATT_REMOVED = CALENDAR_PAGE + 0x31;
+    public static final int CALENDAR_DISPLAY_NAME = CALENDAR_PAGE + 0x32;
+    public static final int CALENDAR_DISALLOW_NEW_TIME_PROPOSAL = CALENDAR_PAGE + 0x33;
+    public static final int CALENDAR_RESPONSE_REQUESTED = CALENDAR_PAGE + 0x34;
+    public static final int CALENDAR_APPOINTMENT_REPLY_TIME = CALENDAR_PAGE + 0x35;
+    public static final int CALENDAR_RESPONSE_TYPE = CALENDAR_PAGE + 0x36;
+    public static final int CALENDAR_CALENDAR_TYPE = CALENDAR_PAGE + 0x37;
+    public static final int CALENDAR_IS_LEAP_MONTH = CALENDAR_PAGE + 0x38;
+    public static final int CALENDAR_FIRST_DAY_OF_WEEK = CALENDAR_PAGE + 0x39;
+    public static final int CALENDAR_ONLINE_MEETING_CONFLINK = CALENDAR_PAGE + 0x3A;
+    public static final int CALENDAR_ONLINE_MEETING_EXTERNAL_LINK = CALENDAR_PAGE + 0x3B;
+
+    public static final int FOLDER_PAGE = FOLDER << PAGE_SHIFT;
+    public static final int FOLDER_FOLDERS = FOLDER_PAGE + 5;
+    public static final int FOLDER_FOLDER = FOLDER_PAGE + 6;
+    public static final int FOLDER_DISPLAY_NAME = FOLDER_PAGE + 7;
+    public static final int FOLDER_SERVER_ID = FOLDER_PAGE + 8;
+    public static final int FOLDER_PARENT_ID = FOLDER_PAGE + 9;
+    public static final int FOLDER_TYPE = FOLDER_PAGE + 0xA;
+    public static final int FOLDER_RESPONSE = FOLDER_PAGE + 0xB;
+    public static final int FOLDER_STATUS = FOLDER_PAGE + 0xC;
+    public static final int FOLDER_CONTENT_CLASS = FOLDER_PAGE + 0xD;
+    public static final int FOLDER_CHANGES = FOLDER_PAGE + 0xE;
+    public static final int FOLDER_ADD = FOLDER_PAGE + 0xF;
+    public static final int FOLDER_DELETE = FOLDER_PAGE + 0x10;
+    public static final int FOLDER_UPDATE = FOLDER_PAGE + 0x11;
+    public static final int FOLDER_SYNC_KEY = FOLDER_PAGE + 0x12;
+    public static final int FOLDER_FOLDER_CREATE = FOLDER_PAGE + 0x13;
+    public static final int FOLDER_FOLDER_DELETE= FOLDER_PAGE + 0x14;
+    public static final int FOLDER_FOLDER_UPDATE = FOLDER_PAGE + 0x15;
+    public static final int FOLDER_FOLDER_SYNC = FOLDER_PAGE + 0x16;
+    public static final int FOLDER_COUNT = FOLDER_PAGE + 0x17;
+    public static final int FOLDER_VERSION = FOLDER_PAGE + 0x18;
+
+    public static final int MREQ_PAGE = MREQ << PAGE_SHIFT;
+    public static final int MREQ_CAL_ID = MREQ_PAGE + 5;
+    public static final int MREQ_COLLECTION_ID = MREQ_PAGE + 6;
+    public static final int MREQ_MEETING_RESPONSE = MREQ_PAGE + 7;
+    public static final int MREQ_REQ_ID = MREQ_PAGE + 8;
+    public static final int MREQ_REQUEST = MREQ_PAGE + 9;
+    public static final int MREQ_RESULT = MREQ_PAGE + 0xA;
+    public static final int MREQ_STATUS = MREQ_PAGE + 0xB;
+    public static final int MREQ_USER_RESPONSE = MREQ_PAGE + 0xC;
+    public static final int MREQ_VERSION = MREQ_PAGE + 0xD;
+
+    public static final int EMAIL_PAGE = EMAIL << PAGE_SHIFT;
+    public static final int EMAIL_ATTACHMENT = EMAIL_PAGE + 5;
+    public static final int EMAIL_ATTACHMENTS = EMAIL_PAGE + 6;
+    public static final int EMAIL_ATT_NAME = EMAIL_PAGE + 7;
+    public static final int EMAIL_ATT_SIZE = EMAIL_PAGE + 8;
+    public static final int EMAIL_ATT0ID = EMAIL_PAGE + 9;
+    public static final int EMAIL_ATT_METHOD = EMAIL_PAGE + 0xA;
+    public static final int EMAIL_ATT_REMOVED = EMAIL_PAGE + 0xB;
+    public static final int EMAIL_BODY = EMAIL_PAGE + 0xC;
+    public static final int EMAIL_BODY_SIZE = EMAIL_PAGE + 0xD;
+    public static final int EMAIL_BODY_TRUNCATED = EMAIL_PAGE + 0xE;
+    public static final int EMAIL_DATE_RECEIVED = EMAIL_PAGE + 0xF;
+    public static final int EMAIL_DISPLAY_NAME = EMAIL_PAGE + 0x10;
+    public static final int EMAIL_DISPLAY_TO = EMAIL_PAGE + 0x11;
+    public static final int EMAIL_IMPORTANCE = EMAIL_PAGE + 0x12;
+    public static final int EMAIL_MESSAGE_CLASS = EMAIL_PAGE + 0x13;
+    public static final int EMAIL_SUBJECT = EMAIL_PAGE + 0x14;
+    public static final int EMAIL_READ = EMAIL_PAGE + 0x15;
+    public static final int EMAIL_TO = EMAIL_PAGE + 0x16;
+    public static final int EMAIL_CC = EMAIL_PAGE + 0x17;
+    public static final int EMAIL_FROM = EMAIL_PAGE + 0x18;
+    public static final int EMAIL_REPLY_TO = EMAIL_PAGE + 0x19;
+    public static final int EMAIL_ALL_DAY_EVENT = EMAIL_PAGE + 0x1A;
+    public static final int EMAIL_CATEGORIES = EMAIL_PAGE + 0x1B;
+    public static final int EMAIL_CATEGORY = EMAIL_PAGE + 0x1C;
+    public static final int EMAIL_DTSTAMP = EMAIL_PAGE + 0x1D;
+    public static final int EMAIL_END_TIME = EMAIL_PAGE + 0x1E;
+    public static final int EMAIL_INSTANCE_TYPE = EMAIL_PAGE + 0x1F;
+    public static final int EMAIL_INTD_BUSY_STATUS = EMAIL_PAGE + 0x20;
+    public static final int EMAIL_LOCATION = EMAIL_PAGE + 0x21;
+    public static final int EMAIL_MEETING_REQUEST = EMAIL_PAGE + 0x22;
+    public static final int EMAIL_ORGANIZER = EMAIL_PAGE + 0x23;
+    public static final int EMAIL_RECURRENCE_ID = EMAIL_PAGE + 0x24;
+    public static final int EMAIL_REMINDER = EMAIL_PAGE + 0x25;
+    public static final int EMAIL_RESPONSE_REQUESTED = EMAIL_PAGE + 0x26;
+    public static final int EMAIL_RECURRENCES = EMAIL_PAGE + 0x27;
+    public static final int EMAIL_RECURRENCE = EMAIL_PAGE + 0x28;
+    public static final int EMAIL_RECURRENCE_TYPE = EMAIL_PAGE + 0x29;
+    public static final int EMAIL_RECURRENCE_UNTIL = EMAIL_PAGE + 0x2A;
+    public static final int EMAIL_RECURRENCE_OCCURRENCES = EMAIL_PAGE + 0x2B;
+    public static final int EMAIL_RECURRENCE_INTERVAL = EMAIL_PAGE + 0x2C;
+    public static final int EMAIL_RECURRENCE_DAYOFWEEK = EMAIL_PAGE + 0x2D;
+    public static final int EMAIL_RECURRENCE_DAYOFMONTH = EMAIL_PAGE + 0x2E;
+    public static final int EMAIL_RECURRENCE_WEEKOFMONTH = EMAIL_PAGE + 0x2F;
+    public static final int EMAIL_RECURRENCE_MONTHOFYEAR = EMAIL_PAGE + 0x30;
+    public static final int EMAIL_START_TIME = EMAIL_PAGE + 0x31;
+    public static final int EMAIL_SENSITIVITY = EMAIL_PAGE + 0x32;
+    public static final int EMAIL_TIME_ZONE = EMAIL_PAGE + 0x33;
+    public static final int EMAIL_GLOBAL_OBJID = EMAIL_PAGE + 0x34;
+    public static final int EMAIL_THREAD_TOPIC = EMAIL_PAGE + 0x35;
+    public static final int EMAIL_MIME_DATA = EMAIL_PAGE + 0x36;
+    public static final int EMAIL_MIME_TRUNCATED = EMAIL_PAGE + 0x37;
+    public static final int EMAIL_MIME_SIZE = EMAIL_PAGE + 0x38;
+    public static final int EMAIL_INTERNET_CPID = EMAIL_PAGE + 0x39;
+    public static final int EMAIL_FLAG = EMAIL_PAGE + 0x3A;
+    public static final int EMAIL_FLAG_STATUS = EMAIL_PAGE + 0x3B;
+    public static final int EMAIL_CONTENT_CLASS = EMAIL_PAGE + 0x3C;
+    public static final int EMAIL_FLAG_TYPE = EMAIL_PAGE + 0x3D;
+    public static final int EMAIL_COMPLETE_TIME = EMAIL_PAGE + 0x3E;
+    public static final int EMAIL_DISALLOW_NEW_TIME_PROPOSAL = EMAIL_PAGE + 0x3F;
+
+    public static final int TASK_PAGE = TASK << PAGE_SHIFT;
+    public static final int TASK_BODY = TASK_PAGE + 5;
+    public static final int TASK_BODY_SIZE = TASK_PAGE + 6;
+    public static final int TASK_BODY_TRUNCATED = TASK_PAGE + 7;
+    public static final int TASK_CATEGORIES = TASK_PAGE + 8;
+    public static final int TASK_CATEGORY = TASK_PAGE + 9;
+    public static final int TASK_COMPLETE = TASK_PAGE + 0xA;
+    public static final int TASK_DATE_COMPLETED = TASK_PAGE + 0xB;
+    public static final int TASK_DUE_DATE = TASK_PAGE + 0xC;
+    public static final int TASK_UTC_DUE_DATE = TASK_PAGE + 0xD;
+    public static final int TASK_IMPORTANCE = TASK_PAGE + 0xE;
+    public static final int TASK_RECURRENCE = TASK_PAGE + 0xF;
+    public static final int TASK_RECURRENCE_TYPE = TASK_PAGE + 0x10;
+    public static final int TASK_RECURRENCE_START = TASK_PAGE + 0x11;
+    public static final int TASK_RECURRENCE_UNTIL = TASK_PAGE + 0x12;
+    public static final int TASK_RECURRENCE_OCCURRENCES = TASK_PAGE + 0x13;
+    public static final int TASK_RECURRENCE_INTERVAL = TASK_PAGE + 0x14;
+    public static final int TASK_RECURRENCE_DAY_OF_MONTH = TASK_PAGE + 0x15;
+    public static final int TASK_RECURRENCE_DAY_OF_WEEK = TASK_PAGE + 0x16;
+    public static final int TASK_RECURRENCE_WEEK_OF_MONTH = TASK_PAGE + 0x17;
+    public static final int TASK_RECURRENCE_MONTH_OF_YEAR = TASK_PAGE + 0x18;
+    public static final int TASK_RECURRENCE_REGENERATE = TASK_PAGE + 0x19;
+    public static final int TASK_RECURRENCE_DEAD_OCCUR = TASK_PAGE + 0x1A;
+    public static final int TASK_REMINDER_SET = TASK_PAGE + 0x1B;
+    public static final int TASK_REMINDER_TIME = TASK_PAGE + 0x1C;
+    public static final int TASK_SENSITIVITY = TASK_PAGE + 0x1D;
+    public static final int TASK_START_DATE = TASK_PAGE + 0x1E;
+    public static final int TASK_UTC_START_DATE = TASK_PAGE + 0x1F;
+    public static final int TASK_SUBJECT = TASK_PAGE + 0x20;
+    public static final int COMPRESSED_RTF = TASK_PAGE + 0x21;
+    public static final int ORDINAL_DATE = TASK_PAGE + 0x22;
+    public static final int SUBORDINAL_DATE = TASK_PAGE + 0x23;
+
+    public static final int MOVE_PAGE = MOVE << PAGE_SHIFT;
+    public static final int MOVE_MOVE_ITEMS = MOVE_PAGE + 5;
+    public static final int MOVE_MOVE = MOVE_PAGE + 6;
+    public static final int MOVE_SRCMSGID = MOVE_PAGE + 7;
+    public static final int MOVE_SRCFLDID = MOVE_PAGE + 8;
+    public static final int MOVE_DSTFLDID = MOVE_PAGE + 9;
+    public static final int MOVE_RESPONSE = MOVE_PAGE + 0xA;
+    public static final int MOVE_STATUS = MOVE_PAGE + 0xB;
+    public static final int MOVE_DSTMSGID = MOVE_PAGE + 0xC;
+
+    public static final int CONTACTS2_PAGE = CONTACTS2 << PAGE_SHIFT;
+    public static final int CONTACTS2_CUSTOMER_ID = CONTACTS2_PAGE + 5;
+    public static final int CONTACTS2_GOVERNMENT_ID = CONTACTS2_PAGE + 6;
+    public static final int CONTACTS2_IM_ADDRESS = CONTACTS2_PAGE + 7;
+    public static final int CONTACTS2_IM_ADDRESS_2 = CONTACTS2_PAGE + 8;
+    public static final int CONTACTS2_IM_ADDRESS_3 = CONTACTS2_PAGE + 9;
+    public static final int CONTACTS2_MANAGER_NAME = CONTACTS2_PAGE + 0xA;
+    public static final int CONTACTS2_COMPANY_MAIN_PHONE = CONTACTS2_PAGE + 0xB;
+    public static final int CONTACTS2_ACCOUNT_NAME = CONTACTS2_PAGE + 0xC;
+    public static final int CONTACTS2_NICKNAME = CONTACTS2_PAGE + 0xD;
+    public static final int CONTACTS2_MMS = CONTACTS2_PAGE + 0xE;
+
+    public static final int PING_PAGE = PING << PAGE_SHIFT;
+    public static final int PING_PING = PING_PAGE + 5;
+    public static final int PING_AUTD_STATE = PING_PAGE + 6;
+    public static final int PING_STATUS = PING_PAGE + 7;
+    public static final int PING_HEARTBEAT_INTERVAL = PING_PAGE + 8;
+    public static final int PING_FOLDERS = PING_PAGE + 9;
+    public static final int PING_FOLDER = PING_PAGE + 0xA;
+    public static final int PING_ID = PING_PAGE + 0xB;
+    public static final int PING_CLASS = PING_PAGE + 0xC;
+    public static final int PING_MAX_FOLDERS = PING_PAGE + 0xD;
+
+    public static final int SEARCH_PAGE = SEARCH << PAGE_SHIFT;
+    public static final int SEARCH_SEARCH = SEARCH_PAGE + 5;
+    public static final int SEARCH_STORES = SEARCH_PAGE + 6;
+    public static final int SEARCH_STORE = SEARCH_PAGE + 7;
+    public static final int SEARCH_NAME = SEARCH_PAGE + 8;
+    public static final int SEARCH_QUERY = SEARCH_PAGE + 9;
+    public static final int SEARCH_OPTIONS = SEARCH_PAGE + 0xA;
+    public static final int SEARCH_RANGE = SEARCH_PAGE + 0xB;
+    public static final int SEARCH_STATUS = SEARCH_PAGE + 0xC;
+    public static final int SEARCH_RESPONSE = SEARCH_PAGE + 0xD;
+    public static final int SEARCH_RESULT = SEARCH_PAGE + 0xE;
+    public static final int SEARCH_PROPERTIES = SEARCH_PAGE + 0xF;
+    public static final int SEARCH_TOTAL = SEARCH_PAGE + 0x10;
+    public static final int SEARCH_EQUAL_TO = SEARCH_PAGE + 0x11;
+    public static final int SEARCH_VALUE = SEARCH_PAGE + 0x12;
+    public static final int SEARCH_AND = SEARCH_PAGE + 0x13;
+    public static final int SEARCH_OR = SEARCH_PAGE + 0x14;
+    public static final int SEARCH_FREE_TEXT = SEARCH_PAGE + 0x15;
+    public static final int SEARCH_SUBSTRING_OP = SEARCH_PAGE + 0x16;
+    public static final int SEARCH_DEEP_TRAVERSAL = SEARCH_PAGE + 0x17;
+    public static final int SEARCH_LONG_ID = SEARCH_PAGE + 0x18;
+    public static final int SEARCH_REBUILD_RESULTS = SEARCH_PAGE + 0x19;
+    public static final int SEARCH_LESS_THAN = SEARCH_PAGE + 0x1A;
+    public static final int SEARCH_GREATER_THAN = SEARCH_PAGE + 0x1B;
+    public static final int SEARCH_SCHEMA = SEARCH_PAGE + 0x1C;
+    public static final int SEARCH_SUPPORTED = SEARCH_PAGE + 0x1D;
+
+    public static final int GAL_PAGE = GAL << PAGE_SHIFT;
+    public static final int GAL_DISPLAY_NAME = GAL_PAGE + 5;
+    public static final int GAL_PHONE = GAL_PAGE + 6;
+    public static final int GAL_OFFICE = GAL_PAGE + 7;
+    public static final int GAL_TITLE = GAL_PAGE + 8;
+    public static final int GAL_COMPANY = GAL_PAGE + 9;
+    public static final int GAL_ALIAS = GAL_PAGE + 0xA;
+    public static final int GAL_FIRST_NAME = GAL_PAGE + 0xB;
+    public static final int GAL_LAST_NAME = GAL_PAGE + 0xC;
+    public static final int GAL_HOME_PHONE = GAL_PAGE + 0xD;
+    public static final int GAL_MOBILE_PHONE = GAL_PAGE + 0xE;
+    public static final int GAL_EMAIL_ADDRESS = GAL_PAGE + 0xF;
+
+    public static final int PROVISION_PAGE = PROVISION << PAGE_SHIFT;
+    // EAS 2.5
+    public static final int PROVISION_PROVISION = PROVISION_PAGE + 5;
+    public static final int PROVISION_POLICIES = PROVISION_PAGE + 6;
+    public static final int PROVISION_POLICY = PROVISION_PAGE + 7;
+    public static final int PROVISION_POLICY_TYPE = PROVISION_PAGE + 8;
+    public static final int PROVISION_POLICY_KEY = PROVISION_PAGE + 9;
+    public static final int PROVISION_DATA = PROVISION_PAGE + 0xA;
+    public static final int PROVISION_STATUS = PROVISION_PAGE + 0xB;
+    public static final int PROVISION_REMOTE_WIPE = PROVISION_PAGE + 0xC;
+    // EAS 12.0
+    public static final int PROVISION_EAS_PROVISION_DOC = PROVISION_PAGE + 0xD;
+    public static final int PROVISION_DEVICE_PASSWORD_ENABLED = PROVISION_PAGE + 0xE;
+    public static final int PROVISION_ALPHA_DEVICE_PASSWORD_ENABLED = PROVISION_PAGE + 0xF;
+    public static final int PROVISION_DEVICE_ENCRYPTION_ENABLED = PROVISION_PAGE + 0x10;
+    public static final int PROVISION_PASSWORD_RECOVERY_ENABLED = PROVISION_PAGE + 0x11;
+    public static final int PROVISION_ATTACHMENTS_ENABLED = PROVISION_PAGE + 0x13;
+    public static final int PROVISION_MIN_DEVICE_PASSWORD_LENGTH = PROVISION_PAGE + 0x14;
+    public static final int PROVISION_MAX_INACTIVITY_TIME_DEVICE_LOCK = PROVISION_PAGE + 0x15;
+    public static final int PROVISION_MAX_DEVICE_PASSWORD_FAILED_ATTEMPTS = PROVISION_PAGE + 0x16;
+    public static final int PROVISION_MAX_ATTACHMENT_SIZE = PROVISION_PAGE + 0x17;
+    public static final int PROVISION_ALLOW_SIMPLE_DEVICE_PASSWORD = PROVISION_PAGE + 0x18;
+    public static final int PROVISION_DEVICE_PASSWORD_EXPIRATION = PROVISION_PAGE + 0x19;
+    public static final int PROVISION_DEVICE_PASSWORD_HISTORY = PROVISION_PAGE + 0x1A;
+    public static final int PROVISION_MAX_SUPPORTED_TAG = PROVISION_DEVICE_PASSWORD_HISTORY;
+
+    // EAS 12.1
+    public static final int PROVISION_ALLOW_STORAGE_CARD = PROVISION_PAGE + 0x1B;
+    public static final int PROVISION_ALLOW_CAMERA = PROVISION_PAGE + 0x1C;
+    public static final int PROVISION_REQUIRE_DEVICE_ENCRYPTION = PROVISION_PAGE + 0x1D;
+    public static final int PROVISION_ALLOW_UNSIGNED_APPLICATIONS = PROVISION_PAGE + 0x1E;
+    public static final int PROVISION_ALLOW_UNSIGNED_INSTALLATION_PACKAGES = PROVISION_PAGE + 0x1F;
+    public static final int PROVISION_MIN_DEVICE_PASSWORD_COMPLEX_CHARS = PROVISION_PAGE + 0x20;
+    public static final int PROVISION_ALLOW_WIFI = PROVISION_PAGE + 0x21;
+    public static final int PROVISION_ALLOW_TEXT_MESSAGING = PROVISION_PAGE + 0x22;
+    public static final int PROVISION_ALLOW_POP_IMAP_EMAIL = PROVISION_PAGE + 0x23;
+    public static final int PROVISION_ALLOW_BLUETOOTH = PROVISION_PAGE + 0x24;
+    public static final int PROVISION_ALLOW_IRDA = PROVISION_PAGE + 0x25;
+    public static final int PROVISION_REQUIRE_MANUAL_SYNC_WHEN_ROAMING = PROVISION_PAGE + 0x26;
+    public static final int PROVISION_ALLOW_DESKTOP_SYNC = PROVISION_PAGE + 0x27;
+    public static final int PROVISION_MAX_CALENDAR_AGE_FILTER = PROVISION_PAGE + 0x28;
+    public static final int PROVISION_ALLOW_HTML_EMAIL = PROVISION_PAGE + 0x29;
+    public static final int PROVISION_MAX_EMAIL_AGE_FILTER = PROVISION_PAGE + 0x2A;
+    public static final int PROVISION_MAX_EMAIL_BODY_TRUNCATION_SIZE = PROVISION_PAGE + 0x2B;
+    public static final int PROVISION_MAX_EMAIL_HTML_BODY_TRUNCATION_SIZE = PROVISION_PAGE + 0x2C;
+    public static final int PROVISION_REQUIRE_SIGNED_SMIME_MESSAGES = PROVISION_PAGE + 0x2D;
+    public static final int PROVISION_REQUIRE_ENCRYPTED_SMIME_MESSAGES = PROVISION_PAGE + 0x2E;
+    public static final int PROVISION_REQUIRE_SIGNED_SMIME_ALGORITHM = PROVISION_PAGE + 0x2F;
+    public static final int PROVISION_REQUIRE_ENCRYPTION_SMIME_ALGORITHM = PROVISION_PAGE + 0x30;
+    public static final int PROVISION_ALLOW_SMIME_ENCRYPTION_NEGOTIATION = PROVISION_PAGE + 0x31;
+    public static final int PROVISION_ALLOW_SMIME_SOFT_CERTS = PROVISION_PAGE + 0x32;
+    public static final int PROVISION_ALLOW_BROWSER = PROVISION_PAGE + 0x33;
+    public static final int PROVISION_ALLOW_CONSUMER_EMAIL = PROVISION_PAGE + 0x34;
+    public static final int PROVISION_ALLOW_REMOTE_DESKTOP = PROVISION_PAGE + 0x35;
+    public static final int PROVISION_ALLOW_INTERNET_SHARING = PROVISION_PAGE + 0x36;
+    public static final int PROVISION_UNAPPROVED_IN_ROM_APPLICATION_LIST = PROVISION_PAGE + 0x37;
+    public static final int PROVISION_APPLICATION_NAME = PROVISION_PAGE + 0x38;
+    public static final int PROVISION_APPROVED_APPLICATION_LIST = PROVISION_PAGE + 0x39;
+    public static final int PROVISION_HASH = PROVISION_PAGE + 0x3A;
+
+    public static final int BASE_PAGE = BASE << PAGE_SHIFT;
+    public static final int BASE_BODY_PREFERENCE = BASE_PAGE + 5;
+    public static final int BASE_TYPE = BASE_PAGE + 6;
+    public static final int BASE_TRUNCATION_SIZE = BASE_PAGE + 7;
+    public static final int BASE_ALL_OR_NONE = BASE_PAGE + 8;
+    public static final int BASE_RESERVED = BASE_PAGE + 9;
+    public static final int BASE_BODY = BASE_PAGE + 0xA;
+    public static final int BASE_DATA = BASE_PAGE + 0xB;
+    public static final int BASE_ESTIMATED_DATA_SIZE = BASE_PAGE + 0xC;
+    public static final int BASE_TRUNCATED = BASE_PAGE + 0xD;
+    public static final int BASE_ATTACHMENTS = BASE_PAGE + 0xE;
+    public static final int BASE_ATTACHMENT = BASE_PAGE + 0xF;
+    public static final int BASE_DISPLAY_NAME = BASE_PAGE + 0x10;
+    public static final int BASE_FILE_REFERENCE = BASE_PAGE + 0x11;
+    public static final int BASE_METHOD = BASE_PAGE + 0x12;
+    public static final int BASE_CONTENT_ID = BASE_PAGE + 0x13;
+    public static final int BASE_CONTENT_LOCATION = BASE_PAGE + 0x14;
+    public static final int BASE_IS_INLINE = BASE_PAGE + 0x15;
+    public static final int BASE_NATIVE_BODY_TYPE = BASE_PAGE + 0x16;
+    public static final int BASE_CONTENT_TYPE = BASE_PAGE + 0x17;
+
+    public static final int SETTINGS_PAGE = SETTINGS << PAGE_SHIFT;
+    public static final int SETTINGS_SETTINGS = SETTINGS_PAGE + 5;
+    public static final int SETTINGS_STATUS = SETTINGS_PAGE + 6;
+    public static final int SETTINGS_GET = SETTINGS_PAGE + 7;
+    public static final int SETTINGS_SET = SETTINGS_PAGE + 8;
+    public static final int SETTINGS_OOF = SETTINGS_PAGE + 9;
+    public static final int SETTINGS_OOF_STATE = SETTINGS_PAGE + 0xA;
+    public static final int SETTINGS_START_TIME = SETTINGS_PAGE + 0xB;
+    public static final int SETTINGS_END_TIME = SETTINGS_PAGE + 0xC;
+    public static final int SETTINGS_OOF_MESSAGE = SETTINGS_PAGE + 0xD;
+    public static final int SETTINGS_APPLIES_TO_INTERNAL = SETTINGS_PAGE + 0xE;
+    public static final int SETTINGS_APPLIES_TO_EXTERNAL_KNOWN = SETTINGS_PAGE + 0xF;
+    public static final int SETTINGS_APPLIES_TO_EXTERNAL_UNKNOWN = SETTINGS_PAGE + 0x10;
+    public static final int SETTINGS_ENABLED = SETTINGS_PAGE + 0x11;
+    public static final int SETTINGS_REPLY_MESSAGE = SETTINGS_PAGE + 0x12;
+    public static final int SETTINGS_BODY_TYPE = SETTINGS_PAGE + 0x13;
+    public static final int SETTINGS_DEVICE_PASSWORD = SETTINGS_PAGE + 0x14;
+    public static final int SETTINGS_PASSWORD = SETTINGS_PAGE + 0x15;
+    public static final int SETTINGS_DEVICE_INFORMATION = SETTINGS_PAGE + 0x16;
+    public static final int SETTINGS_MODEL = SETTINGS_PAGE + 0x17;
+    public static final int SETTINGS_IMEI = SETTINGS_PAGE + 0x18;
+    public static final int SETTINGS_FRIENDLY_NAME = SETTINGS_PAGE + 0x19;
+    public static final int SETTINGS_OS = SETTINGS_PAGE + 0x1A;
+    public static final int SETTINGS_OS_LANGUAGE = SETTINGS_PAGE + 0x1B;
+    public static final int SETTINGS_PHONE_NUMBER = SETTINGS_PAGE + 0x1C;
+    public static final int SETTINGS_USER_INFORMATION = SETTINGS_PAGE + 0x1D;
+    public static final int SETTINGS_EMAIL_ADDRESS = SETTINGS_PAGE + 0x1E;
+    public static final int SETTINGS_SMTP_ADDRESS = SETTINGS_PAGE + 0x1F;
+    public static final int SETTINGS_USER_AGENT = SETTINGS_PAGE + 0x20;
+    public static final int SETTINGS_ENABLE_OUTGOING_SMS = SETTINGS_PAGE + 0x21;
+    public static final int SETTINGS_MOBILE_OPERATOR = SETTINGS_PAGE + 0x22;
+
+    public static final int ITEMS_PAGE = ITEMS << PAGE_SHIFT;
+    public static final int ITEMS_ITEMS = ITEMS_PAGE + 5;
+    public static final int ITEMS_FETCH = ITEMS_PAGE + 6;
+    public static final int ITEMS_STORE = ITEMS_PAGE + 7;
+    public static final int ITEMS_OPTIONS = ITEMS_PAGE + 8;
+    public static final int ITEMS_RANGE = ITEMS_PAGE + 9;
+    public static final int ITEMS_TOTAL = ITEMS_PAGE + 0xA;
+    public static final int ITEMS_PROPERTIES = ITEMS_PAGE + 0xB;
+    public static final int ITEMS_DATA = ITEMS_PAGE + 0xC;
+    public static final int ITEMS_STATUS = ITEMS_PAGE + 0xD;
+    public static final int ITEMS_RESPONSE = ITEMS_PAGE + 0xE;
+    public static final int ITEMS_VERSION = ITEMS_PAGE + 0xF;
+    public static final int ITEMS_SCHEMA = ITEMS_PAGE + 0x10;
+    public static final int ITEMS_PART = ITEMS_PAGE + 0x11;
+    public static final int ITEMS_EMPTY_FOLDER = ITEMS_PAGE + 0x12;
+    public static final int ITEMS_DELETE_SUB_FOLDERS = ITEMS_PAGE + 0x13;
+    public static final int ITEMS_USERNAME = ITEMS_PAGE + 0x14;
+    public static final int ITEMS_PASSWORD = ITEMS_PAGE + 0x15;
+    public static final int ITEMS_MOVE = ITEMS_PAGE + 0x16;
+    public static final int ITEMS_DSTFLDID = ITEMS_PAGE + 0x17;
+    public static final int ITEMS_CONVERSATION_ID = ITEMS_PAGE + 0x18;
+    public static final int ITEMS_MOVE_ALWAYS = ITEMS_PAGE + 0x19;
+
+    public static final int COMPOSE_PAGE = COMPOSE << PAGE_SHIFT;
+    public static final int COMPOSE_SEND_MAIL = COMPOSE_PAGE + 5;
+    public static final int COMPOSE_SMART_FORWARD = COMPOSE_PAGE + 6;
+    public static final int COMPOSE_SMART_REPLY = COMPOSE_PAGE + 7;
+    public static final int COMPOSE_SAVE_IN_SENT_ITEMS = COMPOSE_PAGE + 8;
+    public static final int COMPOSE_REPLACE_MIME = COMPOSE_PAGE + 9;
+    // There no tag for COMPOSE_PAGE + 0xA
+    public static final int COMPOSE_SOURCE = COMPOSE_PAGE + 0xB;
+    public static final int COMPOSE_FOLDER_ID = COMPOSE_PAGE + 0xC;
+    public static final int COMPOSE_ITEM_ID = COMPOSE_PAGE + 0xD;
+    public static final int COMPOSE_LONG_ID = COMPOSE_PAGE + 0xE;
+    public static final int COMPOSE_INSTANCE_ID = COMPOSE_PAGE + 0xF;
+    public static final int COMPOSE_MIME = COMPOSE_PAGE + 0x10;
+    public static final int COMPOSE_CLIENT_ID = COMPOSE_PAGE + 0x11;
+    public static final int COMPOSE_STATUS = COMPOSE_PAGE + 0x12;
+    public static final int COMPOSE_ACCOUNT_ID = COMPOSE_PAGE + 0x13;
+
+    public static final int EMAIL2_PAGE = EMAIL2 << PAGE_SHIFT;
+    public static final int EMAIL2_UM_CALLER_ID = EMAIL2_PAGE + 5;
+    public static final int EMAIL2_UM_USER_NOTES = EMAIL2_PAGE + 6;
+    public static final int EMAIL2_UM_ATT_DURATION = EMAIL2_PAGE + 7;
+    public static final int EMAIL2_UM_ATT_ORDER = EMAIL2_PAGE + 8;
+    public static final int EMAIL2_CONVERSATION_ID = EMAIL2_PAGE + 9;
+    public static final int EMAIL2_CONVERSATION_INDEX = EMAIL2_PAGE + 0xA;
+    public static final int EMAIL2_LAST_VERB_EXECUTED = EMAIL2_PAGE + 0xB;
+    public static final int EMAIL2_LAST_VERB_EXECUTION_TIME = EMAIL2_PAGE + 0xC;
+    public static final int EMAIL2_RECEIVED_AS_BCC = EMAIL2_PAGE + 0xD;
+    public static final int EMAIL2_SENDER = EMAIL2_PAGE + 0xE;
+    public static final int EMAIL2_CALENDAR_TYPE = EMAIL2_PAGE + 0xF;
+    public static final int EMAIL2_IS_LEAP_MONTH = EMAIL2_PAGE + 0x10;
+    public static final int EMAIL2_ACCOUNT_ID = EMAIL2_PAGE + 0x11;
+    public static final int EMAIL2_FIRST_DAY_OF_WEEK = EMAIL2_PAGE + 0x12;
+    public static final int EMAIL2_MEETING_MESSAGE_TYPE = EMAIL2_PAGE + 0x13;
+
+    public static final int RIGHTS_PAGE = RIGHTS << PAGE_SHIFT;
+    public static final int RIGHTS_SUPPORT = RIGHTS_PAGE + 5;
+    public static final int RIGHTS_TEMPLATES = RIGHTS_PAGE + 6;
+    public static final int RIGHTS_TEMPLATE = RIGHTS_PAGE + 7;
+    public static final int RIGHTS_LICENSE = RIGHTS_PAGE + 8;
+    public static final int RIGHTS_EDIT_ALLOWED = RIGHTS_PAGE + 9;
+    public static final int RIGHTS_REPLY_ALLOWED = RIGHTS_PAGE + 0xA;
+    public static final int RIGHTS_REPLY_ALL_ALLOWED = RIGHTS_PAGE + 0xB;
+    public static final int RIGHTS_FORWARD_ALLOWED = RIGHTS_PAGE + 0xC;
+    public static final int RIGHTS_MODIFY_RECIPIENTS_ALLOWED = RIGHTS_PAGE + 0xD;
+    public static final int RIGHTS_EXTRACT_ALLOWED = RIGHTS_PAGE + 0xE;
+    public static final int RIGHTS_PRINT_ALLOWED = RIGHTS_PAGE + 0xF;
+    public static final int RIGHTS_EXPORT_ALLOWED = RIGHTS_PAGE + 0x10;
+    public static final int RIGHTS_PROGRAMMATIC_ACCESS_ALLOWED = RIGHTS_PAGE + 0x11;
+    public static final int RIGHTS_OWNER = RIGHTS_PAGE + 0x12;
+    public static final int RIGHTS_CONTENT_EXPIRY_DATE = RIGHTS_PAGE + 0x13;
+    public static final int RIGHTS_TEMPLATE_ID = RIGHTS_PAGE + 0x14;
+    public static final int RIGHTS_TEMPLATE_NAME = RIGHTS_PAGE + 0x15;
+    public static final int RIGHTS_TEMPLATE_DESCRIPTION = RIGHTS_PAGE + 0x16;
+    public static final int RIGHTS_CONTENT_OWNER = RIGHTS_PAGE + 0x17;
+    public static final int RIGHTS_REMOVE_RM_DISTRIBUTION = RIGHTS_PAGE + 0x18;
+
+    static public String[][] pages = {
+        {    // 0x00 AirSync
+            "Sync", "Responses", "Add", "Change", "Delete", "Fetch", "SyncKey", "ClientId",
+            "ServerId", "Status", "Collection", "Class", "Version", "CollectionId", "GetChanges",
+            "MoreAvailable", "WindowSize", "Commands", "Options", "FilterType", "Truncation",
+            "RTFTruncation", "Conflict", "Collections", "ApplicationData", "DeletesAsMoves",
+            "NotifyGUID", "Supported", "SoftDelete", "MIMESupport", "MIMETruncation", "Wait",
+            "Limit", "Partial"
+        },
+        {
+            // 0x01 Contacts
+            "Anniversary", "AssistantName", "AssistantTelephoneNumber", "Birthday", "ContactsBody",
+            "ContactsBodySize", "ContactsBodyTruncated", "Business2TelephoneNumber",
+            "BusinessAddressCity",
+            "BusinessAddressCountry", "BusinessAddressPostalCode", "BusinessAddressState",
+            "BusinessAddressStreet", "BusinessFaxNumber", "BusinessTelephoneNumber",
+            "CarTelephoneNumber", "ContactsCategories", "ContactsCategory", "Children", "Child",
+            "CompanyName", "Department", "Email1Address", "Email2Address", "Email3Address",
+            "FileAs", "FirstName", "Home2TelephoneNumber", "HomeAddressCity", "HomeAddressCountry",
+            "HomeAddressPostalCode", "HomeAddressState", "HomeAddressStreet", "HomeFaxNumber",
+            "HomeTelephoneNumber", "JobTitle", "LastName", "MiddleName", "MobileTelephoneNumber",
+            "OfficeLocation", "OtherAddressCity", "OtherAddressCountry",
+            "OtherAddressPostalCode", "OtherAddressState", "OtherAddressStreet", "PagerNumber",
+            "RadioTelephoneNumber", "Spouse", "Suffix", "Title", "Webpage", "YomiCompanyName",
+            "YomiFirstName", "YomiLastName", "CompressedRTF", "Picture"
+        },
+        {
+            // 0x02 Email
+            "Attachment", "Attachments", "AttName", "AttSize", "Add0Id", "AttMethod", "AttRemoved",
+            "Body", "BodySize", "BodyTruncated", "DateReceived", "DisplayName", "DisplayTo",
+            "Importance", "MessageClass", "Subject", "Read", "To", "CC", "From", "ReplyTo",
+            "AllDayEvent", "Categories", "Category", "DTStamp", "EndTime", "InstanceType",
+            "IntDBusyStatus", "Location", "MeetingRequest", "Organizer", "RecurrenceId", "Reminder",
+            "ResponseRequested", "Recurrences", "Recurence", "Recurrence_Type", "Recurrence_Until",
+            "Recurrence_Occurrences", "Recurrence_Interval", "Recurrence_DayOfWeek",
+            "Recurrence_DayOfMonth", "Recurrence_WeekOfMonth", "Recurrence_MonthOfYear",
+            "StartTime", "Sensitivity", "TimeZone", "GlobalObjId", "ThreadTopic", "MIMEData",
+            "MIMETruncated", "MIMESize", "InternetCPID", "Flag", "FlagStatus", "EmailContentClass",
+            "FlagType", "CompleteTime", "DisallowNewTimeProposal"
+        },
+        {
+            // 0x03 AirNotify
+        },
+        {
+            // 0x04 Calendar
+            "CalTimeZone", "CalAllDayEvent", "CalAttendees", "CalAttendee", "CalAttendee_Email",
+            "CalAttendee_Name", "CalBody", "CalBodyTruncated", "CalBusyStatus", "CalCategories",
+            "CalCategory", "CalCompressed_RTF", "CalDTStamp", "CalEndTime", "CalExeption",
+            "CalExceptions", "CalException_IsDeleted", "CalException_StartTime", "CalLocation",
+            "CalMeetingStatus", "CalOrganizer_Email", "CalOrganizer_Name", "CalRecurrence",
+            "CalRecurrence_Type", "CalRecurrence_Until", "CalRecurrence_Occurrences",
+            "CalRecurrence_Interval", "CalRecurrence_DayOfWeek", "CalRecurrence_DayOfMonth",
+            "CalRecurrence_WeekOfMonth", "CalRecurrence_MonthOfYear", "CalReminder_MinsBefore",
+            "CalSensitivity", "CalSubject", "CalStartTime", "CalUID", "CalAttendee_Status",
+            "CalAttendee_Type", "CalAttachment", "CalAttachments", "CalAttName", "CalAttSize",
+            "CalAttOid", "CalAttMethod", "CalAttRemoved", "CalDisplayName",
+            "CalDisallowNewTimeProposal", "CalResponseRequested", "CalAppointmentReplyTime",
+            "CalResponseType", "CalCalendarType", "CalIsLeapMonth", "CalFirstDayOfWeek",
+            "CalOnlineMeetingConfLink", "CalOnlineMeetingExternalLink"
+        },
+        {
+            // 0x05 Move
+            "MoveItems", "Move", "SrcMsgId", "SrcFldId", "DstFldId", "MoveResponse", "MoveStatus",
+            "DstMsgId"
+        },
+        {
+            // 0x06 ItemEstimate
+            "GetItemEstimate", "Version", "IECollections", "IECollection", "IEClass",
+            "IECollectionId", "DateTime", "Estimate", "IEResponse", "ItemEstimateStatus"
+        },
+        {
+            // 0x07 FolderHierarchy
+            "Folders", "Folder", "FolderDisplayName", "FolderServerId", "FolderParentId", "Type",
+            "FolderResponse", "FolderStatus", "FolderContentClass", "Changes", "FolderAdd",
+            "FolderDelete", "FolderUpdate", "FolderSyncKey", "FolderFolderCreate",
+            "FolderFolderDelete", "FolderFolderUpdate", "FolderSync", "Count", "FolderVersion"
+        },
+        {
+            // 0x08 MeetingResponse
+            "CalId", "CollectionId", "MeetingResponse", "ReqId", "Request",
+            "MeetingResponseResult", "MeetingResponseStatus", "UserResponse", "Version"
+        },
+        {
+            // 0x09 Tasks
+            "TasksBody", "TasksBodySize", "TasksBodyTruncated", "TasksCategories", "TasksCategory",
+            "Complete", "DateCompleted", "DueDate", "UTCDueDate", "TasksImportance", "Recurrence",
+            "RecurrenceType", "RecurrenceStart", "RecurrenceUntil", "RecurrenceOccurrences",
+            "RecurrenceInterval", "RecurrenceDOM", "RecurrenceDOW", "RecurrenceWOM",
+            "RecurrenceMOY", "RecurrenceRegenerate", "RecurrenceDeadOccur", "ReminderSet",
+            "ReminderTime", "TasksSensitivity", "StartDate", "UTCStartDate", "TasksSubject",
+            "TasksCompressedRTF", "OrdinalDate", "SubordinalDate"
+        },
+        {
+            // 0x0A ResolveRecipients
+        },
+        {
+            // 0x0B ValidateCert
+        },
+        {
+            // 0x0C Contacts2
+            "CustomerId", "GovernmentId", "IMAddress", "IMAddress2", "IMAddress3", "ManagerName",
+            "CompanyMainPhone", "AccountName", "NickName", "MMS"
+        },
+        {
+            // 0x0D Ping
+            "Ping", "AutdState", "PingStatus", "HeartbeatInterval", "PingFolders", "PingFolder",
+            "PingId", "PingClass", "MaxFolders"
+        },
+        {
+            // 0x0E Provision
+            "Provision", "Policies", "Policy", "PolicyType", "PolicyKey", "Data", "ProvisionStatus",
+            "RemoteWipe", "EASProvidionDoc", "DevicePasswordEnabled",
+            "AlphanumericDevicePasswordRequired",
+            "DeviceEncryptionEnabled", "PasswordRecoveryEnabled", "-unused-", "AttachmentsEnabled",
+            "MinDevicePasswordLength",
+            "MaxInactivityTimeDeviceLock", "MaxDevicePasswordFailedAttempts", "MaxAttachmentSize",
+            "AllowSimpleDevicePassword", "DevicePasswordExpiration", "DevicePasswordHistory",
+            "AllowStorageCard", "AllowCamera", "RequireDeviceEncryption",
+            "AllowUnsignedApplications", "AllowUnsignedInstallationPackages",
+            "MinDevicePasswordComplexCharacters", "AllowWiFi", "AllowTextMessaging",
+            "AllowPOPIMAPEmail", "AllowBluetooth", "AllowIrDA", "RequireManualSyncWhenRoaming",
+            "AllowDesktopSync",
+            "MaxCalendarAgeFilder", "AllowHTMLEmail", "MaxEmailAgeFilter",
+            "MaxEmailBodyTruncationSize", "MaxEmailHTMLBodyTruncationSize",
+            "RequireSignedSMIMEMessages", "RequireEncryptedSMIMEMessages",
+            "RequireSignedSMIMEAlgorithm", "RequireEncryptionSMIMEAlgorithm",
+            "AllowSMIMEEncryptionAlgorithmNegotiation", "AllowSMIMESoftCerts", "AllowBrowser",
+            "AllowConsumerEmail", "AllowRemoteDesktop", "AllowInternetSharing",
+            "UnapprovedInROMApplicationList", "ApplicationName", "ApprovedApplicationList", "Hash"
+        },
+        {
+            // 0x0F Search
+            "Search", "Stores", "Store", "Name", "Query",
+            "SearchOptions", "Range", "SearchStatus", "Response", "Result",
+            "Properties", "Total", "EqualTo", "Value", "And",
+            "Or", "FreeText", "SubstringOp", "DeepTraversal", "LongId",
+            "RebuildResults", "LessThan", "GreateerThan", "Schema", "SearchSupported"
+        },
+        {
+            // 0x10 Gal
+            "GalDisplayName", "GalPhone", "GalOffice", "GalTitle", "GalCompany", "GalAlias",
+            "GalFirstName", "GalLastName", "GalHomePhone", "GalMobilePhone", "GalEmailAddress"
+        },
+        {
+            // 0x11 AirSyncBase
+            "BodyPreference", "BodyPreferenceType", "BodyPreferenceTruncationSize", "AllOrNone",
+            "--unused1--", "BaseBody", "BaseData", "BaseEstimatedDataSize", "BaseTruncated",
+            "BaseAttachments", "BaseAttachment", "BaseDisplayName", "FileReference", "BaseMethod",
+            "BaseContentId", "BaseContentLocation", "BaseIsInline", "BaseNativeBodyType",
+            "BaseContentType"
+        },
+        {
+            // 0x12 Settings
+            "Settings", "SettingsStatus", "Get", "Set", "Oof", "OofState", "SettingsStartTime",
+            "SettingsEndTime", "OofMessage", "AppliesToInternal", "AppliesToExternalKnown",
+            "AppliesToExternalUnknown", "Enabled", "ReplyMessage", "BodyType", "DevicePassword",
+            "Password", "DeviceInformation", "Model", "IMEI", "FriendlyName", "OS", "OSLanguage",
+            "PhoneNumber", "UserInformation", "EmailAddress", "StmpAddress", "UserAgent",
+            "EnableOutboundSMS", "MobileOperator"
+        },
+        {
+            // 0x13 DocumentLibrary
+        },
+        {
+            // 0x14 ItemOperations
+            "Items", "ItemsFetch", "ItemsStore", "ItemsOptions", "ItemsRange",
+            "ItemsTotal", "ItemsProperties", "ItemsData", "ItemsStatus", "ItemsResponse",
+            "ItemsVersion", "ItemsSchema", "ItemsPart", "ItemsEmptyFolder", "ItemsDeleteSubFolders",
+            "ItemsUserName", "ItemsPassword", "ItemsMove", "ItemsDstFldId", "ItemsConversationId",
+            "ItemsMoveAlways"
+        },
+        {
+            // 0x15 ComposeMail
+            "SendMail", "SmartForward", "SmartReply", "SaveInSentItems", "ReplaceMime",
+            "--unused2--", "ComposeSource", "ComposeFolderId", "ComposeItemId", "ComposeLongId",
+            "ComposeInstanceId", "ComposeMime", "ComposeClientId", "ComposeStatus",
+            "ComposeAccountId"
+        },
+        {
+            // 0x16 Email2
+            "UmCallerId", "UmUserNotes", "UmAttDuration", "UmAttOrder", "ConversationId",
+            "ConversationIndex", "LastVerbExecuted", "LastVerbExecutionTime", "ReceivedAsBcc",
+            "Sender", "CalendarType", "IsLeapMonth", "AccountId", "FirstDayOfWeek",
+            "MeetingMessageType"
+        },
+        {
+            // 0x17 Notes
+        },
+        {
+            // 0x18 Rights Management
+            "RMSupport", "RMTemplates", "RMTemplate", "RMLicense", "EditAllowed", "ReplyAllowed",
+            "ReplyAllAllowed", "ForwardAllowed", "ModifyRecipientsAllowed", "ExtractAllowed",
+            "PrintAllowed", "ExportAllowed", "ProgrammaticAccessAllowed", "RMOwner",
+            "ContentExpiryDate", "TemplateID", "TemplateName", "TemplateDescription",
+            "ContentOwner", "RemoveRMDistribution"
+        }
+    };
+}
diff --git a/exchange2/src/com/android/exchange/adapter/Wbxml.java b/exchange2/src/com/android/exchange/adapter/Wbxml.java
new file mode 100644
index 0000000..b8ae789
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/Wbxml.java
@@ -0,0 +1,51 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package com.android.exchange.adapter;
+
+
+/** contains the WBXML constants  */
+
+
+public interface Wbxml {
+
+    static public final int SWITCH_PAGE = 0;
+    static public final int END = 1;
+    static public final int ENTITY = 2;
+    static public final int STR_I = 3;
+    static public final int LITERAL = 4;
+    static public final int EXT_I_0 = 0x40;
+    static public final int EXT_I_1 = 0x41;
+    static public final int EXT_I_2 = 0x42;
+    static public final int PI = 0x43;
+    static public final int LITERAL_C = 0x44;
+    static public final int EXT_T_0 = 0x80;
+    static public final int EXT_T_1 = 0x81;
+    static public final int EXT_T_2 = 0x82;
+    static public final int STR_T = 0x83;
+    static public final int LITERAL_A = 0x084;
+    static public final int EXT_0 = 0x0c0;
+    static public final int EXT_1 = 0x0c1;
+    static public final int EXT_2 = 0x0c2;
+    static public final int OPAQUE = 0x0c3; 
+    static public final int LITERAL_AC = 0x0c4;
+
+    static public final int WITH_CONTENT = 0x40;
+}
diff --git a/exchange2/src/com/android/exchange/adapter/patent_disclaimer.txt b/exchange2/src/com/android/exchange/adapter/patent_disclaimer.txt
new file mode 100644
index 0000000..8a715a3
--- /dev/null
+++ b/exchange2/src/com/android/exchange/adapter/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+-----------------------------
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the source code made available hereunder is
+unencumbered by third-party patents.  Those intending to use this source code in hardware or
+software products are advised that implementations of this code, including in open source software
+or shareware, may require patent licenses from the relevant patent holders.
+
+-----------------------------
diff --git a/exchange2/src/com/android/exchange/patent_disclaimer.txt b/exchange2/src/com/android/exchange/patent_disclaimer.txt
new file mode 100644
index 0000000..8a715a3
--- /dev/null
+++ b/exchange2/src/com/android/exchange/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+-----------------------------
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the source code made available hereunder is
+unencumbered by third-party patents.  Those intending to use this source code in hardware or
+software products are advised that implementations of this code, including in open source software
+or shareware, may require patent licenses from the relevant patent holders.
+
+-----------------------------
diff --git a/exchange2/src/com/android/exchange/provider/ExchangeDirectoryProvider.java b/exchange2/src/com/android/exchange/provider/ExchangeDirectoryProvider.java
new file mode 100644
index 0000000..6d725ff
--- /dev/null
+++ b/exchange2/src/com/android/exchange/provider/ExchangeDirectoryProvider.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import com.android.emailcommon.Configuration;
+import com.android.emailcommon.mail.PackedString;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.service.AccountServiceProxy;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.Eas;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.R;
+import com.android.exchange.provider.GalResult.GalData;
+
+import android.accounts.AccountManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Contacts.Data;
+import android.provider.ContactsContract.Directory;
+import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * ExchangeDirectoryProvider provides real-time data from the Exchange server; at the moment, it is
+ * used solely to provide GAL (Global Address Lookup) service to email address adapters
+ */
+public class ExchangeDirectoryProvider extends ContentProvider {
+    public static final String EXCHANGE_GAL_AUTHORITY = "com.android.exchange.directory.provider";
+
+    private static final int DEFAULT_CONTACT_ID = 1;
+    private static final int DEFAULT_LOOKUP_LIMIT = 20;
+
+    private static final int GAL_BASE = 0;
+    private static final int GAL_DIRECTORIES = GAL_BASE;
+    private static final int GAL_FILTER = GAL_BASE + 1;
+    private static final int GAL_CONTACT = GAL_BASE + 2;
+    private static final int GAL_CONTACT_WITH_ID = GAL_BASE + 3;
+    private static final int GAL_EMAIL_FILTER = GAL_BASE + 4;
+
+    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+    /*package*/ final HashMap<String, Long> mAccountIdMap = new HashMap<String, Long>();
+
+    static {
+        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "directories", GAL_DIRECTORIES);
+        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/filter/*", GAL_FILTER);
+        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/lookup/*/entities", GAL_CONTACT);
+        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/lookup/*/#/entities",
+                GAL_CONTACT_WITH_ID);
+        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "data/emails/filter/*", GAL_EMAIL_FILTER);
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    static class GalProjection {
+        final int size;
+        final HashMap<String, Integer> columnMap = new HashMap<String, Integer>();
+
+        GalProjection(String[] projection) {
+            size = projection.length;
+            for (int i = 0; i < projection.length; i++) {
+                columnMap.put(projection[i], i);
+            }
+        }
+    }
+
+    static class GalContactRow {
+        private final GalProjection mProjection;
+        private Object[] row;
+        static long dataId = 1;
+
+        GalContactRow(GalProjection projection, long contactId, String lookupKey,
+                String accountName, String displayName) {
+            this.mProjection = projection;
+            row = new Object[projection.size];
+
+            put(Contacts.Entity.CONTACT_ID, contactId);
+
+            // We only have one raw contact per aggregate, so they can have the same ID
+            put(Contacts.Entity.RAW_CONTACT_ID, contactId);
+            put(Contacts.Entity.DATA_ID, dataId++);
+
+            put(Contacts.DISPLAY_NAME, displayName);
+
+            // TODO alternative display name
+            put(Contacts.DISPLAY_NAME_ALTERNATIVE, displayName);
+
+            put(RawContacts.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+            put(RawContacts.ACCOUNT_NAME, accountName);
+            put(RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
+            put(Data.IS_READ_ONLY, 1);
+        }
+
+        Object[] getRow () {
+            return row;
+        }
+
+        void put(String columnName, Object value) {
+            Integer integer = mProjection.columnMap.get(columnName);
+            if (integer != null) {
+                row[integer] = value;
+            } else {
+                System.out.println("Unsupported column: " + columnName);
+            }
+        }
+
+        static void addEmailAddress(MatrixCursor cursor, GalProjection galProjection,
+                long contactId, String lookupKey, String accountName, String displayName,
+                String address) {
+            if (!TextUtils.isEmpty(address)) {
+                GalContactRow r = new GalContactRow(
+                        galProjection, contactId, lookupKey, accountName, displayName);
+                r.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+                r.put(Email.TYPE, Email.TYPE_WORK);
+                r.put(Email.ADDRESS, address);
+                cursor.addRow(r.getRow());
+            }
+        }
+
+        static void addPhoneRow(MatrixCursor cursor, GalProjection projection, long contactId,
+                String lookupKey, String accountName, String displayName, int type, String number) {
+            if (!TextUtils.isEmpty(number)) {
+                GalContactRow r = new GalContactRow(
+                        projection, contactId, lookupKey, accountName, displayName);
+                r.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+                r.put(Phone.TYPE, type);
+                r.put(Phone.NUMBER, number);
+                cursor.addRow(r.getRow());
+            }
+        }
+
+        public static void addNameRow(MatrixCursor cursor, GalProjection galProjection,
+                long contactId, String lookupKey, String accountName, String displayName,
+                String firstName, String lastName) {
+            GalContactRow r = new GalContactRow(
+                    galProjection, contactId, lookupKey, accountName, displayName);
+            r.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+            r.put(StructuredName.GIVEN_NAME, firstName);
+            r.put(StructuredName.FAMILY_NAME, lastName);
+            r.put(StructuredName.DISPLAY_NAME, displayName);
+            cursor.addRow(r.getRow());
+        }
+    }
+
+    /**
+     * Find the record id of an Account, given its name (email address)
+     * @param accountName the name of the account
+     * @return the record id of the Account, or -1 if not found
+     */
+    /*package*/ long getAccountIdByName(Context context, String accountName) {
+        Long accountId = mAccountIdMap.get(accountName);
+        if (accountId == null) {
+            accountId = Utility.getFirstRowLong(context, Account.CONTENT_URI,
+                    EmailContent.ID_PROJECTION, AccountColumns.EMAIL_ADDRESS + "=?",
+                    new String[] {accountName}, null, EmailContent.ID_PROJECTION_COLUMN , -1L);
+            if (accountId != -1) {
+                mAccountIdMap.put(accountName, accountId);
+            }
+        }
+        return accountId;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        int match = sURIMatcher.match(uri);
+        MatrixCursor cursor;
+        Object[] row;
+        PackedString ps;
+        String lookupKey;
+
+        switch (match) {
+            case GAL_DIRECTORIES: {
+                // Assuming that GAL can be used with all exchange accounts
+                android.accounts.Account[] accounts = AccountManager.get(getContext())
+                        .getAccountsByType(Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+                cursor = new MatrixCursor(projection);
+                if (accounts != null) {
+                    for (android.accounts.Account account : accounts) {
+                        row = new Object[projection.length];
+
+                        for (int i = 0; i < projection.length; i++) {
+                            String column = projection[i];
+                            if (column.equals(Directory.ACCOUNT_NAME)) {
+                                row[i] = account.name;
+                            } else if (column.equals(Directory.ACCOUNT_TYPE)) {
+                                row[i] = account.type;
+                            } else if (column.equals(Directory.TYPE_RESOURCE_ID)) {
+                                Bundle bundle = null;
+                                String accountType = Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE;
+                                bundle = new AccountServiceProxy(getContext())
+                                    .getConfigurationData(accountType);
+                                // Default to the alternative name, erring on the conservative side
+                                int exchangeName = R.string.exchange_name_alternate;
+                                if (bundle != null && !bundle.getBoolean(
+                                        Configuration.EXCHANGE_CONFIGURATION_USE_ALTERNATE_STRINGS,
+                                        true)) {
+                                    exchangeName = R.string.exchange_name;
+                                }
+                                row[i] = exchangeName;
+                            } else if (column.equals(Directory.DISPLAY_NAME)) {
+                                // If the account name is an email address, extract
+                                // the domain name and use it as the directory display name
+                                final String accountName = account.name;
+                                int atIndex = accountName.indexOf('@');
+                                if (atIndex != -1 && atIndex < accountName.length() - 2) {
+                                    final char firstLetter = Character.toUpperCase(
+                                            accountName.charAt(atIndex + 1));
+                                    row[i] = firstLetter + accountName.substring(atIndex + 2);
+                                } else {
+                                    row[i] = account.name;
+                                }
+                            } else if (column.equals(Directory.EXPORT_SUPPORT)) {
+                                row[i] = Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY;
+                            } else if (column.equals(Directory.SHORTCUT_SUPPORT)) {
+                                row[i] = Directory.SHORTCUT_SUPPORT_NONE;
+                            }
+                        }
+                        cursor.addRow(row);
+                    }
+                }
+                return cursor;
+            }
+
+            case GAL_FILTER:
+            case GAL_EMAIL_FILTER: {
+                String filter = uri.getLastPathSegment();
+                // We should have at least two characters before doing a GAL search
+                if (filter == null || filter.length() < 2) {
+                    return null;
+                }
+
+                String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
+                if (accountName == null) {
+                    return null;
+                }
+
+                // Enforce a limit on the number of lookup responses
+                String limitString = uri.getQueryParameter(ContactsContract.LIMIT_PARAM_KEY);
+                int limit = DEFAULT_LOOKUP_LIMIT;
+                if (limitString != null) {
+                    try {
+                        limit = Integer.parseInt(limitString);
+                    } catch (NumberFormatException e) {
+                        limit = 0;
+                    }
+                    if (limit <= 0) {
+                        throw new IllegalArgumentException("Limit not valid: " + limitString);
+                    }
+                }
+
+                long callingId = Binder.clearCallingIdentity();
+                try {
+                    // Find the account id to pass along to EasSyncService
+                    long accountId = getAccountIdByName(getContext(), accountName);
+                    if (accountId == -1) {
+                        // The account was deleted?
+                        return null;
+                    }
+
+                    // Get results from the Exchange account
+                    GalResult galResult = EasSyncService.searchGal(getContext(), accountId,
+                            filter, limit);
+                    if (galResult != null) {
+                        return buildGalResultCursor(projection, galResult);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(callingId);
+                }
+                break;
+            }
+
+            case GAL_CONTACT:
+            case GAL_CONTACT_WITH_ID: {
+                String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
+                if (accountName == null) {
+                    return null;
+                }
+
+                GalProjection galProjection = new GalProjection(projection);
+                cursor = new MatrixCursor(projection);
+                // Handle the decomposition of the key into rows suitable for CP2
+                List<String> pathSegments = uri.getPathSegments();
+                lookupKey = pathSegments.get(2);
+                long contactId = (match == GAL_CONTACT_WITH_ID)
+                        ? Long.parseLong(pathSegments.get(3))
+                        : DEFAULT_CONTACT_ID;
+                ps = new PackedString(lookupKey);
+                String displayName = ps.get(GalData.DISPLAY_NAME);
+                GalContactRow.addEmailAddress(cursor, galProjection, contactId, lookupKey,
+                        accountName, displayName, ps.get(GalData.EMAIL_ADDRESS));
+                GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName,
+                        displayName, displayName, Phone.TYPE_HOME, ps.get(GalData.HOME_PHONE));
+                GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName,
+                        displayName, displayName, Phone.TYPE_WORK, ps.get(GalData.WORK_PHONE));
+                GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName,
+                        displayName, displayName, Phone.TYPE_MOBILE, ps.get(GalData.MOBILE_PHONE));
+                GalContactRow.addNameRow(cursor, galProjection, contactId, accountName, displayName,
+                        ps.get(GalData.FIRST_NAME), ps.get(GalData.LAST_NAME), displayName);
+                return cursor;
+            }
+        }
+
+        return null;
+    }
+
+    /*package*/ Cursor buildGalResultCursor(String[] projection, GalResult galResult) {
+        int displayNameIndex = -1;
+        int alternateDisplayNameIndex = -1;;
+        int emailIndex = -1;
+        int idIndex = -1;
+        int lookupIndex = -1;
+
+        for (int i = 0; i < projection.length; i++) {
+            String column = projection[i];
+            if (Contacts.DISPLAY_NAME.equals(column) ||
+                    Contacts.DISPLAY_NAME_PRIMARY.equals(column)) {
+                displayNameIndex = i;
+            } else if (Contacts.DISPLAY_NAME_ALTERNATIVE.equals(column)) {
+                alternateDisplayNameIndex = i;
+            } else if (CommonDataKinds.Email.ADDRESS.equals(column)) {
+                emailIndex = i;
+            } else if (Contacts._ID.equals(column)) {
+                idIndex = i;
+            } else if (Contacts.LOOKUP_KEY.equals(column)) {
+                lookupIndex = i;
+            }
+        }
+
+        Object[] row = new Object[projection.length];
+
+        /*
+         * ContactsProvider will ensure that every request has a non-null projection.
+         */
+        MatrixCursor cursor = new MatrixCursor(projection);
+        int count = galResult.galData.size();
+        for (int i = 0; i < count; i++) {
+            GalData galDataRow = galResult.galData.get(i);
+            String firstName = galDataRow.get(GalData.FIRST_NAME);
+            String lastName = galDataRow.get(GalData.LAST_NAME);
+            String displayName = galDataRow.get(GalData.DISPLAY_NAME);
+            // If we don't have a display name, try to create one using first and last name
+            if (displayName == null) {
+                if (firstName != null && lastName != null) {
+                    displayName = firstName + " " + lastName;
+                } else if (firstName != null) {
+                    displayName = firstName;
+                } else if (lastName != null) {
+                    displayName = lastName;
+                }
+            }
+            galDataRow.put(GalData.DISPLAY_NAME, displayName);
+
+            if (displayNameIndex != -1) {
+                row[displayNameIndex] = displayName;
+            }
+            if (alternateDisplayNameIndex != -1) {
+                // Try to create an alternate display name, using first and last name
+                // TODO: Check with Contacts team to make sure we're using this properly
+                if (firstName != null && lastName != null) {
+                    row[alternateDisplayNameIndex] = lastName + " " + firstName;
+                } else {
+                    row[alternateDisplayNameIndex] = displayName;
+                }
+            }
+            if (emailIndex != -1) {
+                row[emailIndex] = galDataRow.get(GalData.EMAIL_ADDRESS);
+            }
+            if (idIndex != -1) {
+                row[idIndex] = i + 1;  // Let's be 1 based
+            }
+            if (lookupIndex != -1) {
+                // We use the packed string as our lookup key; it contains ALL of the gal data
+                // We do this because we are not able to provide a stable id to ContactsProvider
+                row[lookupIndex] = Uri.encode(galDataRow.toPackedString());
+            }
+            cursor.addRow(row);
+        }
+        return cursor;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        int match = sURIMatcher.match(uri);
+        switch (match) {
+            case GAL_FILTER:
+                return Contacts.CONTENT_ITEM_TYPE;
+        }
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/exchange2/src/com/android/exchange/provider/GalResult.java b/exchange2/src/com/android/exchange/provider/GalResult.java
new file mode 100644
index 0000000..4d0d908
--- /dev/null
+++ b/exchange2/src/com/android/exchange/provider/GalResult.java
@@ -0,0 +1,94 @@
+/* Copyright (C) 2010 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import com.android.emailcommon.mail.PackedString;
+
+import java.util.ArrayList;
+
+/**
+ * A container for GAL results from EAS
+ * Each element of the galData array becomes an element of the list used by autocomplete
+ */
+public class GalResult {
+    // Total number of matches in this result
+    public int total;
+    public ArrayList<GalData> galData = new ArrayList<GalData>();
+
+    public GalResult() {
+    }
+
+    /**
+     * Legacy method for email address autocomplete
+     */
+    public void addGalData(long id, String displayName, String emailAddress) {
+        galData.add(new GalData(id, displayName, emailAddress));
+    }
+
+    public void addGalData(GalData data) {
+        galData.add(data);
+    }
+
+    public static class GalData {
+        // PackedString constants for GalData
+        public static final String ID = "_id";
+        public static final String DISPLAY_NAME = "displayName";
+        public static final String EMAIL_ADDRESS = "emailAddress";
+        public static final String WORK_PHONE = "workPhone";
+        public static final String HOME_PHONE = "homePhone";
+        public static final String MOBILE_PHONE = "mobilePhone";
+        public static final String FIRST_NAME = "firstName";
+        public static final String LAST_NAME = "lastName";
+        public static final String COMPANY = "company";
+        public static final String TITLE = "title";
+        public static final String OFFICE = "office";
+        public static final String ALIAS = "alias";
+        // The Builder we use to construct the PackedString
+        PackedString.Builder builder = new PackedString.Builder();
+
+        // The following three fields are for legacy email autocomplete
+        public long _id = 0;
+        public String displayName;
+        public String emailAddress;
+
+        /**
+         * Legacy constructor for email address autocomplete
+         */
+        private GalData(long id, String _displayName, String _emailAddress) {
+            put(ID, Long.toString(id));
+            _id = id;
+            put(DISPLAY_NAME, _displayName);
+            displayName = _displayName;
+            put(EMAIL_ADDRESS, _emailAddress);
+            emailAddress = _emailAddress;
+        }
+
+        public GalData() {
+        }
+
+        public String get(String field) {
+            return builder.get(field);
+        }
+
+        public void put(String field, String value) {
+            builder.put(field, value);
+        }
+
+        public String toPackedString() {
+            return builder.toString();
+        }
+    }
+}
diff --git a/exchange2_src/com/android/exchange/provider/MailboxUtilities.java b/exchange2/src/com/android/exchange/provider/MailboxUtilities.java
similarity index 100%
rename from exchange2_src/com/android/exchange/provider/MailboxUtilities.java
rename to exchange2/src/com/android/exchange/provider/MailboxUtilities.java
diff --git a/exchange2/src/com/android/exchange/service/ExchangeBroadcastProcessorService.java b/exchange2/src/com/android/exchange/service/ExchangeBroadcastProcessorService.java
new file mode 100644
index 0000000..8f88910
--- /dev/null
+++ b/exchange2/src/com/android/exchange/service/ExchangeBroadcastProcessorService.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.service;
+
+import android.accounts.AccountManager;
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.android.emailcommon.Logging;
+import com.android.exchange.Eas;
+import com.android.exchange.ExchangeService;
+
+/**
+ * The service that really handles broadcast intents on a worker thread.
+ *
+ * We make it a service, because:
+ * <ul>
+ *   <li>So that it's less likely for the process to get killed.
+ *   <li>Even if it does, the Intent that have started it will be re-delivered by the system,
+ *   and we can start the process again.  (Using {@link #setIntentRedelivery}).
+ * </ul>
+ */
+public class ExchangeBroadcastProcessorService extends IntentService {
+    // Action used for BroadcastReceiver entry point
+    private static final String ACTION_BROADCAST = "broadcast_receiver";
+
+    public ExchangeBroadcastProcessorService() {
+        // Class name will be the thread name.
+        super(ExchangeBroadcastProcessorService.class.getName());
+        // Intent should be redelivered if the process gets killed before completing the job.
+        setIntentRedelivery(true);
+    }
+
+    /**
+     * Entry point for {@link ExchangeBroadcastReceiver}.
+     */
+    public static void processBroadcastIntent(Context context, Intent broadcastIntent) {
+        Intent i = new Intent(context, ExchangeBroadcastProcessorService.class);
+        i.setAction(ACTION_BROADCAST);
+        i.putExtra(Intent.EXTRA_INTENT, broadcastIntent);
+        context.startService(i);
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        // Dispatch from entry point
+        final String action = intent.getAction();
+        if (ACTION_BROADCAST.equals(action)) {
+            final Intent broadcastIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+            final String broadcastAction = broadcastIntent.getAction();
+
+            if (Intent.ACTION_BOOT_COMPLETED.equals(broadcastAction)) {
+                onBootCompleted();
+            } else if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(broadcastAction)) {
+                if (Eas.USER_LOG) {
+                    Log.d(Logging.LOG_TAG, "Login accounts changed; reconciling...");
+                }
+                ExchangeService.runAccountReconcilerSync(this);
+            }
+       }
+    }
+
+    /**
+     * Handles {@link Intent#ACTION_BOOT_COMPLETED}.  Called on a worker thread.
+     */
+    private void onBootCompleted() {
+        startService(new Intent(this, ExchangeService.class));
+    }
+}
diff --git a/exchange2/src/com/android/exchange/service/ExchangeBroadcastReceiver.java b/exchange2/src/com/android/exchange/service/ExchangeBroadcastReceiver.java
new file mode 100644
index 0000000..e79eec0
--- /dev/null
+++ b/exchange2/src/com/android/exchange/service/ExchangeBroadcastReceiver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.service;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * The broadcast receiver.  The actual job is done in EmailBroadcastProcessor on a worker thread.
+ */
+public class ExchangeBroadcastReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        ExchangeBroadcastProcessorService.processBroadcastIntent(context, intent);
+    }
+}
diff --git a/exchange2/src/com/android/exchange/utility/CalendarUtilities.java b/exchange2/src/com/android/exchange/utility/CalendarUtilities.java
new file mode 100644
index 0000000..2302b7a
--- /dev/null
+++ b/exchange2/src/com/android/exchange/utility/CalendarUtilities.java
@@ -0,0 +1,1949 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.utility;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Entity;
+import android.content.Entity.NamedContentValues;
+import android.content.EntityIterator;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.CalendarContract.Attendees;
+import android.provider.CalendarContract.Calendars;
+import android.provider.CalendarContract.Events;
+import android.provider.CalendarContract.EventsEntity;
+import android.text.TextUtils;
+import android.text.format.Time;
+import android.util.Base64;
+import android.util.Log;
+
+import com.android.calendarcommon.DateException;
+import com.android.calendarcommon.Duration;
+import com.android.emailcommon.Logging;
+import com.android.emailcommon.mail.Address;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.Attachment;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.service.AccountServiceProxy;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.Eas;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.ExchangeService;
+import com.android.exchange.R;
+import com.android.exchange.adapter.Serializer;
+import com.android.exchange.adapter.Tags;
+import com.android.internal.util.ArrayUtils;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.TimeZone;
+
+public class CalendarUtilities {
+
+    // NOTE: Most definitions in this class are have package visibility for testing purposes
+    private static final String TAG = "CalendarUtility";
+
+    // Time related convenience constants, in milliseconds
+    static final int SECONDS = 1000;
+    static final int MINUTES = SECONDS*60;
+    static final int HOURS = MINUTES*60;
+    static final long DAYS = HOURS*24;
+
+    // We want to find a time zone whose DST info is accurate to one minute
+    static final int STANDARD_DST_PRECISION = MINUTES;
+    // If we can't find one, we'll try a more lenient standard (this is better than guessing a
+    // time zone, which is what we otherwise do).  Note that this specifically addresses an issue
+    // seen in some time zones sent by MS Exchange in which the start and end hour differ
+    // for no apparent reason
+    static final int LENIENT_DST_PRECISION = 4*HOURS;
+
+    private static final String SYNC_VERSION = Events.SYNC_DATA4;
+    // NOTE All Microsoft data structures are little endian
+
+    // The following constants relate to standard Microsoft data sizes
+    // For documentation, see http://msdn.microsoft.com/en-us/library/aa505945.aspx
+    static final int MSFT_LONG_SIZE = 4;
+    static final int MSFT_WCHAR_SIZE = 2;
+    static final int MSFT_WORD_SIZE = 2;
+
+    // The following constants relate to Microsoft's SYSTEMTIME structure
+    // For documentation, see: http://msdn.microsoft.com/en-us/library/ms724950(VS.85).aspx?ppud=4
+
+    static final int MSFT_SYSTEMTIME_YEAR = 0 * MSFT_WORD_SIZE;
+    static final int MSFT_SYSTEMTIME_MONTH = 1 * MSFT_WORD_SIZE;
+    static final int MSFT_SYSTEMTIME_DAY_OF_WEEK = 2 * MSFT_WORD_SIZE;
+    static final int MSFT_SYSTEMTIME_DAY = 3 * MSFT_WORD_SIZE;
+    static final int MSFT_SYSTEMTIME_HOUR = 4 * MSFT_WORD_SIZE;
+    static final int MSFT_SYSTEMTIME_MINUTE = 5 * MSFT_WORD_SIZE;
+    //static final int MSFT_SYSTEMTIME_SECONDS = 6 * MSFT_WORD_SIZE;
+    //static final int MSFT_SYSTEMTIME_MILLIS = 7 * MSFT_WORD_SIZE;
+    static final int MSFT_SYSTEMTIME_SIZE = 8*MSFT_WORD_SIZE;
+
+    // The following constants relate to Microsoft's TIME_ZONE_INFORMATION structure
+    // For documentation, see http://msdn.microsoft.com/en-us/library/ms725481(VS.85).aspx
+    static final int MSFT_TIME_ZONE_BIAS_OFFSET = 0;
+    static final int MSFT_TIME_ZONE_STANDARD_NAME_OFFSET =
+        MSFT_TIME_ZONE_BIAS_OFFSET + MSFT_LONG_SIZE;
+    static final int MSFT_TIME_ZONE_STANDARD_DATE_OFFSET =
+        MSFT_TIME_ZONE_STANDARD_NAME_OFFSET + (MSFT_WCHAR_SIZE*32);
+    static final int MSFT_TIME_ZONE_STANDARD_BIAS_OFFSET =
+        MSFT_TIME_ZONE_STANDARD_DATE_OFFSET + MSFT_SYSTEMTIME_SIZE;
+    static final int MSFT_TIME_ZONE_DAYLIGHT_NAME_OFFSET =
+        MSFT_TIME_ZONE_STANDARD_BIAS_OFFSET + MSFT_LONG_SIZE;
+    static final int MSFT_TIME_ZONE_DAYLIGHT_DATE_OFFSET =
+        MSFT_TIME_ZONE_DAYLIGHT_NAME_OFFSET + (MSFT_WCHAR_SIZE*32);
+    static final int MSFT_TIME_ZONE_DAYLIGHT_BIAS_OFFSET =
+        MSFT_TIME_ZONE_DAYLIGHT_DATE_OFFSET + MSFT_SYSTEMTIME_SIZE;
+    static final int MSFT_TIME_ZONE_SIZE =
+        MSFT_TIME_ZONE_DAYLIGHT_BIAS_OFFSET + MSFT_LONG_SIZE;
+
+    // TimeZone cache; we parse/decode as little as possible, because the process is quite slow
+    private static HashMap<String, TimeZone> sTimeZoneCache = new HashMap<String, TimeZone>();
+    // TZI string cache; we keep around our encoded TimeZoneInformation strings
+    private static HashMap<TimeZone, String> sTziStringCache = new HashMap<TimeZone, String>();
+
+    private static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC");
+    // Default, Popup
+    private static final String ALLOWED_REMINDER_TYPES = "0,1";
+    // None, required, optional
+    private static final String ALLOWED_ATTENDEE_TYPES = "0,1,2";
+    // Busy, free, tentative
+    private static final String ALLOWED_AVAILABILITIES = "0,1,2";
+
+    // There is no type 4 (thus, the "")
+    static final String[] sTypeToFreq =
+        new String[] {"DAILY", "WEEKLY", "MONTHLY", "MONTHLY", "", "YEARLY", "YEARLY"};
+
+    static final String[] sDayTokens =
+        new String[] {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
+
+    static final String[] sTwoCharacterNumbers =
+        new String[] {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"};
+
+    // Bits used in EAS recurrences for days of the week
+    protected static final int EAS_SUNDAY = 1<<0;
+    protected static final int EAS_MONDAY = 1<<1;
+    protected static final int EAS_TUESDAY = 1<<2;
+    protected static final int EAS_WEDNESDAY = 1<<3;
+    protected static final int EAS_THURSDAY = 1<<4;
+    protected static final int EAS_FRIDAY = 1<<5;
+    protected static final int EAS_SATURDAY = 1<<6;
+    protected static final int EAS_WEEKDAYS =
+        EAS_MONDAY | EAS_TUESDAY | EAS_WEDNESDAY | EAS_THURSDAY | EAS_FRIDAY;
+    protected static final int EAS_WEEKENDS = EAS_SATURDAY | EAS_SUNDAY;
+
+    static final int sCurrentYear = new GregorianCalendar().get(Calendar.YEAR);
+    static final TimeZone sGmtTimeZone = TimeZone.getTimeZone("GMT");
+
+    private static final String ICALENDAR_ATTENDEE = "ATTENDEE;ROLE=REQ-PARTICIPANT";
+    static final String ICALENDAR_ATTENDEE_CANCEL = ICALENDAR_ATTENDEE;
+    static final String ICALENDAR_ATTENDEE_INVITE =
+        ICALENDAR_ATTENDEE + ";PARTSTAT=NEEDS-ACTION;RSVP=TRUE";
+    static final String ICALENDAR_ATTENDEE_ACCEPT =
+        ICALENDAR_ATTENDEE + ";PARTSTAT=ACCEPTED";
+    static final String ICALENDAR_ATTENDEE_DECLINE =
+        ICALENDAR_ATTENDEE + ";PARTSTAT=DECLINED";
+    static final String ICALENDAR_ATTENDEE_TENTATIVE =
+        ICALENDAR_ATTENDEE + ";PARTSTAT=TENTATIVE";
+
+    // Note that these constants apply to Calendar items
+    // For future reference: MeetingRequest data can also include free/busy information, but the
+    // constants for these four options in MeetingRequest data have different values!
+    // See [MS-ASCAL] 2.2.2.8 for Calendar BusyStatus
+    // See [MS-EMAIL] 2.2.2.34 for MeetingRequest BusyStatus
+    public static final int BUSY_STATUS_FREE = 0;
+    public static final int BUSY_STATUS_TENTATIVE = 1;
+    public static final int BUSY_STATUS_BUSY = 2;
+    public static final int BUSY_STATUS_OUT_OF_OFFICE = 3;
+
+    // Note that these constants apply to Calendar items, and are used in EAS 14+
+    // See [MS-ASCAL] 2.2.2.22 for Calendar ResponseType
+    public static final int RESPONSE_TYPE_NONE = 0;
+    public static final int RESPONSE_TYPE_ORGANIZER = 1;
+    public static final int RESPONSE_TYPE_TENTATIVE = 2;
+    public static final int RESPONSE_TYPE_ACCEPTED = 3;
+    public static final int RESPONSE_TYPE_DECLINED = 4;
+    public static final int RESPONSE_TYPE_NOT_RESPONDED = 5;
+
+    // Return a 4-byte long from a byte array (little endian)
+    static int getLong(byte[] bytes, int offset) {
+        return (bytes[offset++] & 0xFF) | ((bytes[offset++] & 0xFF) << 8) |
+        ((bytes[offset++] & 0xFF) << 16) | ((bytes[offset] & 0xFF) << 24);
+    }
+
+    // Put a 4-byte long into a byte array (little endian)
+    static void setLong(byte[] bytes, int offset, int value) {
+        bytes[offset++] = (byte) (value & 0xFF);
+        bytes[offset++] = (byte) ((value >> 8) & 0xFF);
+        bytes[offset++] = (byte) ((value >> 16) & 0xFF);
+        bytes[offset] = (byte) ((value >> 24) & 0xFF);
+    }
+
+    // Return a 2-byte word from a byte array (little endian)
+    static int getWord(byte[] bytes, int offset) {
+        return (bytes[offset++] & 0xFF) | ((bytes[offset] & 0xFF) << 8);
+    }
+
+    // Put a 2-byte word into a byte array (little endian)
+    static void setWord(byte[] bytes, int offset, int value) {
+        bytes[offset++] = (byte) (value & 0xFF);
+        bytes[offset] = (byte) ((value >> 8) & 0xFF);
+    }
+
+    // Internal structure for storing a time zone date from a SYSTEMTIME structure
+    // This date represents either the start or the end time for DST
+    static class TimeZoneDate {
+        String year;
+        int month;
+        int dayOfWeek;
+        int day;
+        int time;
+        int hour;
+        int minute;
+    }
+
+    @VisibleForTesting
+    static void clearTimeZoneCache() {
+        sTimeZoneCache.clear();
+    }
+
+    static void putRuleIntoTimeZoneInformation(byte[] bytes, int offset, RRule rrule, int hour,
+            int minute) {
+        // MSFT months are 1 based, same as RRule
+        setWord(bytes, offset + MSFT_SYSTEMTIME_MONTH, rrule.month);
+        // MSFT day of week starts w/ Sunday = 0; RRule starts w/ Sunday = 1
+        setWord(bytes, offset + MSFT_SYSTEMTIME_DAY_OF_WEEK, rrule.dayOfWeek - 1);
+        // 5 means "last" in MSFT land; for RRule, it's -1
+        setWord(bytes, offset + MSFT_SYSTEMTIME_DAY, rrule.week < 0 ? 5 : rrule.week);
+        // Turn hours/minutes into ms from midnight (per TimeZone)
+        setWord(bytes, offset + MSFT_SYSTEMTIME_HOUR, hour);
+        setWord(bytes, offset + MSFT_SYSTEMTIME_MINUTE, minute);
+    }
+
+    // Write a transition time into SYSTEMTIME data (via an offset into a byte array)
+    static void putTransitionMillisIntoSystemTime(byte[] bytes, int offset, long millis) {
+        GregorianCalendar cal = new GregorianCalendar(TimeZone.getDefault());
+        // Round to the next highest minute; we always write seconds as zero
+        cal.setTimeInMillis(millis + 30*SECONDS);
+
+        // MSFT months are 1 based; TimeZone is 0 based
+        setWord(bytes, offset + MSFT_SYSTEMTIME_MONTH, cal.get(Calendar.MONTH) + 1);
+        // MSFT day of week starts w/ Sunday = 0; TimeZone starts w/ Sunday = 1
+        setWord(bytes, offset + MSFT_SYSTEMTIME_DAY_OF_WEEK, cal.get(Calendar.DAY_OF_WEEK) - 1);
+
+        // Get the "day" in TimeZone format
+        int wom = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
+        // 5 means "last" in MSFT land; for TimeZone, it's -1
+        setWord(bytes, offset + MSFT_SYSTEMTIME_DAY, wom < 0 ? 5 : wom);
+
+        // Turn hours/minutes into ms from midnight (per TimeZone)
+        setWord(bytes, offset + MSFT_SYSTEMTIME_HOUR, getTrueTransitionHour(cal));
+        setWord(bytes, offset + MSFT_SYSTEMTIME_MINUTE, getTrueTransitionMinute(cal));
+     }
+
+    // Build a TimeZoneDate structure from a SYSTEMTIME within a byte array at a given offset
+    static TimeZoneDate getTimeZoneDateFromSystemTime(byte[] bytes, int offset) {
+        TimeZoneDate tzd = new TimeZoneDate();
+
+        // MSFT year is an int; TimeZone is a String
+        int num = getWord(bytes, offset + MSFT_SYSTEMTIME_YEAR);
+        tzd.year = Integer.toString(num);
+
+        // MSFT month = 0 means no daylight time
+        // MSFT months are 1 based; TimeZone is 0 based
+        num = getWord(bytes, offset + MSFT_SYSTEMTIME_MONTH);
+        if (num == 0) {
+            return null;
+        } else {
+            tzd.month = num -1;
+        }
+
+        // MSFT day of week starts w/ Sunday = 0; TimeZone starts w/ Sunday = 1
+        tzd.dayOfWeek = getWord(bytes, offset + MSFT_SYSTEMTIME_DAY_OF_WEEK) + 1;
+
+        // Get the "day" in TimeZone format
+        num = getWord(bytes, offset + MSFT_SYSTEMTIME_DAY);
+        // 5 means "last" in MSFT land; for TimeZone, it's -1
+        if (num == 5) {
+            tzd.day = -1;
+        } else {
+            tzd.day = num;
+        }
+
+        // Turn hours/minutes into ms from midnight (per TimeZone)
+        int hour = getWord(bytes, offset + MSFT_SYSTEMTIME_HOUR);
+        tzd.hour = hour;
+        int minute = getWord(bytes, offset + MSFT_SYSTEMTIME_MINUTE);
+        tzd.minute = minute;
+        tzd.time = (hour*HOURS) + (minute*MINUTES);
+
+        return tzd;
+    }
+
+    /**
+     * Build a GregorianCalendar, based on a time zone and TimeZoneDate.
+     * @param timeZone the time zone we're checking
+     * @param tzd the TimeZoneDate we're interested in
+     * @return a GregorianCalendar with the given time zone and date
+     */
+    static long getMillisAtTimeZoneDateTransition(TimeZone timeZone, TimeZoneDate tzd) {
+        GregorianCalendar testCalendar = new GregorianCalendar(timeZone);
+        testCalendar.set(GregorianCalendar.YEAR, sCurrentYear);
+        testCalendar.set(GregorianCalendar.MONTH, tzd.month);
+        testCalendar.set(GregorianCalendar.DAY_OF_WEEK, tzd.dayOfWeek);
+        testCalendar.set(GregorianCalendar.DAY_OF_WEEK_IN_MONTH, tzd.day);
+        testCalendar.set(GregorianCalendar.HOUR_OF_DAY, tzd.hour);
+        testCalendar.set(GregorianCalendar.MINUTE, tzd.minute);
+        testCalendar.set(GregorianCalendar.SECOND, 0);
+        return testCalendar.getTimeInMillis();
+    }
+
+    /**
+     * Return a GregorianCalendar representing the first standard/daylight transition between a
+     * start time and an end time in the given time zone
+     * @param tz a TimeZone the time zone in which we're looking for transitions
+     * @param startTime the start time for the test
+     * @param endTime the end time for the test
+     * @param startInDaylightTime whether daylight time is in effect at the startTime
+     * @return a GregorianCalendar representing the transition or null if none
+     */
+    static GregorianCalendar findTransitionDate(TimeZone tz, long startTime,
+            long endTime, boolean startInDaylightTime) {
+        long startingEndTime = endTime;
+        Date date = null;
+
+        // We'll keep splitting the difference until we're within a minute
+        while ((endTime - startTime) > MINUTES) {
+            long checkTime = ((startTime + endTime) / 2) + 1;
+            date = new Date(checkTime);
+            boolean inDaylightTime = tz.inDaylightTime(date);
+            if (inDaylightTime != startInDaylightTime) {
+                endTime = checkTime;
+            } else {
+                startTime = checkTime;
+            }
+        }
+
+        // If these are the same, we're really messed up; return null
+        if (endTime == startingEndTime) {
+            return null;
+        }
+
+        // Set up our calendar and return it
+        GregorianCalendar calendar = new GregorianCalendar(tz);
+        calendar.setTimeInMillis(startTime);
+        return calendar;
+    }
+
+    /**
+     * Return a Base64 representation of a MSFT TIME_ZONE_INFORMATION structure from a TimeZone
+     * that might be found in an Event; use cached result, if possible
+     * @param tz the TimeZone
+     * @return the Base64 String representing a Microsoft TIME_ZONE_INFORMATION element
+     */
+    static public String timeZoneToTziString(TimeZone tz) {
+        String tziString = sTziStringCache.get(tz);
+        if (tziString != null) {
+            if (Eas.USER_LOG) {
+                ExchangeService.log(TAG, "TZI string for " + tz.getDisplayName() +
+                        " found in cache.");
+            }
+            return tziString;
+        }
+        tziString = timeZoneToTziStringImpl(tz);
+        sTziStringCache.put(tz, tziString);
+        return tziString;
+    }
+
+    /**
+     * A class for storing RRULE information.  The RRULE members can be accessed individually or
+     * an RRULE string can be created with toString()
+     */
+    static class RRule {
+        static final int RRULE_NONE = 0;
+        static final int RRULE_DAY_WEEK = 1;
+        static final int RRULE_DATE = 2;
+
+        int type;
+        int dayOfWeek;
+        int week;
+        int month;
+        int date;
+
+        /**
+         * Create an RRULE based on month and date
+         * @param _month the month (1 = JAN, 12 = DEC)
+         * @param _date the date in the month (1-31)
+         */
+        RRule(int _month, int _date) {
+            type = RRULE_DATE;
+            month = _month;
+            date = _date;
+        }
+
+        /**
+         * Create an RRULE based on month, day of week, and week #
+         * @param _month the month (1 = JAN, 12 = DEC)
+         * @param _dayOfWeek the day of the week (1 = SU, 7 = SA)
+         * @param _week the week in the month (1-5 or -1 for last)
+         */
+        RRule(int _month, int _dayOfWeek, int _week) {
+            type = RRULE_DAY_WEEK;
+            month = _month;
+            dayOfWeek = _dayOfWeek;
+            week = _week;
+        }
+
+        @Override
+        public String toString() {
+            if (type == RRULE_DAY_WEEK) {
+                return "FREQ=YEARLY;BYMONTH=" + month + ";BYDAY=" + week +
+                    sDayTokens[dayOfWeek - 1];
+            } else {
+                return "FREQ=YEARLY;BYMONTH=" + month + ";BYMONTHDAY=" + date;
+            }
+       }
+    }
+
+    /**
+     * Generate an RRULE string for an array of GregorianCalendars, if possible.  For now, we are
+     * only looking for rules based on the same date in a month or a specific instance of a day of
+     * the week in a month (e.g. 2nd Tuesday or last Friday).  Indeed, these are the only kinds of
+     * rules used in the current tzinfo database.
+     * @param calendars an array of GregorianCalendar, set to a series of transition times in
+     * consecutive years starting with the current year
+     * @return an RRULE or null if none could be inferred from the calendars
+     */
+    static RRule inferRRuleFromCalendars(GregorianCalendar[] calendars) {
+        // Let's see if we can make a rule about these
+        GregorianCalendar calendar = calendars[0];
+        if (calendar == null) return null;
+        int month = calendar.get(Calendar.MONTH);
+        int date = calendar.get(Calendar.DAY_OF_MONTH);
+        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
+        int week = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
+        int maxWeek = calendar.getActualMaximum(Calendar.DAY_OF_WEEK_IN_MONTH);
+        boolean dateRule = false;
+        boolean dayOfWeekRule = false;
+        for (int i = 1; i < calendars.length; i++) {
+            GregorianCalendar cal = calendars[i];
+            if (cal == null) return null;
+            // If it's not the same month, there's no rule
+            if (cal.get(Calendar.MONTH) != month) {
+                return null;
+            } else if (dayOfWeek == cal.get(Calendar.DAY_OF_WEEK)) {
+                // Ok, it seems to be the same day of the week
+                if (dateRule) {
+                    return null;
+                }
+                dayOfWeekRule = true;
+                int thisWeek = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
+                if (week != thisWeek) {
+                    if (week < 0 || week == maxWeek) {
+                        int thisMaxWeek = cal.getActualMaximum(Calendar.DAY_OF_WEEK_IN_MONTH);
+                        if (thisWeek == thisMaxWeek) {
+                            // We'll use -1 (i.e. last) week
+                            week = -1;
+                            continue;
+                        }
+                    }
+                    return null;
+                }
+            } else if (date == cal.get(Calendar.DAY_OF_MONTH)) {
+                // Maybe the same day of the month?
+                if (dayOfWeekRule) {
+                    return null;
+                }
+                dateRule = true;
+            } else {
+                return null;
+            }
+        }
+
+        if (dateRule) {
+            return new RRule(month + 1, date);
+        }
+        // sDayTokens is 0 based (SU = 0); Calendar days of week are 1 based (SU = 1)
+        // iCalendar months are 1 based; Calendar months are 0 based
+        // So we adjust these when building the string
+        return new RRule(month + 1, dayOfWeek, week);
+    }
+
+    /**
+     * Generate an rfc2445 utcOffset from minutes offset from GMT
+     * These look like +0800 or -0100
+     * @param offsetMinutes minutes offset from GMT (east is positive, west is negative
+     * @return a utcOffset
+     */
+    static String utcOffsetString(int offsetMinutes) {
+        StringBuilder sb = new StringBuilder();
+        int hours = offsetMinutes / 60;
+        if (hours < 0) {
+            sb.append('-');
+            hours = 0 - hours;
+        } else {
+            sb.append('+');
+        }
+        int minutes = offsetMinutes % 60;
+        if (hours < 10) {
+            sb.append('0');
+        }
+        sb.append(hours);
+        if (minutes < 10) {
+            sb.append('0');
+        }
+        sb.append(minutes);
+        return sb.toString();
+    }
+
+    /**
+     * Fill the passed in GregorianCalendars arrays with DST transition information for this and
+     * the following years (based on the length of the arrays)
+     * @param tz the time zone
+     * @param toDaylightCalendars an array of GregorianCalendars, one for each year, representing
+     * the transition to daylight time
+     * @param toStandardCalendars an array of GregorianCalendars, one for each year, representing
+     * the transition to standard time
+     * @return true if transitions could be found for all years, false otherwise
+     */
+    static boolean getDSTCalendars(TimeZone tz, GregorianCalendar[] toDaylightCalendars,
+            GregorianCalendar[] toStandardCalendars) {
+        // We'll use the length of the arrays to determine how many years to check
+        int maxYears = toDaylightCalendars.length;
+        if (toStandardCalendars.length != maxYears) {
+            return false;
+        }
+        // Get the transitions for this year and the next few years
+        for (int i = 0; i < maxYears; i++) {
+            GregorianCalendar cal = new GregorianCalendar(tz);
+            cal.set(sCurrentYear + i, Calendar.JANUARY, 1, 0, 0, 0);
+            long startTime = cal.getTimeInMillis();
+            // Calculate end of year; no need to be insanely precise
+            long endOfYearTime = startTime + (365*DAYS) + (DAYS>>2);
+            Date date = new Date(startTime);
+            boolean startInDaylightTime = tz.inDaylightTime(date);
+            // Find the first transition, and store
+            cal = findTransitionDate(tz, startTime, endOfYearTime, startInDaylightTime);
+            if (cal == null) {
+                return false;
+            } else if (startInDaylightTime) {
+                toStandardCalendars[i] = cal;
+            } else {
+                toDaylightCalendars[i] = cal;
+            }
+            // Find the second transition, and store
+            cal = findTransitionDate(tz, startTime, endOfYearTime, !startInDaylightTime);
+            if (cal == null) {
+                return false;
+            } else if (startInDaylightTime) {
+                toDaylightCalendars[i] = cal;
+            } else {
+                toStandardCalendars[i] = cal;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Write out the STANDARD block of VTIMEZONE and end the VTIMEZONE
+     * @param writer the SimpleIcsWriter we're using
+     * @param tz the time zone
+     * @param offsetString the offset string in VTIMEZONE format (e.g. +0800)
+     * @throws IOException
+     */
+    static private void writeNoDST(SimpleIcsWriter writer, TimeZone tz, String offsetString)
+            throws IOException {
+        writer.writeTag("BEGIN", "STANDARD");
+        writer.writeTag("TZOFFSETFROM", offsetString);
+        writer.writeTag("TZOFFSETTO", offsetString);
+        // Might as well use start of epoch for start date
+        writer.writeTag("DTSTART", millisToEasDateTime(0L));
+        writer.writeTag("END", "STANDARD");
+        writer.writeTag("END", "VTIMEZONE");
+    }
+
+    /** Write a VTIMEZONE block for a given TimeZone into a SimpleIcsWriter
+     * @param tz the TimeZone to be used in the conversion
+     * @param writer the SimpleIcsWriter to be used
+     * @throws IOException
+     */
+    static void timeZoneToVTimezone(TimeZone tz, SimpleIcsWriter writer)
+            throws IOException {
+        // We'll use these regardless of whether there's DST in this time zone or not
+        int rawOffsetMinutes = tz.getRawOffset() / MINUTES;
+        String standardOffsetString = utcOffsetString(rawOffsetMinutes);
+
+        // Preamble for all of our VTIMEZONEs
+        writer.writeTag("BEGIN", "VTIMEZONE");
+        writer.writeTag("TZID", tz.getID());
+        writer.writeTag("X-LIC-LOCATION", tz.getDisplayName());
+
+        // Simplest case is no daylight time
+        if (!tz.useDaylightTime()) {
+            writeNoDST(writer, tz, standardOffsetString);
+            return;
+        }
+
+        int maxYears = 3;
+        GregorianCalendar[] toDaylightCalendars = new GregorianCalendar[maxYears];
+        GregorianCalendar[] toStandardCalendars = new GregorianCalendar[maxYears];
+        if (!getDSTCalendars(tz, toDaylightCalendars, toStandardCalendars)) {
+            writeNoDST(writer, tz, standardOffsetString);
+            return;
+        }
+        // Try to find a rule to cover these yeras
+        RRule daylightRule = inferRRuleFromCalendars(toDaylightCalendars);
+        RRule standardRule = inferRRuleFromCalendars(toStandardCalendars);
+        String daylightOffsetString =
+            utcOffsetString(rawOffsetMinutes + (tz.getDSTSavings() / MINUTES));
+        // We'll use RRULE's if we found both
+        // Otherwise we write the first as DTSTART and the others as RDATE
+        boolean hasRule = daylightRule != null && standardRule != null;
+
+        // Write the DAYLIGHT block
+        writer.writeTag("BEGIN", "DAYLIGHT");
+        writer.writeTag("TZOFFSETFROM", standardOffsetString);
+        writer.writeTag("TZOFFSETTO", daylightOffsetString);
+        writer.writeTag("DTSTART",
+                transitionMillisToVCalendarTime(
+                        toDaylightCalendars[0].getTimeInMillis(), tz, true));
+        if (hasRule) {
+            writer.writeTag("RRULE", daylightRule.toString());
+        } else {
+            for (int i = 1; i < maxYears; i++) {
+                writer.writeTag("RDATE", transitionMillisToVCalendarTime(
+                        toDaylightCalendars[i].getTimeInMillis(), tz, true));
+            }
+        }
+        writer.writeTag("END", "DAYLIGHT");
+        // Write the STANDARD block
+        writer.writeTag("BEGIN", "STANDARD");
+        writer.writeTag("TZOFFSETFROM", daylightOffsetString);
+        writer.writeTag("TZOFFSETTO", standardOffsetString);
+        writer.writeTag("DTSTART",
+                transitionMillisToVCalendarTime(
+                        toStandardCalendars[0].getTimeInMillis(), tz, false));
+        if (hasRule) {
+            writer.writeTag("RRULE", standardRule.toString());
+        } else {
+            for (int i = 1; i < maxYears; i++) {
+                writer.writeTag("RDATE", transitionMillisToVCalendarTime(
+                        toStandardCalendars[i].getTimeInMillis(), tz, true));
+            }
+        }
+        writer.writeTag("END", "STANDARD");
+        // And we're done
+        writer.writeTag("END", "VTIMEZONE");
+    }
+
+    /**
+     * Find the next transition to occur (i.e. after the current date/time)
+     * @param transitions calendars representing transitions to/from DST
+     * @return millis for the first transition after the current date/time
+     */
+    static long findNextTransition(long startingMillis, GregorianCalendar[] transitions) {
+        for (GregorianCalendar transition: transitions) {
+            long transitionMillis = transition.getTimeInMillis();
+            if (transitionMillis > startingMillis) {
+                return transitionMillis;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Calculate the Base64 representation of a MSFT TIME_ZONE_INFORMATION structure from a TimeZone
+     * that might be found in an Event.  Since the internal representation of the TimeZone is hidden
+     * from us we'll find the DST transitions and build the structure from that information
+     * @param tz the TimeZone
+     * @return the Base64 String representing a Microsoft TIME_ZONE_INFORMATION element
+     */
+    static String timeZoneToTziStringImpl(TimeZone tz) {
+        String tziString;
+        byte[] tziBytes = new byte[MSFT_TIME_ZONE_SIZE];
+        int standardBias = - tz.getRawOffset();
+        standardBias /= 60*SECONDS;
+        setLong(tziBytes, MSFT_TIME_ZONE_BIAS_OFFSET, standardBias);
+        // If this time zone has daylight savings time, we need to do more work
+        if (tz.useDaylightTime()) {
+            GregorianCalendar[] toDaylightCalendars = new GregorianCalendar[3];
+            GregorianCalendar[] toStandardCalendars = new GregorianCalendar[3];
+            // See if we can get transitions for a few years; if not, we can't generate DST info
+            // for this time zone
+            if (getDSTCalendars(tz, toDaylightCalendars, toStandardCalendars)) {
+                // Try to find a rule to cover these years
+                RRule daylightRule = inferRRuleFromCalendars(toDaylightCalendars);
+                RRule standardRule = inferRRuleFromCalendars(toStandardCalendars);
+                if ((daylightRule != null) && (daylightRule.type == RRule.RRULE_DAY_WEEK) &&
+                        (standardRule != null) && (standardRule.type == RRule.RRULE_DAY_WEEK)) {
+                    // We need both rules and they have to be DAY/WEEK type
+                    // Write month, day of week, week, hour, minute
+                    putRuleIntoTimeZoneInformation(tziBytes, MSFT_TIME_ZONE_STANDARD_DATE_OFFSET,
+                            standardRule,
+                            getTrueTransitionHour(toStandardCalendars[0]),
+                            getTrueTransitionMinute(toStandardCalendars[0]));
+                    putRuleIntoTimeZoneInformation(tziBytes, MSFT_TIME_ZONE_DAYLIGHT_DATE_OFFSET,
+                            daylightRule,
+                            getTrueTransitionHour(toDaylightCalendars[0]),
+                            getTrueTransitionMinute(toDaylightCalendars[0]));
+                } else {
+                    // If there's no rule, we'll use the first transition to standard/to daylight
+                    // And indicate that it's just for this year...
+                    long now = System.currentTimeMillis();
+                    long standardTransition = findNextTransition(now, toStandardCalendars);
+                    long daylightTransition = findNextTransition(now, toDaylightCalendars);
+                    // If we can't find transitions, we can't do DST
+                    if (standardTransition != 0 && daylightTransition != 0) {
+                        putTransitionMillisIntoSystemTime(tziBytes,
+                                MSFT_TIME_ZONE_STANDARD_DATE_OFFSET, standardTransition);
+                        putTransitionMillisIntoSystemTime(tziBytes,
+                                MSFT_TIME_ZONE_DAYLIGHT_DATE_OFFSET, daylightTransition);
+                    }
+                }
+            }
+            int dstOffset = tz.getDSTSavings();
+            setLong(tziBytes, MSFT_TIME_ZONE_DAYLIGHT_BIAS_OFFSET, - dstOffset / MINUTES);
+        }
+        byte[] tziEncodedBytes = Base64.encode(tziBytes, Base64.NO_WRAP);
+        tziString = new String(tziEncodedBytes);
+        return tziString;
+    }
+
+    /**
+     * Given a String as directly read from EAS, returns a TimeZone corresponding to that String
+     * @param timeZoneString the String read from the server
+     * @param precision the number of milliseconds of precision in TimeZone determination
+     * @return the TimeZone, or TimeZone.getDefault() if not found
+     */
+    @VisibleForTesting
+    static TimeZone tziStringToTimeZone(String timeZoneString, int precision) {
+        // If we have this time zone cached, use that value and return
+        TimeZone timeZone = sTimeZoneCache.get(timeZoneString);
+        if (timeZone != null) {
+            if (Eas.USER_LOG) {
+                ExchangeService.log(TAG, " Using cached TimeZone " + timeZone.getID());
+            }
+        } else {
+            timeZone = tziStringToTimeZoneImpl(timeZoneString, precision);
+            if (timeZone == null) {
+                // If we don't find a match, we just return the current TimeZone.  In theory, this
+                // shouldn't be happening...
+                ExchangeService.alwaysLog("TimeZone not found using default: " + timeZoneString);
+                timeZone = TimeZone.getDefault();
+            }
+            sTimeZoneCache.put(timeZoneString, timeZone);
+        }
+        return timeZone;
+    }
+
+    /**
+     * The standard entry to EAS time zone conversion, using one minute as the precision
+     */
+    static public TimeZone tziStringToTimeZone(String timeZoneString) {
+        return tziStringToTimeZone(timeZoneString, MINUTES);
+    }
+
+    /**
+     * Given a String as directly read from EAS, tries to find a TimeZone in the database of all
+     * time zones that corresponds to that String.  If the test time zone string includes DST and
+     * we don't find a match, and we're using standard precision, we try again with lenient
+     * precision, which is a bit better than guessing
+     * @param timeZoneString the String read from the server
+     * @return the TimeZone, or null if not found
+     */
+    static TimeZone tziStringToTimeZoneImpl(String timeZoneString, int precision) {
+        TimeZone timeZone = null;
+        // First, we need to decode the base64 string
+        byte[] timeZoneBytes = Base64.decode(timeZoneString, Base64.DEFAULT);
+
+        // Then, we get the bias (similar to a rawOffset); for TimeZone, we need ms
+        // but EAS gives us minutes, so do the conversion.  Note that EAS is the bias that's added
+        // to the time zone to reach UTC; our library uses the time from UTC to our time zone, so
+        // we need to change the sign
+        int bias = -1 * getLong(timeZoneBytes, MSFT_TIME_ZONE_BIAS_OFFSET) * MINUTES;
+
+        // Get all of the time zones with the bias as a rawOffset; if there aren't any, we return
+        // the default time zone
+        String[] zoneIds = TimeZone.getAvailableIDs(bias);
+        if (zoneIds.length > 0) {
+            // Try to find an existing TimeZone from the data provided by EAS
+            // We start by pulling out the date that standard time begins
+            TimeZoneDate dstEnd =
+                getTimeZoneDateFromSystemTime(timeZoneBytes, MSFT_TIME_ZONE_STANDARD_DATE_OFFSET);
+            if (dstEnd == null) {
+                // If the default time zone is a match
+                TimeZone defaultTimeZone = TimeZone.getDefault();
+                if (!defaultTimeZone.useDaylightTime() &&
+                        ArrayUtils.contains(zoneIds, defaultTimeZone.getID())) {
+                    if (Eas.USER_LOG) {
+                        ExchangeService.log(TAG, "TimeZone without DST found to be default: " +
+                                defaultTimeZone.getID());
+                    }
+                    return defaultTimeZone;
+                }
+                // In this case, there is no daylight savings time, so the only interesting data
+                // for possible matches is the offset and DST availability; we'll take the first
+                // match for those
+                for (String zoneId: zoneIds) {
+                    timeZone = TimeZone.getTimeZone(zoneId);
+                    if (!timeZone.useDaylightTime()) {
+                        if (Eas.USER_LOG) {
+                            ExchangeService.log(TAG, "TimeZone without DST found by offset: " +
+                                    timeZone.getID());
+                        }
+                        return timeZone;
+                    }
+                }
+                // None found, return null
+                return null;
+            } else {
+                TimeZoneDate dstStart = getTimeZoneDateFromSystemTime(timeZoneBytes,
+                        MSFT_TIME_ZONE_DAYLIGHT_DATE_OFFSET);
+                // See comment above for bias...
+                long dstSavings =
+                    -1 * getLong(timeZoneBytes, MSFT_TIME_ZONE_DAYLIGHT_BIAS_OFFSET) * MINUTES;
+
+                // We'll go through each time zone to find one with the same DST transitions and
+                // savings length
+                for (String zoneId: zoneIds) {
+                    // Get the TimeZone using the zoneId
+                    timeZone = TimeZone.getTimeZone(zoneId);
+
+                    // Our strategy here is to check just before and just after the transitions
+                    // and see whether the check for daylight time matches the expectation
+                    // If both transitions match, then we have a match for the offset and start/end
+                    // of dst.  That's the best we can do for now, since there's no other info
+                    // provided by EAS (i.e. we can't get dynamic transitions, etc.)
+
+                    // Check one minute before and after DST start transition
+                    long millisAtTransition = getMillisAtTimeZoneDateTransition(timeZone, dstStart);
+                    Date before = new Date(millisAtTransition - precision);
+                    Date after = new Date(millisAtTransition + precision);
+                    if (timeZone.inDaylightTime(before)) continue;
+                    if (!timeZone.inDaylightTime(after)) continue;
+
+                    // Check one minute before and after DST end transition
+                    millisAtTransition = getMillisAtTimeZoneDateTransition(timeZone, dstEnd);
+                    // Note that we need to subtract an extra hour here, because we end up with
+                    // gaining an hour in the transition BACK to standard time
+                    before = new Date(millisAtTransition - (dstSavings + precision));
+                    after = new Date(millisAtTransition + precision);
+                    if (!timeZone.inDaylightTime(before)) continue;
+                    if (timeZone.inDaylightTime(after)) continue;
+
+                    // Check that the savings are the same
+                    if (dstSavings != timeZone.getDSTSavings()) continue;
+                    return timeZone;
+                }
+                // In this case, there is no daylight savings time, so the only interesting data
+                // is the offset, and we know that all of the zoneId's match; we'll take the first
+                boolean lenient = false;
+                if ((dstStart.hour != dstEnd.hour) && (precision == STANDARD_DST_PRECISION)) {
+                    timeZone = tziStringToTimeZoneImpl(timeZoneString, LENIENT_DST_PRECISION);
+                    lenient = true;
+                } else {
+                    timeZone = TimeZone.getTimeZone(zoneIds[0]);
+                }
+                if (Eas.USER_LOG) {
+                    ExchangeService.log(TAG,
+                            "No TimeZone with correct DST settings; using " +
+                            (lenient ? "lenient" : "first") + ": " + timeZone.getID());
+                }
+                return timeZone;
+            }
+        }
+        return null;
+    }
+
+    static public String convertEmailDateTimeToCalendarDateTime(String date) {
+        // Format for email date strings is 2010-02-23T16:00:00.000Z
+        // Format for calendar date strings is 20100223T160000Z
+       return date.substring(0, 4) + date.substring(5, 7) + date.substring(8, 13) +
+           date.substring(14, 16) + date.substring(17, 19) + 'Z';
+    }
+
+    static String formatTwo(int num) {
+        if (num <= 12) {
+            return sTwoCharacterNumbers[num];
+        } else
+            return Integer.toString(num);
+    }
+
+    /**
+     * Generate an EAS formatted date/time string based on GMT. See below for details.
+     */
+    static public String millisToEasDateTime(long millis) {
+        return millisToEasDateTime(millis, sGmtTimeZone, true);
+    }
+
+    /**
+     * Generate an EAS formatted local date/time string from a time and a time zone. If the final
+     * argument is false, only a date will be returned (e.g. 20100331)
+     * @param millis a time in milliseconds
+     * @param tz a time zone
+     * @param withTime if the time is to be included in the string
+     * @return an EAS formatted string indicating the date (and time) in the given time zone
+     */
+    static public String millisToEasDateTime(long millis, TimeZone tz, boolean withTime) {
+        StringBuilder sb = new StringBuilder();
+        GregorianCalendar cal = new GregorianCalendar(tz);
+        cal.setTimeInMillis(millis);
+        sb.append(cal.get(Calendar.YEAR));
+        sb.append(formatTwo(cal.get(Calendar.MONTH) + 1));
+        sb.append(formatTwo(cal.get(Calendar.DAY_OF_MONTH)));
+        if (withTime) {
+            sb.append('T');
+            sb.append(formatTwo(cal.get(Calendar.HOUR_OF_DAY)));
+            sb.append(formatTwo(cal.get(Calendar.MINUTE)));
+            sb.append(formatTwo(cal.get(Calendar.SECOND)));
+            if (tz == sGmtTimeZone) {
+                sb.append('Z');
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Return the true minute at which a transition occurs
+     * Our transition time should be the in the minute BEFORE the transition
+     * If this minute is 59, set minute to 0 and increment the hour
+     * NOTE: We don't want to add a minute and retrieve minute/hour from the Calendar, because
+     * Calendar time will itself be influenced by the transition!  So adding 1 minute to
+     * 01:59 (assume PST->PDT) will become 03:00, which isn't what we want (we want 02:00)
+     *
+     * @param calendar the calendar holding the transition date/time
+     * @return the true minute of the transition
+     */
+    static int getTrueTransitionMinute(GregorianCalendar calendar) {
+        int minute = calendar.get(Calendar.MINUTE);
+        if (minute == 59) {
+            minute = 0;
+        }
+        return minute;
+    }
+
+    /**
+     * Return the true hour at which a transition occurs
+     * See description for getTrueTransitionMinute, above
+     * @param calendar the calendar holding the transition date/time
+     * @return the true hour of the transition
+     */
+    static int getTrueTransitionHour(GregorianCalendar calendar) {
+        int hour = calendar.get(Calendar.HOUR_OF_DAY);
+        hour++;
+        if (hour == 24) {
+            hour = 0;
+        }
+        return hour;
+    }
+
+    /**
+     * Generate a date/time string suitable for VTIMEZONE from a transition time in millis
+     * The format is YYYYMMDDTHHMMSS
+     * @param millis a transition time in milliseconds
+     * @param tz a time zone
+     * @param dst whether we're entering daylight time
+     */
+    static String transitionMillisToVCalendarTime(long millis, TimeZone tz, boolean dst) {
+        StringBuilder sb = new StringBuilder();
+        GregorianCalendar cal = new GregorianCalendar(tz);
+        cal.setTimeInMillis(millis);
+        sb.append(cal.get(Calendar.YEAR));
+        sb.append(formatTwo(cal.get(Calendar.MONTH) + 1));
+        sb.append(formatTwo(cal.get(Calendar.DAY_OF_MONTH)));
+        sb.append('T');
+        sb.append(formatTwo(getTrueTransitionHour(cal)));
+        sb.append(formatTwo(getTrueTransitionMinute(cal)));
+        sb.append(formatTwo(0));
+        return sb.toString();
+    }
+
+    /**
+     * Returns a UTC calendar with year/month/day from local calendar and h/m/s/ms = 0
+     * @param time the time in seconds of an all-day event in local time
+     * @return the time in seconds in UTC
+     */
+    static public long getUtcAllDayCalendarTime(long time, TimeZone localTimeZone) {
+        return transposeAllDayTime(time, localTimeZone, UTC_TIMEZONE);
+    }
+
+    /**
+     * Returns a local calendar with year/month/day from UTC calendar and h/m/s/ms = 0
+     * @param time the time in seconds of an all-day event in UTC
+     * @return the time in seconds in local time
+     */
+    static public long getLocalAllDayCalendarTime(long time, TimeZone localTimeZone) {
+        return transposeAllDayTime(time, UTC_TIMEZONE, localTimeZone);
+    }
+
+    static private long transposeAllDayTime(long time, TimeZone fromTimeZone,
+            TimeZone toTimeZone) {
+        GregorianCalendar fromCalendar = new GregorianCalendar(fromTimeZone);
+        fromCalendar.setTimeInMillis(time);
+        GregorianCalendar toCalendar = new GregorianCalendar(toTimeZone);
+        // Set this calendar with correct year, month, and day, but zero hour, minute, and seconds
+        toCalendar.set(fromCalendar.get(GregorianCalendar.YEAR),
+                fromCalendar.get(GregorianCalendar.MONTH),
+                fromCalendar.get(GregorianCalendar.DATE), 0, 0, 0);
+        toCalendar.set(GregorianCalendar.MILLISECOND, 0);
+        return toCalendar.getTimeInMillis();
+    }
+
+    static void addByDay(StringBuilder rrule, int dow, int wom) {
+        rrule.append(";BYDAY=");
+        boolean addComma = false;
+        for (int i = 0; i < 7; i++) {
+            if ((dow & 1) == 1) {
+                if (addComma) {
+                    rrule.append(',');
+                }
+                if (wom > 0) {
+                    // 5 = last week -> -1
+                    // So -1SU = last sunday
+                    rrule.append(wom == 5 ? -1 : wom);
+                }
+                rrule.append(sDayTokens[i]);
+                addComma = true;
+            }
+            dow >>= 1;
+        }
+    }
+
+    static void addBySetpos(StringBuilder rrule, int dow, int wom) {
+        // Indicate the days, but don't use wom in this case (it's used in the BYSETPOS);
+        addByDay(rrule, dow, 0);
+        rrule.append(";BYSETPOS=");
+        rrule.append(wom == 5 ? "-1" : wom);
+    }
+
+    static void addByMonthDay(StringBuilder rrule, int dom) {
+        // 127 means last day of the month
+        if (dom == 127) {
+            dom = -1;
+        }
+        rrule.append(";BYMONTHDAY=" + dom);
+    }
+
+    /**
+     * Generate the String version of the EAS integer for a given BYDAY value in an rrule
+     * @param dow the BYDAY value of the rrule
+     * @return the String version of the EAS value of these days
+     */
+    static String generateEasDayOfWeek(String dow) {
+        int bits = 0;
+        int bit = 1;
+        for (String token: sDayTokens) {
+            // If we can find the day in the dow String, add the bit to our bits value
+            if (dow.indexOf(token) >= 0) {
+                bits |= bit;
+            }
+            bit <<= 1;
+        }
+        return Integer.toString(bits);
+    }
+
+    /**
+     * Extract the value of a token in an RRULE string
+     * @param rrule an RRULE string
+     * @param token a token to look for in the RRULE
+     * @return the value of that token
+     */
+    static String tokenFromRrule(String rrule, String token) {
+        int start = rrule.indexOf(token);
+        if (start < 0) return null;
+        int len = rrule.length();
+        start += token.length();
+        int end = start;
+        char c;
+        do {
+            c = rrule.charAt(end++);
+            if ((c == ';') || (end == len)) {
+                if (end == len) end++;
+                return rrule.substring(start, end -1);
+            }
+        } while (true);
+    }
+
+    /**
+     * Reformat an RRULE style UNTIL to an EAS style until
+     */
+    @VisibleForTesting
+    static String recurrenceUntilToEasUntil(String until) {
+        // Get a calendar in our local time zone
+        GregorianCalendar localCalendar = new GregorianCalendar(TimeZone.getDefault());
+        // Set the time per GMT time in the 'until'
+        localCalendar.setTimeInMillis(Utility.parseDateTimeToMillis(until));
+        StringBuilder sb = new StringBuilder();
+        // Build a string with local year/month/date
+        sb.append(localCalendar.get(Calendar.YEAR));
+        sb.append(formatTwo(localCalendar.get(Calendar.MONTH) + 1));
+        sb.append(formatTwo(localCalendar.get(Calendar.DAY_OF_MONTH)));
+        // EAS ignores the time in 'until'; go figure
+        sb.append("T000000Z");
+        return sb.toString();
+    }
+
+    /**
+     * Convenience method to add "count", "interval", and "until" to an EAS calendar stream
+     * According to EAS docs, OCCURRENCES must always come before INTERVAL
+     */
+    static private void addCountIntervalAndUntil(String rrule, Serializer s) throws IOException {
+        String count = tokenFromRrule(rrule, "COUNT=");
+        if (count != null) {
+            s.data(Tags.CALENDAR_RECURRENCE_OCCURRENCES, count);
+        }
+        String interval = tokenFromRrule(rrule, "INTERVAL=");
+        if (interval != null) {
+            s.data(Tags.CALENDAR_RECURRENCE_INTERVAL, interval);
+        }
+        String until = tokenFromRrule(rrule, "UNTIL=");
+        if (until != null) {
+            s.data(Tags.CALENDAR_RECURRENCE_UNTIL, recurrenceUntilToEasUntil(until));
+        }
+    }
+
+    static private void addByDay(String byDay, Serializer s) throws IOException {
+        // This can be 1WE (1st Wednesday) or -1FR (last Friday)
+        int weekOfMonth = byDay.charAt(0);
+        String bareByDay;
+        if (weekOfMonth == '-') {
+            // -1 is the only legal case (last week) Use "5" for EAS
+            weekOfMonth = 5;
+            bareByDay = byDay.substring(2);
+        } else {
+            weekOfMonth = weekOfMonth - '0';
+            bareByDay = byDay.substring(1);
+        }
+        s.data(Tags.CALENDAR_RECURRENCE_WEEKOFMONTH, Integer.toString(weekOfMonth));
+        s.data(Tags.CALENDAR_RECURRENCE_DAYOFWEEK, generateEasDayOfWeek(bareByDay));
+    }
+
+    static private void addByDaySetpos(String byDay, String bySetpos, Serializer s)
+            throws IOException {
+        int weekOfMonth = bySetpos.charAt(0);
+        if (weekOfMonth == '-') {
+            // -1 is the only legal case (last week) Use "5" for EAS
+            weekOfMonth = 5;
+        } else {
+            weekOfMonth = weekOfMonth - '0';
+        }
+        s.data(Tags.CALENDAR_RECURRENCE_WEEKOFMONTH, Integer.toString(weekOfMonth));
+        s.data(Tags.CALENDAR_RECURRENCE_DAYOFWEEK, generateEasDayOfWeek(byDay));
+    }
+
+    /**
+     * Write recurrence information to EAS based on the RRULE in CalendarProvider
+     * @param rrule the RRULE, from CalendarProvider
+     * @param startTime, the DTSTART of this Event
+     * @param s the Serializer we're using to write WBXML data
+     * @throws IOException
+     */
+    // NOTE: For the moment, we're only parsing recurrence types that are supported by the
+    // Calendar app UI, which is a subset of possible recurrence types
+    // This code must be updated when the Calendar adds new functionality
+    static public void recurrenceFromRrule(String rrule, long startTime, Serializer s)
+            throws IOException {
+        if (Eas.USER_LOG) {
+            ExchangeService.log(TAG, "RRULE: " + rrule);
+        }
+        String freq = tokenFromRrule(rrule, "FREQ=");
+        // If there's no FREQ=X, then we don't write a recurrence
+        // Note that we duplicate s.start(Tags.CALENDAR_RECURRENCE); s.end(); to prevent the
+        // possibility of writing out a partial recurrence stanza
+        if (freq != null) {
+            if (freq.equals("DAILY")) {
+                s.start(Tags.CALENDAR_RECURRENCE);
+                s.data(Tags.CALENDAR_RECURRENCE_TYPE, "0");
+                addCountIntervalAndUntil(rrule, s);
+                s.end();
+            } else if (freq.equals("WEEKLY")) {
+                s.start(Tags.CALENDAR_RECURRENCE);
+                s.data(Tags.CALENDAR_RECURRENCE_TYPE, "1");
+                // Requires a day of week (whereas RRULE does not)
+                addCountIntervalAndUntil(rrule, s);
+                String byDay = tokenFromRrule(rrule, "BYDAY=");
+                if (byDay != null) {
+                    s.data(Tags.CALENDAR_RECURRENCE_DAYOFWEEK, generateEasDayOfWeek(byDay));
+                    // Find week number (1-4 and 5 for last)
+                    if (byDay.startsWith("-1")) {
+                        s.data(Tags.CALENDAR_RECURRENCE_WEEKOFMONTH, "5");
+                    } else {
+                        char c = byDay.charAt(0);
+                        if (c >= '1' && c <= '4') {
+                            s.data(Tags.CALENDAR_RECURRENCE_WEEKOFMONTH, byDay.substring(0, 1));
+                        }
+                    }
+                }
+                s.end();
+            } else if (freq.equals("MONTHLY")) {
+                String byMonthDay = tokenFromRrule(rrule, "BYMONTHDAY=");
+                if (byMonthDay != null) {
+                    s.start(Tags.CALENDAR_RECURRENCE);
+                    // Special case for last day of month
+                    if (byMonthDay == "-1") {
+                        s.data(Tags.CALENDAR_RECURRENCE_TYPE, "3");
+                        addCountIntervalAndUntil(rrule, s);
+                        s.data(Tags.CALENDAR_RECURRENCE_DAYOFWEEK, "127");
+                    } else {
+                        // The nth day of the month
+                        s.data(Tags.CALENDAR_RECURRENCE_TYPE, "2");
+                        addCountIntervalAndUntil(rrule, s);
+                        s.data(Tags.CALENDAR_RECURRENCE_DAYOFMONTH, byMonthDay);
+                    }
+                    s.end();
+                } else {
+                    String byDay = tokenFromRrule(rrule, "BYDAY=");
+                    String bySetpos = tokenFromRrule(rrule, "BYSETPOS=");
+                    if (byDay != null) {
+                        s.start(Tags.CALENDAR_RECURRENCE);
+                        s.data(Tags.CALENDAR_RECURRENCE_TYPE, "3");
+                        addCountIntervalAndUntil(rrule, s);
+                        if (bySetpos != null) {
+                            addByDaySetpos(byDay, bySetpos, s);
+                        } else {
+                            addByDay(byDay, s);
+                        }
+                        s.end();
+                    }
+                }
+            } else if (freq.equals("YEARLY")) {
+                String byMonth = tokenFromRrule(rrule, "BYMONTH=");
+                String byMonthDay = tokenFromRrule(rrule, "BYMONTHDAY=");
+                String byDay = tokenFromRrule(rrule, "BYDAY=");
+                if (byMonth == null && byMonthDay == null) {
+                    // Calculate the month and day from the startDate
+                    GregorianCalendar cal = new GregorianCalendar();
+                    cal.setTimeInMillis(startTime);
+                    cal.setTimeZone(TimeZone.getDefault());
+                    byMonth = Integer.toString(cal.get(Calendar.MONTH) + 1);
+                    byMonthDay = Integer.toString(cal.get(Calendar.DAY_OF_MONTH));
+                }
+                if (byMonth != null && (byMonthDay != null || byDay != null)) {
+                    s.start(Tags.CALENDAR_RECURRENCE);
+                    s.data(Tags.CALENDAR_RECURRENCE_TYPE, byDay == null ? "5" : "6");
+                    addCountIntervalAndUntil(rrule, s);
+                    s.data(Tags.CALENDAR_RECURRENCE_MONTHOFYEAR, byMonth);
+                    // Note that both byMonthDay and byDay can't be true in a valid RRULE
+                    if (byMonthDay != null) {
+                        s.data(Tags.CALENDAR_RECURRENCE_DAYOFMONTH, byMonthDay);
+                    } else {
+                        addByDay(byDay, s);
+                    }
+                    s.end();
+                }
+            }
+        }
+    }
+
+    /**
+     * Build an RRULE String from EAS recurrence information
+     * @param type the type of recurrence
+     * @param occurrences how many recurrences (instances)
+     * @param interval the interval between recurrences
+     * @param dow day of the week
+     * @param dom day of the month
+     * @param wom week of the month
+     * @param moy month of the year
+     * @param until the last recurrence time
+     * @return a valid RRULE String
+     */
+    static public String rruleFromRecurrence(int type, int occurrences, int interval, int dow,
+            int dom, int wom, int moy, String until) {
+        StringBuilder rrule = new StringBuilder("FREQ=" + sTypeToFreq[type]);
+        // INTERVAL and COUNT
+        if (occurrences > 0) {
+            rrule.append(";COUNT=" + occurrences);
+        }
+        if (interval > 0) {
+            rrule.append(";INTERVAL=" + interval);
+        }
+
+        // Days, weeks, months, etc.
+        switch(type) {
+            case 0: // DAILY
+            case 1: // WEEKLY
+                if (dow > 0) addByDay(rrule, dow, wom);
+                break;
+            case 2: // MONTHLY
+                if (dom > 0) addByMonthDay(rrule, dom);
+                break;
+            case 3: // MONTHLY (on the nth day)
+                // 127 is a special case meaning "last day of the month"
+                if (dow == 127) {
+                    rrule.append(";BYMONTHDAY=-1");
+                // week 5 and dow = weekdays -> last weekday (need BYSETPOS)
+                } else if (wom == 5 && (dow == EAS_WEEKDAYS || dow == EAS_WEEKENDS)) {
+                    addBySetpos(rrule, dow, wom);
+                } else if (dow > 0) addByDay(rrule, dow, wom);
+                break;
+            case 5: // YEARLY (specific day)
+                if (dom > 0) addByMonthDay(rrule, dom);
+                if (moy > 0) {
+                    rrule.append(";BYMONTH=" + moy);
+                }
+                break;
+            case 6: // YEARLY
+                if (dow > 0) addByDay(rrule, dow, wom);
+                if (dom > 0) addByMonthDay(rrule, dom);
+                if (moy > 0) {
+                    rrule.append(";BYMONTH=" + moy);
+                }
+                break;
+            default:
+                break;
+        }
+
+        // UNTIL comes last
+        if (until != null) {
+            rrule.append(";UNTIL=" + until);
+        }
+
+        if (Eas.USER_LOG) {
+            Log.d(Logging.LOG_TAG, "Created rrule: " + rrule);
+        }
+        return rrule.toString();
+    }
+
+    /**
+     * Create a Calendar in CalendarProvider to which synced Events will be linked
+     * @param service the sync service requesting Calendar creation
+     * @param account the account being synced
+     * @param mailbox the Exchange mailbox for the calendar
+     * @return the unique id of the Calendar
+     */
+    static public long createCalendar(EasSyncService service, Account account, Mailbox mailbox) {
+        // Create a Calendar object
+        ContentValues cv = new ContentValues();
+        // TODO How will this change if the user changes his account display name?
+        cv.put(Calendars.CALENDAR_DISPLAY_NAME, account.mDisplayName);
+        cv.put(Calendars.ACCOUNT_NAME, account.mEmailAddress);
+        cv.put(Calendars.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+        cv.put(Calendars.SYNC_EVENTS, 1);
+        cv.put(Calendars.VISIBLE, 1);
+        // Don't show attendee status if we're the organizer
+        cv.put(Calendars.CAN_ORGANIZER_RESPOND, 0);
+        cv.put(Calendars.CAN_MODIFY_TIME_ZONE, 0);
+        cv.put(Calendars.MAX_REMINDERS, 1);
+        cv.put(Calendars.ALLOWED_REMINDERS, ALLOWED_REMINDER_TYPES);
+        cv.put(Calendars.ALLOWED_ATTENDEE_TYPES, ALLOWED_ATTENDEE_TYPES);
+        cv.put(Calendars.ALLOWED_AVAILABILITY, ALLOWED_AVAILABILITIES);
+
+        // TODO Coordinate account colors w/ Calendar, if possible
+        int color = new AccountServiceProxy(service.mContext).getAccountColor(account.mId);
+        cv.put(Calendars.CALENDAR_COLOR, color);
+        cv.put(Calendars.CALENDAR_TIME_ZONE, Time.getCurrentTimezone());
+        cv.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER);
+        cv.put(Calendars.OWNER_ACCOUNT, account.mEmailAddress);
+
+        Uri uri = service.mContentResolver.insert(
+                asSyncAdapter(Calendars.CONTENT_URI, account.mEmailAddress,
+                        Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), cv);
+        // We save the id of the calendar into mSyncStatus
+        if (uri != null) {
+            String stringId = uri.getPathSegments().get(1);
+            mailbox.mSyncStatus = stringId;
+            return Long.parseLong(stringId);
+        }
+        return -1;
+    }
+
+    static Uri asSyncAdapter(Uri uri, String account, String accountType) {
+        return uri.buildUpon()
+                .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,
+                        "true")
+                .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
+                .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
+    }
+
+    /**
+     * Return the uid for an event based on its globalObjId
+     * @param globalObjId the base64 encoded String provided by EAS
+     * @return the uid for the calendar event
+     */
+    static public String getUidFromGlobalObjId(String globalObjId) {
+        StringBuilder sb = new StringBuilder();
+        // First get the decoded base64
+        try {
+            byte[] idBytes = Base64.decode(globalObjId, Base64.DEFAULT);
+            String idString = new String(idBytes);
+            // If the base64 decoded string contains the magic substring: "vCal-Uid", then
+            // the actual uid is hidden within; the magic substring is never at the start of the
+            // decoded base64
+            int index = idString.indexOf("vCal-Uid");
+            if (index > 0) {
+                // The uid starts after "vCal-Uidxxxx", where xxxx are padding
+                // characters.  And it ends before the last character, which is ascii 0
+                return idString.substring(index + 12, idString.length() - 1);
+            } else {
+                // This is an EAS uid. Go through the bytes and write out the hex
+                // values as characters; this is what we'll need to pass back to EAS
+                // when responding to the invitation
+                for (byte b: idBytes) {
+                    Utility.byteToHex(sb, b);
+                }
+                return sb.toString();
+            }
+        } catch (RuntimeException e) {
+            // In the worst of cases (bad format, etc.), we can always return the input
+            return globalObjId;
+        }
+    }
+
+    /**
+     * Get a selfAttendeeStatus from a busy status
+     * The default here is NONE (i.e. we don't know the status)
+     * Note that a busy status of FREE must mean NONE as well, since it can't mean declined
+     * (there would be no event)
+     * @param busyStatus the busy status, from EAS
+     * @return the corresponding value for selfAttendeeStatus
+     */
+    static public int attendeeStatusFromBusyStatus(int busyStatus) {
+        int attendeeStatus;
+        switch (busyStatus) {
+            case BUSY_STATUS_BUSY:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_ACCEPTED;
+                break;
+            case BUSY_STATUS_TENTATIVE:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_TENTATIVE;
+                break;
+            case BUSY_STATUS_FREE:
+            case BUSY_STATUS_OUT_OF_OFFICE:
+            default:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
+        }
+        return attendeeStatus;
+    }
+
+    /**
+     * Get a selfAttendeeStatus from a response type (EAS 14+)
+     * The default here is NONE (i.e. we don't know the status), though in theory this can't happen
+     * @param busyStatus the response status, from EAS
+     * @return the corresponding value for selfAttendeeStatus
+     */
+    static public int attendeeStatusFromResponseType(int responseType) {
+        int attendeeStatus;
+        switch (responseType) {
+            case RESPONSE_TYPE_NOT_RESPONDED:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
+                break;
+            case RESPONSE_TYPE_ACCEPTED:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_ACCEPTED;
+                break;
+            case RESPONSE_TYPE_TENTATIVE:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_TENTATIVE;
+                break;
+            case RESPONSE_TYPE_DECLINED:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_DECLINED;
+                break;
+            default:
+                attendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
+        }
+        return attendeeStatus;
+    }
+
+    /** Get a busy status from a selfAttendeeStatus
+     * The default here is BUSY
+     * @param selfAttendeeStatus from CalendarProvider2
+     * @return the corresponding value of busy status
+     */
+    static public int busyStatusFromAttendeeStatus(int selfAttendeeStatus) {
+        int busyStatus;
+        switch (selfAttendeeStatus) {
+            case Attendees.ATTENDEE_STATUS_DECLINED:
+            case Attendees.ATTENDEE_STATUS_NONE:
+            case Attendees.ATTENDEE_STATUS_INVITED:
+                busyStatus = BUSY_STATUS_FREE;
+                break;
+            case Attendees.ATTENDEE_STATUS_TENTATIVE:
+                busyStatus = BUSY_STATUS_TENTATIVE;
+                break;
+            case Attendees.ATTENDEE_STATUS_ACCEPTED:
+            default:
+                busyStatus = BUSY_STATUS_BUSY;
+                break;
+        }
+        return busyStatus;
+    }
+
+    static public String buildMessageTextFromEntityValues(Context context,
+            ContentValues entityValues, StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+        Resources resources = context.getResources();
+        // TODO: Add more detail to message text
+        // Right now, we're using.. When: Tuesday, March 5th at 2:00pm
+        // What we're missing is the duration and any recurrence information.  So this should be
+        // more like... When: Tuesdays, starting March 5th from 2:00pm - 3:00pm
+        // This would require code to build complex strings, and it will have to wait
+        // For now, we'll just use the meeting_recurring string
+
+        boolean allDayEvent = false;
+        if (entityValues.containsKey(Events.ALL_DAY)) {
+            Integer ade = entityValues.getAsInteger(Events.ALL_DAY);
+            allDayEvent = (ade != null) && (ade == 1);
+        }
+        boolean recurringEvent = !entityValues.containsKey(Events.ORIGINAL_SYNC_ID) &&
+            entityValues.containsKey(Events.RRULE);
+
+        String dateTimeString;
+        int res;
+        long startTime = entityValues.getAsLong(Events.DTSTART);
+        if (allDayEvent) {
+            Date date = new Date(getLocalAllDayCalendarTime(startTime, TimeZone.getDefault()));
+            dateTimeString = DateFormat.getDateInstance().format(date);
+            res = recurringEvent ? R.string.meeting_allday_recurring : R.string.meeting_allday;
+        } else {
+            dateTimeString = DateFormat.getDateTimeInstance().format(new Date(startTime));
+            res = recurringEvent ? R.string.meeting_recurring : R.string.meeting_when;
+        }
+        sb.append(resources.getString(res, dateTimeString));
+
+        String location = null;
+        if (entityValues.containsKey(Events.EVENT_LOCATION)) {
+            location = entityValues.getAsString(Events.EVENT_LOCATION);
+            if (!TextUtils.isEmpty(location)) {
+                sb.append("\n");
+                sb.append(resources.getString(R.string.meeting_where, location));
+            }
+        }
+        // If there's a description for this event, append it
+        String desc = entityValues.getAsString(Events.DESCRIPTION);
+        if (desc != null) {
+            sb.append("\n--\n");
+            sb.append(desc);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Add an attendee to the ics attachment and the to list of the Message being composed
+     * @param ics the ics attachment writer
+     * @param toList the list of addressees for this email
+     * @param attendeeName the name of the attendee
+     * @param attendeeEmail the email address of the attendee
+     * @param messageFlag the flag indicating the action to be indicated by the message
+     * @param account the sending account of the email
+     */
+    static private void addAttendeeToMessage(SimpleIcsWriter ics, ArrayList<Address> toList,
+            String attendeeName, String attendeeEmail, int messageFlag, Account account) {
+        if ((messageFlag & Message.FLAG_OUTGOING_MEETING_REQUEST_MASK) != 0) {
+            String icalTag = ICALENDAR_ATTENDEE_INVITE;
+            if ((messageFlag & Message.FLAG_OUTGOING_MEETING_CANCEL) != 0) {
+                icalTag = ICALENDAR_ATTENDEE_CANCEL;
+            }
+            if (attendeeName != null) {
+                icalTag += ";CN=" + SimpleIcsWriter.quoteParamValue(attendeeName);
+            }
+            ics.writeTag(icalTag, "MAILTO:" + attendeeEmail);
+            toList.add(attendeeName == null ? new Address(attendeeEmail) :
+                new Address(attendeeEmail, attendeeName));
+        } else if (attendeeEmail.equalsIgnoreCase(account.mEmailAddress)) {
+            String icalTag = null;
+            switch (messageFlag) {
+                case Message.FLAG_OUTGOING_MEETING_ACCEPT:
+                    icalTag = ICALENDAR_ATTENDEE_ACCEPT;
+                    break;
+                case Message.FLAG_OUTGOING_MEETING_DECLINE:
+                    icalTag = ICALENDAR_ATTENDEE_DECLINE;
+                    break;
+                case Message.FLAG_OUTGOING_MEETING_TENTATIVE:
+                    icalTag = ICALENDAR_ATTENDEE_TENTATIVE;
+                    break;
+            }
+            if (icalTag != null) {
+                if (attendeeName != null) {
+                    icalTag += ";CN="
+                            + SimpleIcsWriter.quoteParamValue(attendeeName);
+                }
+                ics.writeTag(icalTag, "MAILTO:" + attendeeEmail);
+            }
+        }
+    }
+
+    /**
+     * Create a Message for an (Event) Entity
+     * @param entity the Entity for the Event (as might be retrieved by CalendarProvider)
+     * @param messageFlag the Message.FLAG_XXX constant indicating the type of email to be sent
+     * @param the unique id of this Event, or null if it can be retrieved from the Event
+     * @param the user's account
+     * @return a Message with many fields pre-filled (more later)
+     */
+    static public Message createMessageForEntity(Context context, Entity entity,
+            int messageFlag, String uid, Account account) {
+        return createMessageForEntity(context, entity, messageFlag, uid, account,
+                null /*specifiedAttendee*/);
+    }
+
+    static public EmailContent.Message createMessageForEntity(Context context, Entity entity,
+            int messageFlag, String uid, Account account, String specifiedAttendee) {
+        ContentValues entityValues = entity.getEntityValues();
+        ArrayList<NamedContentValues> subValues = entity.getSubValues();
+        boolean isException = entityValues.containsKey(Events.ORIGINAL_SYNC_ID);
+        boolean isReply = false;
+
+        EmailContent.Message msg = new EmailContent.Message();
+        msg.mFlags = messageFlag;
+        msg.mTimeStamp = System.currentTimeMillis();
+
+        String method;
+        if ((messageFlag & EmailContent.Message.FLAG_OUTGOING_MEETING_INVITE) != 0) {
+            method = "REQUEST";
+        } else if ((messageFlag & EmailContent.Message.FLAG_OUTGOING_MEETING_CANCEL) != 0) {
+            method = "CANCEL";
+        } else {
+            method = "REPLY";
+            isReply = true;
+        }
+
+        try {
+            // Create our iCalendar writer and start generating tags
+            SimpleIcsWriter ics = new SimpleIcsWriter();
+            ics.writeTag("BEGIN", "VCALENDAR");
+            ics.writeTag("METHOD", method);
+            ics.writeTag("PRODID", "AndroidEmail");
+            ics.writeTag("VERSION", "2.0");
+
+            // Our default vcalendar time zone is UTC, but this will change (below) if we're
+            // sending a recurring event, in which case we use local time
+            TimeZone vCalendarTimeZone = sGmtTimeZone;
+            String vCalendarDateSuffix = "";
+
+            // Check for all day event
+            boolean allDayEvent = false;
+            if (entityValues.containsKey(Events.ALL_DAY)) {
+                Integer ade = entityValues.getAsInteger(Events.ALL_DAY);
+                allDayEvent = (ade != null) && (ade == 1);
+                if (allDayEvent) {
+                    // Example: DTSTART;VALUE=DATE:20100331 (all day event)
+                    vCalendarDateSuffix = ";VALUE=DATE";
+                }
+            }
+
+            // If we're inviting people and the meeting is recurring, we need to send our time zone
+            // information and make sure to send DTSTART/DTEND in local time (unless, of course,
+            // this is an all-day event).  Recurring, for this purpose, includes exceptions to
+            // recurring events
+            if (!isReply && !allDayEvent &&
+                    (entityValues.containsKey(Events.RRULE) ||
+                            entityValues.containsKey(Events.ORIGINAL_SYNC_ID))) {
+                vCalendarTimeZone = TimeZone.getDefault();
+                // Write the VTIMEZONE block to the writer
+                timeZoneToVTimezone(vCalendarTimeZone, ics);
+                // Example: DTSTART;TZID=US/Pacific:20100331T124500
+                vCalendarDateSuffix = ";TZID=" + vCalendarTimeZone.getID();
+            }
+
+            ics.writeTag("BEGIN", "VEVENT");
+            if (uid == null) {
+                uid = entityValues.getAsString(Events.SYNC_DATA2);
+            }
+            if (uid != null) {
+                ics.writeTag("UID", uid);
+            }
+
+            if (entityValues.containsKey("DTSTAMP")) {
+                ics.writeTag("DTSTAMP", entityValues.getAsString("DTSTAMP"));
+            } else {
+                ics.writeTag("DTSTAMP", millisToEasDateTime(System.currentTimeMillis()));
+            }
+
+            long startTime = entityValues.getAsLong(Events.DTSTART);
+            if (startTime != 0) {
+                ics.writeTag("DTSTART" + vCalendarDateSuffix,
+                        millisToEasDateTime(startTime, vCalendarTimeZone, !allDayEvent));
+            }
+
+            // If this is an Exception, we send the recurrence-id, which is just the original
+            // instance time
+            if (isException) {
+                long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
+                ics.writeTag("RECURRENCE-ID" + vCalendarDateSuffix,
+                        millisToEasDateTime(originalTime, vCalendarTimeZone, !allDayEvent));
+            }
+
+            if (!entityValues.containsKey(Events.DURATION)) {
+                if (entityValues.containsKey(Events.DTEND)) {
+                    ics.writeTag("DTEND" + vCalendarDateSuffix,
+                            millisToEasDateTime(
+                                    entityValues.getAsLong(Events.DTEND), vCalendarTimeZone,
+                                    !allDayEvent));
+                }
+            } else {
+                // Convert this into millis and add it to DTSTART for DTEND
+                // We'll use 1 hour as a default
+                long durationMillis = HOURS;
+                Duration duration = new Duration();
+                try {
+                    duration.parse(entityValues.getAsString(Events.DURATION));
+                    durationMillis = duration.getMillis();
+                } catch (DateException e) {
+                    // We'll use the default in this case
+                }
+                ics.writeTag("DTEND" + vCalendarDateSuffix,
+                        millisToEasDateTime(
+                                startTime + durationMillis, vCalendarTimeZone, !allDayEvent));
+            }
+
+            String location = null;
+            if (entityValues.containsKey(Events.EVENT_LOCATION)) {
+                location = entityValues.getAsString(Events.EVENT_LOCATION);
+                ics.writeTag("LOCATION", location);
+            }
+
+            String sequence = entityValues.getAsString(SYNC_VERSION);
+            if (sequence == null) {
+                sequence = "0";
+            }
+
+            // We'll use 0 to mean a meeting invitation
+            int titleId = 0;
+            switch (messageFlag) {
+                case Message.FLAG_OUTGOING_MEETING_INVITE:
+                    if (!sequence.equals("0")) {
+                        titleId = R.string.meeting_updated;
+                    }
+                    break;
+                case Message.FLAG_OUTGOING_MEETING_ACCEPT:
+                    titleId = R.string.meeting_accepted;
+                    break;
+                case Message.FLAG_OUTGOING_MEETING_DECLINE:
+                    titleId = R.string.meeting_declined;
+                    break;
+                case Message.FLAG_OUTGOING_MEETING_TENTATIVE:
+                    titleId = R.string.meeting_tentative;
+                    break;
+                case Message.FLAG_OUTGOING_MEETING_CANCEL:
+                    titleId = R.string.meeting_canceled;
+                    break;
+            }
+            Resources resources = context.getResources();
+            String title = entityValues.getAsString(Events.TITLE);
+            if (title == null) {
+                title = "";
+            }
+            ics.writeTag("SUMMARY", title);
+            // For meeting invitations just use the title
+            if (titleId == 0) {
+                msg.mSubject = title;
+            } else {
+                // Otherwise, use the additional text
+                msg.mSubject = resources.getString(titleId, title);
+            }
+
+            // Build the text for the message, starting with an initial line describing the
+            // exception (if this is one)
+            StringBuilder sb = new StringBuilder();
+            if (isException && !isReply) {
+                // Add the line, depending on whether this is a cancellation or update
+                Date date = new Date(entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME));
+                String dateString = DateFormat.getDateInstance().format(date);
+                if (titleId == R.string.meeting_canceled) {
+                    sb.append(resources.getString(R.string.exception_cancel, dateString));
+                } else {
+                    sb.append(resources.getString(R.string.exception_updated, dateString));
+                }
+                sb.append("\n\n");
+            }
+            String text =
+                CalendarUtilities.buildMessageTextFromEntityValues(context, entityValues, sb);
+
+            if (text.length() > 0) {
+                ics.writeTag("DESCRIPTION", text);
+            }
+            // And store the message text
+            msg.mText = text;
+            if (!isReply) {
+                if (entityValues.containsKey(Events.ALL_DAY)) {
+                    Integer ade = entityValues.getAsInteger(Events.ALL_DAY);
+                    ics.writeTag("X-MICROSOFT-CDO-ALLDAYEVENT", ade == 0 ? "FALSE" : "TRUE");
+                }
+
+                String rrule = entityValues.getAsString(Events.RRULE);
+                if (rrule != null) {
+                    ics.writeTag("RRULE", rrule);
+                }
+
+                // If we decide to send alarm information in the meeting request ics file,
+                // handle it here by looping through the subvalues
+            }
+
+            // Handle attendee data here; determine "to" list and add ATTENDEE tags to ics
+            String organizerName = null;
+            String organizerEmail = null;
+            ArrayList<Address> toList = new ArrayList<Address>();
+            for (NamedContentValues ncv: subValues) {
+                Uri ncvUri = ncv.uri;
+                ContentValues ncvValues = ncv.values;
+                if (ncvUri.equals(Attendees.CONTENT_URI)) {
+                    Integer relationship =
+                        ncvValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
+                    // If there's no relationship, we can't create this for EAS
+                    // Similarly, we need an attendee email for each invitee
+                    if (relationship != null &&
+                            ncvValues.containsKey(Attendees.ATTENDEE_EMAIL)) {
+                        // Organizer isn't among attendees in EAS
+                        if (relationship == Attendees.RELATIONSHIP_ORGANIZER) {
+                            organizerName = ncvValues.getAsString(Attendees.ATTENDEE_NAME);
+                            organizerEmail = ncvValues.getAsString(Attendees.ATTENDEE_EMAIL);
+                            continue;
+                        }
+                        String attendeeEmail = ncvValues.getAsString(Attendees.ATTENDEE_EMAIL);
+                        String attendeeName = ncvValues.getAsString(Attendees.ATTENDEE_NAME);
+
+                        // This shouldn't be possible, but allow for it
+                        if (attendeeEmail == null) continue;
+                        // If we only want to send to the specifiedAttendee, eliminate others here
+                        if ((specifiedAttendee != null) &&
+                                !attendeeEmail.equalsIgnoreCase(specifiedAttendee)) {
+                            continue;
+                        }
+
+                        addAttendeeToMessage(ics, toList, attendeeName, attendeeEmail, messageFlag,
+                                account);
+                    }
+                }
+            }
+
+            // Manually add the specifiedAttendee if he wasn't added in the Attendees loop
+            if (toList.isEmpty() && (specifiedAttendee != null)) {
+                addAttendeeToMessage(ics, toList, null, specifiedAttendee, messageFlag, account);
+            }
+
+            // Create the organizer tag for ical
+            if (organizerEmail != null) {
+                String icalTag = "ORGANIZER";
+                // We should be able to find this, assuming the Email is the user's email
+                // TODO Find this in the account
+                if (organizerName != null) {
+                    icalTag += ";CN=" + SimpleIcsWriter.quoteParamValue(organizerName);
+                }
+                ics.writeTag(icalTag, "MAILTO:" + organizerEmail);
+                if (isReply) {
+                    toList.add(organizerName == null ? new Address(organizerEmail) :
+                        new Address(organizerEmail, organizerName));
+                }
+            }
+
+            // If we have no "to" list, we're done
+            if (toList.isEmpty()) return null;
+
+            // Write out the "to" list
+            Address[] toArray = new Address[toList.size()];
+            int i = 0;
+            for (Address address: toList) {
+                toArray[i++] = address;
+            }
+            msg.mTo = Address.pack(toArray);
+
+            ics.writeTag("CLASS", "PUBLIC");
+            ics.writeTag("STATUS", (messageFlag == Message.FLAG_OUTGOING_MEETING_CANCEL) ?
+                    "CANCELLED" : "CONFIRMED");
+            ics.writeTag("TRANSP", "OPAQUE"); // What Exchange uses
+            ics.writeTag("PRIORITY", "5");  // 1 to 9, 5 = medium
+            ics.writeTag("SEQUENCE", sequence);
+            ics.writeTag("END", "VEVENT");
+            ics.writeTag("END", "VCALENDAR");
+
+            // Create the ics attachment using the "content" field
+            Attachment att = new Attachment();
+            att.mContentBytes = ics.getBytes();
+            att.mMimeType = "text/calendar; method=" + method;
+            att.mFileName = "invite.ics";
+            att.mSize = att.mContentBytes.length;
+            // We don't send content-disposition with this attachment
+            att.mFlags = Attachment.FLAG_ICS_ALTERNATIVE_PART;
+
+            // Add the attachment to the message
+            msg.mAttachments = new ArrayList<Attachment>();
+            msg.mAttachments.add(att);
+        } catch (IOException e) {
+            Log.w(TAG, "IOException in createMessageForEntity");
+            return null;
+        }
+
+        // Return the new Message to caller
+        return msg;
+    }
+
+    /**
+     * Create a Message for an Event that can be retrieved from CalendarProvider
+     * by its unique id
+     *
+     * @param cr a content resolver that can be used to query for the Event
+     * @param eventId the unique id of the Event
+     * @param messageFlag the Message.FLAG_XXX constant indicating the type of
+     *            email to be sent
+     * @param the unique id of this Event, or null if it can be retrieved from
+     *            the Event
+     * @param the user's account
+     * @param requireAddressees if true (the default), no Message is returned if
+     *            there aren't any addressees; if false, return the Message
+     *            regardless (addressees will be filled in later)
+     * @return a Message with many fields pre-filled (more later)
+     * @throws RemoteException if there is an issue retrieving the Event from
+     *             CalendarProvider
+     */
+    static public EmailContent.Message createMessageForEventId(Context context, long eventId,
+            int messageFlag, String uid, Account account) throws RemoteException {
+        return createMessageForEventId(context, eventId, messageFlag, uid, account,
+                null /* specifiedAttendee */);
+    }
+
+    static public EmailContent.Message createMessageForEventId(Context context, long eventId,
+            int messageFlag, String uid, Account account, String specifiedAttendee)
+            throws RemoteException {
+        ContentResolver cr = context.getContentResolver();
+        EntityIterator eventIterator = EventsEntity.newEntityIterator(cr.query(
+                ContentUris.withAppendedId(Events.CONTENT_URI, eventId), null, null, null, null),
+                cr);
+        try {
+            while (eventIterator.hasNext()) {
+                Entity entity = eventIterator.next();
+                return createMessageForEntity(context, entity, messageFlag, uid, account,
+                        specifiedAttendee);
+            }
+        } finally {
+            eventIterator.close();
+        }
+        return null;
+    }
+
+    /**
+     * Return a boolean value for an integer ContentValues column
+     * @param values a ContentValues object
+     * @param columnName the name of a column to be found in the ContentValues
+     * @return a boolean representation of the value of columnName in values; null and 0 = false,
+     * other integers = true
+     */
+    static public boolean getIntegerValueAsBoolean(ContentValues values, String columnName) {
+        Integer intValue = values.getAsInteger(columnName);
+        return (intValue != null && intValue != 0);
+    }
+}
diff --git a/exchange2/src/com/android/exchange/utility/FileLogger.java b/exchange2/src/com/android/exchange/utility/FileLogger.java
new file mode 100644
index 0000000..bb17151
--- /dev/null
+++ b/exchange2/src/com/android/exchange/utility/FileLogger.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange.utility;
+
+import android.content.Context;
+import android.os.Environment;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Date;
+
+public class FileLogger {
+    private static FileLogger LOGGER = null;
+    private static FileWriter sLogWriter = null;
+    public static String LOG_FILE_NAME =
+        Environment.getExternalStorageDirectory() + "/emaillog.txt";
+
+    public synchronized static FileLogger getLogger (Context c) {
+        LOGGER = new FileLogger();
+        return LOGGER;
+    }
+
+    private FileLogger() {
+        try {
+            sLogWriter = new FileWriter(LOG_FILE_NAME, true);
+        } catch (IOException e) {
+            // Doesn't matter
+        }
+    }
+
+    static public synchronized void close() {
+        if (sLogWriter != null) {
+            try {
+                sLogWriter.close();
+            } catch (IOException e) {
+                // Doesn't matter
+            }
+            sLogWriter = null;
+        }
+    }
+
+    static public synchronized void log(Exception e) {
+        if (sLogWriter != null) {
+            log("Exception", "Stack trace follows...");
+            PrintWriter pw = new PrintWriter(sLogWriter);
+            e.printStackTrace(pw);
+            pw.flush();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    static public synchronized void log(String prefix, String str) {
+        if (LOGGER == null) {
+            LOGGER = new FileLogger();
+            log("Logger", "\r\n\r\n --- New Log ---");
+        }
+        Date d = new Date();
+        int hr = d.getHours();
+        int min = d.getMinutes();
+        int sec = d.getSeconds();
+
+        // I don't use DateFormat here because (in my experience), it's much slower
+        StringBuffer sb = new StringBuffer(256);
+        sb.append('[');
+        sb.append(hr);
+        sb.append(':');
+        if (min < 10)
+            sb.append('0');
+        sb.append(min);
+        sb.append(':');
+        if (sec < 10) {
+            sb.append('0');
+        }
+        sb.append(sec);
+        sb.append("] ");
+        if (prefix != null) {
+            sb.append(prefix);
+            sb.append("| ");
+        }
+        sb.append(str);
+        sb.append("\r\n");
+        String s = sb.toString();
+
+        if (sLogWriter != null) {
+            try {
+                sLogWriter.write(s);
+                sLogWriter.flush();
+            } catch (IOException e) {
+                // Something might have happened to the sdcard
+                if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
+                    // If the card is mounted and we can create the writer, retry
+                    LOGGER = new FileLogger();
+                    if (sLogWriter != null) {
+                        try {
+                            log("FileLogger", "Exception writing log; recreating...");
+                            log(prefix, str);
+                        } catch (Exception e1) {
+                            // Nothing to do at this point
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/exchange2/src/com/android/exchange/utility/SimpleIcsWriter.java b/exchange2/src/com/android/exchange/utility/SimpleIcsWriter.java
new file mode 100644
index 0000000..1bb8463
--- /dev/null
+++ b/exchange2/src/com/android/exchange/utility/SimpleIcsWriter.java
@@ -0,0 +1,156 @@
+/* Copyright 2010, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.exchange.utility;
+
+import com.android.emailcommon.utility.Utility;
+
+import android.text.TextUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Class to generate iCalender object (*.ics) per RFC 5545.
+ */
+public class SimpleIcsWriter {
+    private static final int MAX_LINE_LENGTH = 75; // In bytes, excluding CRLF
+    private static final int CHAR_MAX_BYTES_IN_UTF8 = 4;  // Used to be 6, but RFC3629 limited it.
+    private final ByteArrayOutputStream mOut = new ByteArrayOutputStream();
+
+    public SimpleIcsWriter() {
+    }
+
+    /**
+     * Low level method to write a line, performing line-folding if necessary.
+     */
+    /* package for testing */ void writeLine(String string) {
+        int numBytes = 0;
+        for (byte b : Utility.toUtf8(string)) {
+            // Fold it when necessary.
+            // To make it simple, we assume all chars are 4 bytes.
+            // If not (and usually it's not), we end up wrapping earlier than necessary, but that's
+            // completely fine.
+            if (numBytes > (MAX_LINE_LENGTH - CHAR_MAX_BYTES_IN_UTF8)
+                    && Utility.isFirstUtf8Byte(b)) { // Only wrappable if it's before the first byte
+                mOut.write((byte) '\r');
+                mOut.write((byte) '\n');
+                mOut.write((byte) '\t');
+                numBytes = 1; // for TAB
+            }
+            mOut.write(b);
+            numBytes++;
+        }
+        mOut.write((byte) '\r');
+        mOut.write((byte) '\n');
+    }
+
+    /**
+     * Write a tag with a value.
+     */
+    public void writeTag(String name, String value) {
+        // Belt and suspenders here; don't crash on null value; just return
+        if (TextUtils.isEmpty(value)) {
+            return;
+        }
+
+        // The following properties take a TEXT value, which need to be escaped.
+        // (These property names should be all interned, so using equals() should be faster than
+        // using a hash table.)
+
+        // TODO make constants for these literals
+        if ("CALSCALE".equals(name)
+                || "METHOD".equals(name)
+                || "PRODID".equals(name)
+                || "VERSION".equals(name)
+                || "CATEGORIES".equals(name)
+                || "CLASS".equals(name)
+                || "COMMENT".equals(name)
+                || "DESCRIPTION".equals(name)
+                || "LOCATION".equals(name)
+                || "RESOURCES".equals(name)
+                || "STATUS".equals(name)
+                || "SUMMARY".equals(name)
+                || "TRANSP".equals(name)
+                || "TZID".equals(name)
+                || "TZNAME".equals(name)
+                || "CONTACT".equals(name)
+                || "RELATED-TO".equals(name)
+                || "UID".equals(name)
+                || "ACTION".equals(name)
+                || "REQUEST-STATUS".equals(name)
+                || "X-LIC-LOCATION".equals(name)
+                ) {
+            value = escapeTextValue(value);
+        }
+        writeLine(name + ":" + value);
+    }
+
+    /**
+     * For debugging
+     */
+    @Override
+    public String toString() {
+        return Utility.fromUtf8(getBytes());
+    }
+
+    /**
+     * @return the entire iCalendar invitation object.
+     */
+    public byte[] getBytes() {
+        try {
+            mOut.flush();
+        } catch (IOException wonthappen) {
+        }
+        return mOut.toByteArray();
+    }
+
+    /**
+     * Quote a param-value string, according to RFC 5545, section 3.1
+     */
+    public static String quoteParamValue(String paramValue) {
+        if (paramValue == null) {
+            return null;
+        }
+        // Wrap with double quotes.
+        // The spec doesn't allow putting double-quotes in a param value, so let's use single quotes
+        // as a substitute.
+        // It's not the smartest implementation.  e.g. we don't have to wrap an empty string with
+        // double quotes.  But it works.
+        return "\"" + paramValue.replace("\"", "'") + "\"";
+    }
+
+    /**
+     * Escape a TEXT value per RFC 5545 section 3.3.11
+     */
+    /* package for testing */ static String escapeTextValue(String s) {
+        StringBuilder sb = new StringBuilder(s.length());
+        for (int i = 0; i < s.length(); i++) {
+            char ch = s.charAt(i);
+            if (ch == '\n') {
+                sb.append("\\n");
+            } else if (ch == '\r') {
+                // Remove CR
+            } else if (ch == ',' || ch == ';' || ch == '\\') {
+                sb.append('\\');
+                sb.append(ch);
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+}
diff --git a/exchange2/src/com/android/exchange/utility/UriCodec.java b/exchange2/src/com/android/exchange/utility/UriCodec.java
new file mode 100644
index 0000000..d8811c6
--- /dev/null
+++ b/exchange2/src/com/android/exchange/utility/UriCodec.java
@@ -0,0 +1,216 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT 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.exchange.utility;
+
+import java.io.ByteArrayOutputStream;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.nio.charset.Charsets;
+
+// Note: This class copied verbatim from libcore.net
+
+/**
+ * Encodes and decodes {@code application/x-www-form-urlencoded} content.
+ * Subclasses define exactly which characters are legal.
+ *
+ * <p>By default, UTF-8 is used to encode escaped characters. A single input
+ * character like "\u0080" may be encoded to multiple octets like %C2%80.
+ */
+public abstract class UriCodec {
+
+    /**
+     * Returns true if {@code c} does not need to be escaped.
+     */
+    protected abstract boolean isRetained(char c);
+
+    /**
+     * Throws if {@code s} is invalid according to this encoder.
+     */
+    public final String validate(String uri, int start, int end, String name)
+            throws URISyntaxException {
+        for (int i = start; i < end; ) {
+            char ch = uri.charAt(i);
+            if ((ch >= 'a' && ch <= 'z')
+                    || (ch >= 'A' && ch <= 'Z')
+                    || (ch >= '0' && ch <= '9')
+                    || isRetained(ch)) {
+                i++;
+            } else if (ch == '%') {
+                if (i + 2 >= end) {
+                    throw new URISyntaxException(uri, "Incomplete % sequence in " + name, i);
+                }
+                int d1 = hexToInt(uri.charAt(i + 1));
+                int d2 = hexToInt(uri.charAt(i + 2));
+                if (d1 == -1 || d2 == -1) {
+                    throw new URISyntaxException(uri, "Invalid % sequence: "
+                            + uri.substring(i, i + 3) + " in " + name, i);
+                }
+                i += 3;
+            } else {
+                throw new URISyntaxException(uri, "Illegal character in " + name, i);
+            }
+        }
+        return uri.substring(start, end);
+    }
+
+    /**
+     * Throws if {@code s} contains characters that are not letters, digits or
+     * in {@code legal}.
+     */
+    public static void validateSimple(String s, String legal)
+            throws URISyntaxException {
+        for (int i = 0; i < s.length(); i++) {
+            char ch = s.charAt(i);
+            if (!((ch >= 'a' && ch <= 'z')
+                    || (ch >= 'A' && ch <= 'Z')
+                    || (ch >= '0' && ch <= '9')
+                    || legal.indexOf(ch) > -1)) {
+                throw new URISyntaxException(s, "Illegal character", i);
+            }
+        }
+    }
+
+    /**
+     * Encodes {@code s} and appends the result to {@code builder}.
+     *
+     * @param isPartiallyEncoded true to fix input that has already been
+     *     partially or fully encoded. For example, input of "hello%20world" is
+     *     unchanged with isPartiallyEncoded=true but would be double-escaped to
+     *     "hello%2520world" otherwise.
+     */
+    private void appendEncoded(StringBuilder builder, String s, Charset charset,
+            boolean isPartiallyEncoded) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+
+        int escapeStart = -1;
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if ((c >= 'a' && c <= 'z')
+                    || (c >= 'A' && c <= 'Z')
+                    || (c >= '0' && c <= '9')
+                    || isRetained(c)
+                    || (c == '%' && isPartiallyEncoded)) {
+                if (escapeStart != -1) {
+                    appendHex(builder, s.substring(escapeStart, i), charset);
+                    escapeStart = -1;
+                }
+                if (c == '%' && isPartiallyEncoded) {
+                    // this is an encoded 3-character sequence like "%20"
+                    builder.append(s, i, i + 3);
+                    i += 2;
+                } else if (c == ' ') {
+                    builder.append('+');
+                } else {
+                    builder.append(c);
+                }
+            } else if (escapeStart == -1) {
+                escapeStart = i;
+            }
+        }
+        if (escapeStart != -1) {
+            appendHex(builder, s.substring(escapeStart, s.length()), charset);
+        }
+    }
+
+    public final String encode(String s, Charset charset) {
+        // Guess a bit larger for encoded form
+        StringBuilder builder = new StringBuilder(s.length() + 16);
+        appendEncoded(builder, s, charset, false);
+        return builder.toString();
+    }
+
+    public final void appendEncoded(StringBuilder builder, String s) {
+        appendEncoded(builder, s, Charsets.UTF_8, false);
+    }
+
+    public final void appendPartiallyEncoded(StringBuilder builder, String s) {
+        appendEncoded(builder, s, Charsets.UTF_8, true);
+    }
+
+    /**
+     * @param convertPlus true to convert '+' to ' '.
+     */
+    public static String decode(String s, boolean convertPlus, Charset charset) {
+        if (s.indexOf('%') == -1 && (!convertPlus || s.indexOf('+') == -1)) {
+            return s;
+        }
+
+        StringBuilder result = new StringBuilder(s.length());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        for (int i = 0; i < s.length();) {
+            char c = s.charAt(i);
+            if (c == '%') {
+                do {
+                    if (i + 2 >= s.length()) {
+                        throw new IllegalArgumentException("Incomplete % sequence at: " + i);
+                    }
+                    int d1 = hexToInt(s.charAt(i + 1));
+                    int d2 = hexToInt(s.charAt(i + 2));
+                    if (d1 == -1 || d2 == -1) {
+                        throw new IllegalArgumentException("Invalid % sequence " +
+                                s.substring(i, i + 3) + " at " + i);
+                    }
+                    out.write((byte) ((d1 << 4) + d2));
+                    i += 3;
+                } while (i < s.length() && s.charAt(i) == '%');
+                result.append(new String(out.toByteArray(), charset));
+                out.reset();
+            } else {
+                if (convertPlus && c == '+') {
+                    c = ' ';
+                }
+                result.append(c);
+                i++;
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * Like {@link Character#digit}, but without support for non-ASCII
+     * characters.
+     */
+    private static int hexToInt(char c) {
+        if ('0' <= c && c <= '9') {
+            return c - '0';
+        } else if ('a' <= c && c <= 'f') {
+            return 10 + (c - 'a');
+        } else if ('A' <= c && c <= 'F') {
+            return 10 + (c - 'A');
+        } else {
+            return -1;
+        }
+    }
+
+    public static String decode(String s) {
+        return decode(s, false, Charsets.UTF_8);
+    }
+
+    private static void appendHex(StringBuilder builder, String s, Charset charset) {
+        for (byte b : s.getBytes(charset)) {
+            appendHex(builder, b);
+        }
+    }
+
+    private static void appendHex(StringBuilder sb, byte b) {
+        sb.append('%');
+        sb.append(Byte.toHexString(b, true));
+    }
+}
diff --git a/exchange2/src/com/android/exchange/utility/patent_disclaimer.txt b/exchange2/src/com/android/exchange/utility/patent_disclaimer.txt
new file mode 100644
index 0000000..8a715a3
--- /dev/null
+++ b/exchange2/src/com/android/exchange/utility/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+-----------------------------
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the source code made available hereunder is
+unencumbered by third-party patents.  Those intending to use this source code in hardware or
+software products are advised that implementations of this code, including in open source software
+or shareware, may require patent licenses from the relevant patent holders.
+
+-----------------------------
diff --git a/exchange2/tests/Android.mk b/exchange2/tests/Android.mk
new file mode 100644
index 0000000..0f36cd2
--- /dev/null
+++ b/exchange2/tests/Android.mk
@@ -0,0 +1,34 @@
+# Copyright 2008, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Notice that we don't have to include the src files of Exchange because, by
+# running the tests using an instrumentation targeting Exchange, we
+# automatically get all of its classes loaded into our environment.
+
+LOCAL_PACKAGE_NAME := Exchange2Tests
+
+LOCAL_INSTRUMENTATION_FOR := Exchange2
+
+include $(BUILD_PACKAGE)
diff --git a/exchange2/tests/AndroidManifest.xml b/exchange2/tests/AndroidManifest.xml
new file mode 100644
index 0000000..6511938
--- /dev/null
+++ b/exchange2/tests/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.exchange.tests"
+    >
+
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--
+    This declares that this app uses the instrumentation test runner targeting
+    the package of com.android.email.  To run the tests use the command:
+    "adb shell am instrument -w com.android.exchange.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.exchange"
+                     android:label="Tests for Exchange."/>
+
+</manifest>
diff --git a/exchange2/tests/src/com/android/exchange/CalendarSyncEnablerTest.java b/exchange2/tests/src/com/android/exchange/CalendarSyncEnablerTest.java
new file mode 100644
index 0000000..4198c08
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/CalendarSyncEnablerTest.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.CalendarContract;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.emailcommon.AccountManagerTypes;
+import com.android.emailcommon.Logging;
+import com.android.exchange.utility.ExchangeTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+@MediumTest
+public class CalendarSyncEnablerTest extends ExchangeTestCase {
+
+    protected static final String TEST_ACCOUNT_PREFIX = "__test";
+    protected static final String TEST_ACCOUNT_SUFFIX = "@android.com";
+
+    private HashMap<Account, Boolean> origCalendarSyncStates = new HashMap<Account, Boolean>();
+
+    // To make the rest of the code shorter thus more readable...
+    private static final String EAT = AccountManagerTypes.TYPE_EXCHANGE;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        // Delete any test accounts we might have created earlier
+        deleteTemporaryAccountManagerAccounts();
+
+        // Save the original calendar sync states.
+        for (Account account : AccountManager.get(getContext()).getAccounts()) {
+            origCalendarSyncStates.put(account,
+                    ContentResolver.getSyncAutomatically(account, CalendarContract.AUTHORITY));
+        }
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        // Delete any test accounts we might have created earlier
+        deleteTemporaryAccountManagerAccounts();
+
+        // Restore the original calendar sync states.
+        // Note we restore only for Exchange accounts.
+        // Other accounts should remain intact throughout the tests.  Plus we don't know if the
+        // Calendar.AUTHORITY is supported by other types of accounts.
+        for (Account account : getExchangeAccounts()) {
+            Boolean state = origCalendarSyncStates.get(account);
+            if (state == null) continue; // Shouldn't happen, but just in case.
+
+            ContentResolver.setSyncAutomatically(account, CalendarContract.AUTHORITY, state);
+        }
+    }
+
+    public void testEnableEasCalendarSync() {
+        final Account[] baseAccounts = getExchangeAccounts();
+
+        String a1 = getTestAccountEmailAddress("1");
+        String a2 = getTestAccountEmailAddress("2");
+
+        // 1. Test with 1 account
+
+        CalendarSyncEnabler enabler = new CalendarSyncEnabler(getContext());
+
+        // Add exchange accounts
+        createAccountManagerAccount(a1);
+
+        String emailAddresses = enabler.enableEasCalendarSyncInternalForTest();
+
+        // Verify
+        verifyCalendarSyncState();
+
+        // There seems to be no good way to examine the contents of Notification, so let's verify
+        // we at least (tried to) show the correct email addresses.
+        checkNotificationEmailAddresses(emailAddresses, baseAccounts, a1);
+
+        // Delete added account.
+        deleteTemporaryAccountManagerAccounts();
+
+        // 2. Test with 2 accounts
+        enabler = new CalendarSyncEnabler(getContext());
+
+        // Add exchange accounts
+        createAccountManagerAccount(a1);
+        createAccountManagerAccount(a2);
+
+        emailAddresses = enabler.enableEasCalendarSyncInternalForTest();
+
+        // Verify
+        verifyCalendarSyncState();
+
+        // Check
+        checkNotificationEmailAddresses(emailAddresses, baseAccounts, a1, a2);
+    }
+
+    private static void checkNotificationEmailAddresses(String actual, Account[] baseAccounts,
+            String... addedAddresses) {
+        // Build and sort actual string array.
+        final String[] actualArray = TextUtils.split(actual, " ");
+        Arrays.sort(actualArray);
+
+        // Build and sort expected string array.
+        ArrayList<String> expected = new ArrayList<String>();
+        for (Account account : baseAccounts) {
+            expected.add(account.name);
+        }
+        for (String address : addedAddresses) {
+            expected.add(address);
+        }
+        final String[] expectedArray = new String[expected.size()];
+        expected.toArray(expectedArray);
+        Arrays.sort(expectedArray);
+
+        // Check!
+        MoreAsserts.assertEquals(expectedArray, actualArray);
+    }
+
+    /**
+     * For all {@link Account}, confirm that:
+     * <ol>
+     *   <li>Calendar sync is enabled if it's an Exchange account.<br>
+     *       Unfortunately setSyncAutomatically() doesn't take effect immediately, so we skip this
+     *       check for now.
+             TODO Find a stable way to check this.
+     *   <li>Otherwise, calendar sync state isn't changed.
+     * </ol>
+     */
+    private void verifyCalendarSyncState() {
+        // It's very unfortunate that setSyncAutomatically doesn't take effect immediately.
+        for (Account account : AccountManager.get(getContext()).getAccounts()) {
+            String message = "account=" + account.name + "(" + account.type + ")";
+            boolean enabled = ContentResolver.getSyncAutomatically(account,
+                    CalendarContract.AUTHORITY);
+            int syncable = ContentResolver.getIsSyncable(account, CalendarContract.AUTHORITY);
+
+            if (EAT.equals(account.type)) {
+                // Should be enabled.
+                // assertEquals(message, Boolean.TRUE, (Boolean) enabled);
+                // assertEquals(message, 1, syncable);
+            } else {
+                // Shouldn't change.
+                assertEquals(message, origCalendarSyncStates.get(account), (Boolean) enabled);
+            }
+        }
+    }
+
+    public void testEnableEasCalendarSyncWithNoExchangeAccounts() {
+        // This test can only meaningfully run when there's no exchange accounts
+        // set up on the device.  Otherwise there'll be no difference from
+        // testEnableEasCalendarSync.
+        if (AccountManager.get(getContext()).getAccountsByType(EAT).length > 0) {
+            Log.w(Logging.LOG_TAG, "testEnableEasCalendarSyncWithNoExchangeAccounts skipped:"
+                    + " It only runs when there's no Exchange account on the device.");
+            return;
+        }
+        CalendarSyncEnabler enabler = new CalendarSyncEnabler(getContext());
+        String emailAddresses = enabler.enableEasCalendarSyncInternalForTest();
+
+        // Verify (nothing should change)
+        verifyCalendarSyncState();
+
+        // No exchange accounts found.
+        assertEquals(0, emailAddresses.length());
+    }
+
+    public void testShowNotification() {
+        CalendarSyncEnabler enabler = new CalendarSyncEnabler(getContext());
+
+        // We can't really check the result, but at least we can make sure it won't crash....
+        enabler.showNotificationForTest("a@b.com");
+
+        // Remove the notification.  Comment it out when you want to know how it looks like.
+        // TODO If NotificationController supports this notification, we can just mock it out
+        // and remove this code.
+        ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE))
+                .cancel(CalendarSyncEnabler.NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED);
+    }
+
+    protected Account[] getExchangeAccounts() {
+        return AccountManager.get(getContext()).getAccountsByType(
+                AccountManagerTypes.TYPE_EXCHANGE);
+    }
+
+    protected Account makeAccountManagerAccount(String username) {
+        return new Account(username, AccountManagerTypes.TYPE_EXCHANGE);
+    }
+
+    protected void createAccountManagerAccount(String username) {
+        final Account account = makeAccountManagerAccount(username);
+        AccountManager.get(getContext()).addAccountExplicitly(account, "password", null);
+    }
+
+    protected com.android.emailcommon.provider.Account
+        setupProviderAndAccountManagerAccount(String username) {
+        // Note that setupAccount creates the email address username@android.com, so that's what
+        // we need to use for the account manager
+        createAccountManagerAccount(username + TEST_ACCOUNT_SUFFIX);
+        return setupTestAccount(username, true);
+    }
+
+    protected ArrayList<com.android.emailcommon.provider.Account> makeExchangeServiceAccountList() {
+        ArrayList<com.android.emailcommon.provider.Account> accountList =
+            new ArrayList<com.android.emailcommon.provider.Account>();
+        Cursor c = mProviderContext.getContentResolver().query(
+                com.android.emailcommon.provider.Account.CONTENT_URI,
+                com.android.emailcommon.provider.Account.CONTENT_PROJECTION, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                com.android.emailcommon.provider.Account account =
+                    new com.android.emailcommon.provider.Account();
+                account.restore(c);
+                accountList.add(account);
+            }
+        } finally {
+            c.close();
+        }
+        return accountList;
+    }
+
+    protected void deleteAccountManagerAccount(Account account) {
+        AccountManagerFuture<Boolean> future =
+            AccountManager.get(getContext()).removeAccount(account, null, null);
+        try {
+            future.getResult();
+        } catch (OperationCanceledException e) {
+        } catch (AuthenticatorException e) {
+        } catch (IOException e) {
+        }
+    }
+
+    protected void deleteTemporaryAccountManagerAccounts() {
+        for (Account accountManagerAccount: getExchangeAccounts()) {
+            if (accountManagerAccount.name.startsWith(TEST_ACCOUNT_PREFIX) &&
+                    accountManagerAccount.name.endsWith(TEST_ACCOUNT_SUFFIX)) {
+                deleteAccountManagerAccount(accountManagerAccount);
+            }
+        }
+    }
+
+    protected String getTestAccountName(String name) {
+        return TEST_ACCOUNT_PREFIX + name;
+    }
+
+    protected String getTestAccountEmailAddress(String name) {
+        return TEST_ACCOUNT_PREFIX + name + TEST_ACCOUNT_SUFFIX;
+    }
+
+
+    /**
+     * Helper to retrieve account manager accounts *and* remove any preexisting accounts
+     * from the list, to "hide" them from the reconciler.
+     */
+    protected Account[] getAccountManagerAccounts(Account[] baseline) {
+        Account[] rawList = getExchangeAccounts();
+        if (baseline.length == 0) {
+            return rawList;
+        }
+        HashSet<Account> set = new HashSet<Account>();
+        for (Account addAccount : rawList) {
+            set.add(addAccount);
+        }
+        for (Account removeAccount : baseline) {
+            set.remove(removeAccount);
+        }
+        return set.toArray(new Account[0]);
+    }
+}
diff --git a/tests/src/com/android/exchange/EasAccountServiceTests.java b/exchange2/tests/src/com/android/exchange/EasAccountServiceTests.java
similarity index 100%
rename from tests/src/com/android/exchange/EasAccountServiceTests.java
rename to exchange2/tests/src/com/android/exchange/EasAccountServiceTests.java
diff --git a/exchange2/tests/src/com/android/exchange/EasOutboxServiceTests.java b/exchange2/tests/src/com/android/exchange/EasOutboxServiceTests.java
new file mode 100644
index 0000000..da995d1
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/EasOutboxServiceTests.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.EasOutboxService.OriginalMessageInfo;
+import com.android.exchange.utility.ExchangeTestCase;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.EasOutboxServiceTests exchange
+ */
+@MediumTest
+public class EasOutboxServiceTests extends ExchangeTestCase {
+
+    public void testGenerateSmartSendCmd() {
+        EasOutboxService svc = new EasOutboxService(mProviderContext, new Mailbox());
+        // Test encoding of collection id; colon should be preserved
+        OriginalMessageInfo info = new OriginalMessageInfo("1339085683659694034", "Mail:^f", null);
+        String cmd = svc.generateSmartSendCmd(true, info);
+        assertEquals("SmartReply&ItemId=1339085683659694034&CollectionId=Mail:%5Ef", cmd);
+        // Test encoding of item id
+        info = new OriginalMessageInfo("14:&3", "6", null);
+        cmd = svc.generateSmartSendCmd(false, info);
+        assertEquals("SmartForward&ItemId=14:%263&CollectionId=6", cmd);
+        // Test use of long id
+        info = new OriginalMessageInfo("1339085683659694034", "Mail:^f", "3232323AAA");
+        cmd = svc.generateSmartSendCmd(false, info);
+        assertEquals("SmartForward&LongId=3232323AAA", cmd);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/EasSyncServiceTests.java b/exchange2/tests/src/com/android/exchange/EasSyncServiceTests.java
new file mode 100644
index 0000000..150b1f1
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/EasSyncServiceTests.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Base64;
+
+import com.android.emailcommon.provider.Account;
+
+import org.apache.http.Header;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+
+import java.io.IOException;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.EasSyncServiceTests exchange
+ */
+@SmallTest
+public class EasSyncServiceTests extends AndroidTestCase {
+    static private final String USER = "user";
+    static private final String PASSWORD = "password";
+    static private final String HOST = "xxx.host.zzz";
+    static private final String ID = "id";
+
+    Context mMockContext;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mMockContext = getContext();
+    }
+
+    public void testAddHeaders() {
+        HttpRequestBase method = new HttpPost();
+        EasSyncService svc = new EasSyncService();
+        svc.mAuthString = "auth";
+        svc.mProtocolVersion = "12.1";
+        svc.mAccount = null;
+        // With second argument false, there should be no header
+        svc.setHeaders(method, false);
+        Header[] headers = method.getHeaders("X-MS-PolicyKey");
+        assertEquals(0, headers.length);
+        // With second argument true, there should always be a header
+        // The value will be "0" without an account
+        method.removeHeaders("X-MS-PolicyKey");
+        svc.setHeaders(method, true);
+        headers = method.getHeaders("X-MS-PolicyKey");
+        assertEquals(1, headers.length);
+        assertEquals("0", headers[0].getValue());
+        // With an account, but null security key, the header's value should be "0"
+        Account account = new Account();
+        account.mSecuritySyncKey = null;
+        svc.mAccount = account;
+        method.removeHeaders("X-MS-PolicyKey");
+        svc.setHeaders(method, true);
+        headers = method.getHeaders("X-MS-PolicyKey");
+        assertEquals(1, headers.length);
+        assertEquals("0", headers[0].getValue());
+        // With an account and security key, the header's value should be the security key
+        account.mSecuritySyncKey = "key";
+        svc.mAccount = account;
+        method.removeHeaders("X-MS-PolicyKey");
+        svc.setHeaders(method, true);
+        headers = method.getHeaders("X-MS-PolicyKey");
+        assertEquals(1, headers.length);
+        assertEquals("key", headers[0].getValue());
+    }
+
+    public void testGetProtocolVersionDouble() {
+        assertEquals(Eas.SUPPORTED_PROTOCOL_EX2003_DOUBLE,
+                Eas.getProtocolVersionDouble(Eas.SUPPORTED_PROTOCOL_EX2003));
+        assertEquals(Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE,
+                Eas.getProtocolVersionDouble(Eas.SUPPORTED_PROTOCOL_EX2007));
+        assertEquals(Eas.SUPPORTED_PROTOCOL_EX2007_SP1_DOUBLE,
+                Eas.getProtocolVersionDouble(Eas.SUPPORTED_PROTOCOL_EX2007_SP1));
+    }
+
+    private EasSyncService setupService(String user) {
+        EasSyncService svc = new EasSyncService();
+        svc.mUserName = user;
+        svc.mPassword = PASSWORD;
+        svc.mDeviceId = ID;
+        svc.mHostAddress = HOST;
+        return svc;
+    }
+
+    public void testMakeUriString() throws IOException {
+        // Simple user name and command
+        EasSyncService svc = setupService(USER);
+        String uriString = svc.makeUriString("Sync", null);
+        // These next two should now be cached
+        assertNotNull(svc.mAuthString);
+        assertNotNull(svc.mUserString);
+        assertEquals("Basic " + Base64.encodeToString((USER+":"+PASSWORD).getBytes(),
+                Base64.NO_WRAP), svc.mAuthString);
+        assertEquals("&User=" + USER + "&DeviceId=" + ID + "&DeviceType=" +
+                EasSyncService.DEVICE_TYPE, svc.mUserString);
+        assertEquals("https://" + HOST + "/Microsoft-Server-ActiveSync?Cmd=Sync" +
+                svc.mUserString, uriString);
+        // User name that requires encoding
+        String user = "name_with_underscore@foo%bar.com";
+        svc = setupService(user);
+        uriString = svc.makeUriString("Sync", null);
+        assertEquals("Basic " + Base64.encodeToString((user+":"+PASSWORD).getBytes(),
+                Base64.NO_WRAP), svc.mAuthString);
+        String safeUserName = "name_with_underscore%40foo%25bar.com";
+        assertEquals("&User=" + safeUserName + "&DeviceId=" + ID + "&DeviceType=" +
+                EasSyncService.DEVICE_TYPE, svc.mUserString);
+        assertEquals("https://" + HOST + "/Microsoft-Server-ActiveSync?Cmd=Sync" +
+                svc.mUserString, uriString);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/ExchangeServiceAccountTests.java b/exchange2/tests/src/com/android/exchange/ExchangeServiceAccountTests.java
new file mode 100644
index 0000000..6b30b1d
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/ExchangeServiceAccountTests.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009 Marc Blank
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.ExchangeService.SyncError;
+import com.android.exchange.provider.EmailContentSetupUtils;
+import com.android.exchange.utility.ExchangeTestCase;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.ExchangeServiceAccountTests exchange
+ */
+@MediumTest
+public class ExchangeServiceAccountTests extends ExchangeTestCase {
+
+    public ExchangeServiceAccountTests() {
+        super();
+    }
+
+    public void testReleaseSyncHolds() {
+        ExchangeService exchangeService = new ExchangeService();
+        SyncError securityErrorAccount1 =
+            exchangeService.new SyncError(AbstractSyncService.EXIT_SECURITY_FAILURE, false);
+        SyncError ioError =
+            exchangeService.new SyncError(AbstractSyncService.EXIT_IO_ERROR, false);
+        SyncError securityErrorAccount2 =
+            exchangeService.new SyncError(AbstractSyncService.EXIT_SECURITY_FAILURE, false);
+        // Create account and two mailboxes
+        Account acct1 = setupTestAccount("acct1", true);
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox("box1", acct1.mId, true,
+                mProviderContext);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox("box2", acct1.mId, true,
+                mProviderContext);
+        Account acct2 = setupTestAccount("acct2", true);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox("box3", acct2.mId, true,
+                mProviderContext);
+        Mailbox box4 = EmailContentSetupUtils.setupMailbox("box4", acct2.mId, true,
+                mProviderContext);
+
+        ConcurrentHashMap<Long, SyncError> errorMap = exchangeService.mSyncErrorMap;
+        // Add errors into the map
+        errorMap.put(box1.mId, securityErrorAccount1);
+        errorMap.put(box2.mId, ioError);
+        errorMap.put(box3.mId, securityErrorAccount2);
+        errorMap.put(box4.mId, securityErrorAccount2);
+        // We should have 4
+        assertEquals(4, errorMap.keySet().size());
+        // Release the holds on acct2 (there are two of them)
+        assertTrue(exchangeService.releaseSyncHolds(mProviderContext,
+                AbstractSyncService.EXIT_SECURITY_FAILURE, acct2));
+        // There should be two left
+        assertEquals(2, errorMap.keySet().size());
+        // And these are the two...
+        assertNotNull(errorMap.get(box2.mId));
+        assertNotNull(errorMap.get(box1.mId));
+
+        // Put the two back
+        errorMap.put(box3.mId, securityErrorAccount2);
+        errorMap.put(box4.mId, securityErrorAccount2);
+        // We should have 4 again
+        assertEquals(4, errorMap.keySet().size());
+        // Release all of the security holds
+        assertTrue(exchangeService.releaseSyncHolds(mProviderContext,
+                AbstractSyncService.EXIT_SECURITY_FAILURE, null));
+        // There should be one left
+        assertEquals(1, errorMap.keySet().size());
+        // And this is the one
+        assertNotNull(errorMap.get(box2.mId));
+
+        // Release the i/o holds on account 2 (there aren't any)
+        assertFalse(exchangeService.releaseSyncHolds(mProviderContext,
+                AbstractSyncService.EXIT_IO_ERROR, acct2));
+        // There should still be one left
+        assertEquals(1, errorMap.keySet().size());
+
+        // Release the i/o holds on account 1 (there's one)
+        assertTrue(exchangeService.releaseSyncHolds(mProviderContext,
+                AbstractSyncService.EXIT_IO_ERROR, acct1));
+        // There should still be one left
+        assertEquals(0, errorMap.keySet().size());
+    }
+
+    public void testIsSyncable() {
+        Account acct1 = setupTestAccount("acct1", true);
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox("box1", acct1.mId, true,
+                mProviderContext, Mailbox.TYPE_DRAFTS);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox("box2", acct1.mId, true,
+                mProviderContext, Mailbox.TYPE_OUTBOX);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox("box2", acct1.mId, true,
+                mProviderContext, Mailbox.TYPE_ATTACHMENT);
+        Mailbox box4 = EmailContentSetupUtils.setupMailbox("box2", acct1.mId, true,
+                mProviderContext, Mailbox.TYPE_NOT_SYNCABLE + 64);
+        Mailbox box5 = EmailContentSetupUtils.setupMailbox("box2", acct1.mId, true,
+                mProviderContext, Mailbox.TYPE_MAIL);
+        assertFalse(ExchangeService.isSyncable(box1));
+        assertFalse(ExchangeService.isSyncable(box2));
+        assertFalse(ExchangeService.isSyncable(box3));
+        assertFalse(ExchangeService.isSyncable(box4));
+        assertTrue(ExchangeService.isSyncable(box5));
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/ExchangeServiceTest.java b/exchange2/tests/src/com/android/exchange/ExchangeServiceTest.java
new file mode 100644
index 0000000..b4be23f
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/ExchangeServiceTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.File;
+@SmallTest
+public class ExchangeServiceTest extends AndroidTestCase {
+    private static class MyContext extends ContextWrapper {
+        public boolean isGetFileStreamPathCalled;
+
+        public MyContext(Context base) {
+            super(base);
+        }
+
+        @Override
+        public File getFileStreamPath(String name) {
+            isGetFileStreamPathCalled = true;
+            return super.getFileStreamPath(name);
+        }
+    }
+
+    public void testGetDeviceId() throws Exception {
+        final MyContext context = new MyContext(getContext());
+
+        final String id = ExchangeService.getDeviceId(context);
+
+        // Consists of alpha-numeric
+        assertTrue(id.matches("^[a-zA-Z0-9]+$"));
+
+        // getDeviceId may have been called in other tests, so we don't check
+        // isGetFileStreamPathCalled here.
+
+        context.isGetFileStreamPathCalled = false;
+        final String cachedId = ExchangeService.getDeviceId(context);
+
+        // Should be the same.
+        assertEquals(id, cachedId);
+        // Should be cached.  (If cached, this method won't be called.)
+        assertFalse(context.isGetFileStreamPathCalled);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/RequestTests.java b/exchange2/tests/src/com/android/exchange/RequestTests.java
new file mode 100644
index 0000000..d736404
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/RequestTests.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import com.android.emailcommon.provider.EmailContent.Attachment;
+
+import android.test.AndroidTestCase;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.RequestTests exchange
+ */
+public class RequestTests extends AndroidTestCase {
+
+    public void testPartRequestEquals() {
+        Attachment att1 = new Attachment();
+        att1.mId = 1;
+        Attachment att2 = new Attachment();
+        att2.mId = 2;
+        // For part requests, the attachment id's must be ==
+        PartRequest req1 = new PartRequest(att1, "dest1", "content1");
+        PartRequest req2 = new PartRequest(att2, "dest2", "content2");
+        assertFalse(req1.equals(req2));
+        Attachment att3 = new Attachment();
+        att3.mId = 1;
+        PartRequest req3 = new PartRequest(att3, "dest3", "content3");
+        assertTrue(req1.equals(req3));
+        MessageMoveRequest req4 = new MessageMoveRequest(10L, 12L);
+        assertFalse(req1.equals(req4));
+    }
+
+    public void testRequestEquals() {
+        // Only the messageId needs to be ==
+        MessageMoveRequest req1 = new MessageMoveRequest(1L, 10L);
+        MessageMoveRequest req2 = new MessageMoveRequest(1L, 11L);
+        assertTrue(req1.equals(req2));
+        MessageMoveRequest req3 = new MessageMoveRequest(2L, 11L);
+        assertFalse(req3.equals(req2));
+        MeetingResponseRequest req4 = new MeetingResponseRequest(1L, 3);
+        assertFalse(req4.equals(req1));
+        MeetingResponseRequest req5 = new MeetingResponseRequest(1L, 4);
+        assertTrue(req5.equals(req4));
+    }
+}
\ No newline at end of file
diff --git a/exchange2/tests/src/com/android/exchange/TagsTests.java b/exchange2/tests/src/com/android/exchange/TagsTests.java
new file mode 100644
index 0000000..55b27c0
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/TagsTests.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.exchange;
+
+import com.android.exchange.adapter.Tags;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.HashMap;
+@SmallTest
+public class TagsTests extends AndroidTestCase {
+
+    // Make sure there are no duplicates in the tags table
+    // This test is no longer required - tags can be duplicated
+    public void disable_testNoDuplicates() {
+        String[][] allTags = Tags.pages;
+        HashMap<String, Boolean> map = new HashMap<String, Boolean>();
+        for (String[] page: allTags) {
+            for (String tag: page) {
+                assertTrue(tag, !map.containsKey(tag));
+                map.put(tag, true);
+            }
+        }
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/AttachmentLoaderTests.java b/exchange2/tests/src/com/android/exchange/adapter/AttachmentLoaderTests.java
new file mode 100644
index 0000000..2e16ac8
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/AttachmentLoaderTests.java
@@ -0,0 +1,40 @@
+/* Copyright (C) 2011 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.adapter.AttachmentLoaderTests exchange
+ */
+package com.android.exchange.adapter;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class AttachmentLoaderTests extends AndroidTestCase {
+    private static final String TEST_LOCATION =
+        "Inbox/FW:%204G%20Netbook%20|%20Now%20Available%20for%20Order.EML/image012.jpg";
+
+    public void testEncodeForExchange2003() {
+        assertEquals("abc", AttachmentLoader.encodeForExchange2003("abc"));
+        // We don't encode the four characters after abc
+        assertEquals("abc_:/.", AttachmentLoader.encodeForExchange2003("abc_:/."));
+        // We don't re-encode escaped characters
+        assertEquals("%20%33", AttachmentLoader.encodeForExchange2003("%20%33"));
+        // Test with the location that failed in use
+        assertEquals(TEST_LOCATION.replace("|", "%7C"),
+                AttachmentLoader.encodeForExchange2003(TEST_LOCATION));
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/CalendarSyncAdapterTests.java b/exchange2/tests/src/com/android/exchange/adapter/CalendarSyncAdapterTests.java
new file mode 100644
index 0000000..2e2f553
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/CalendarSyncAdapterTests.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import com.android.exchange.adapter.AbstractSyncAdapter.Operation;
+import com.android.exchange.adapter.CalendarSyncAdapter.CalendarOperations;
+import com.android.exchange.adapter.CalendarSyncAdapter.EasCalendarSyncParser;
+import com.android.exchange.provider.MockProvider;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.os.RemoteException;
+import android.provider.CalendarContract.Attendees;
+import android.provider.CalendarContract.Events;
+import android.test.IsolatedContext;
+import android.test.RenamingDelegatingContext;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.adapter.CalendarSyncAdapterTests exchange
+ */
+@MediumTest
+public class CalendarSyncAdapterTests extends SyncAdapterTestCase<CalendarSyncAdapter> {
+    private static final String[] ATTENDEE_PROJECTION = new String[] {Attendees.ATTENDEE_EMAIL,
+            Attendees.ATTENDEE_NAME, Attendees.ATTENDEE_STATUS};
+    private static final int ATTENDEE_EMAIL = 0;
+    private static final int ATTENDEE_NAME = 1;
+    private static final int ATTENDEE_STATUS = 2;
+
+    private static final String SINGLE_ATTENDEE_EMAIL = "attendee@host.com";
+    private static final String SINGLE_ATTENDEE_NAME = "Bill Attendee";
+
+    private Context mMockContext;
+    private MockContentResolver mMockResolver;
+
+    // This is the US/Pacific time zone as a base64-encoded TIME_ZONE_INFORMATION structure, as
+    // it would appear coming from an Exchange server
+    private static final String TEST_TIME_ZONE = "4AEAAFAAYQBjAGkAZgBpAGMAIABTAHQAYQBuAGQAYQByA" +
+        "GQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAABAAIAAAAAAAAAAAAAAFAAY" +
+        "QBjAGkAZgBpAGMAIABEAGEAeQBsAGkAZwBoAHQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAMAAAACAAIAAAAAAAAAxP///w==";
+
+    private class MockContext2 extends MockContext {
+
+        @Override
+        public Resources getResources() {
+            return getContext().getResources();
+        }
+
+        @Override
+        public File getDir(String name, int mode) {
+            // name the directory so the directory will be separated from
+            // one created through the regular Context
+            return getContext().getDir("mockcontext2_" + name, mode);
+        }
+
+        @Override
+        public Context getApplicationContext() {
+            return this;
+        }
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mMockResolver = new MockContentResolver();
+        final String filenamePrefix = "test.";
+        RenamingDelegatingContext targetContextWrapper = new
+        RenamingDelegatingContext(
+                new MockContext2(), // The context that most methods are delegated to
+                getContext(), // The context that file methods are delegated to
+                filenamePrefix);
+        mMockContext = new IsolatedContext(mMockResolver, targetContextWrapper);
+        mMockResolver.addProvider(MockProvider.AUTHORITY, new MockProvider(mMockContext));
+    }
+
+    public CalendarSyncAdapterTests() {
+        super();
+    }
+
+    public void testSetTimeRelatedValues_NonRecurring() throws IOException {
+        CalendarSyncAdapter adapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+        EasCalendarSyncParser p = adapter.new EasCalendarSyncParser(getTestInputStream(), adapter);
+        ContentValues cv = new ContentValues();
+        // Basic, one-time meeting lasting an hour
+        GregorianCalendar startCalendar = new GregorianCalendar(2010, 5, 10, 8, 30);
+        Long startTime = startCalendar.getTimeInMillis();
+        GregorianCalendar endCalendar = new GregorianCalendar(2010, 5, 10, 9, 30);
+        Long endTime = endCalendar.getTimeInMillis();
+
+        p.setTimeRelatedValues(cv, startTime, endTime, 0);
+        assertNull(cv.getAsInteger(Events.DURATION));
+        assertEquals(startTime, cv.getAsLong(Events.DTSTART));
+        assertEquals(endTime, cv.getAsLong(Events.DTEND));
+        assertEquals(endTime, cv.getAsLong(Events.LAST_DATE));
+        assertNull(cv.getAsString(Events.EVENT_TIMEZONE));
+    }
+
+    public void testSetTimeRelatedValues_Recurring() throws IOException {
+        CalendarSyncAdapter adapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+        EasCalendarSyncParser p = adapter.new EasCalendarSyncParser(getTestInputStream(), adapter);
+        ContentValues cv = new ContentValues();
+        // Recurring meeting lasting an hour
+        GregorianCalendar startCalendar = new GregorianCalendar(2010, 5, 10, 8, 30);
+        Long startTime = startCalendar.getTimeInMillis();
+        GregorianCalendar endCalendar = new GregorianCalendar(2010, 5, 10, 9, 30);
+        Long endTime = endCalendar.getTimeInMillis();
+        cv.put(Events.RRULE, "FREQ=DAILY");
+        p.setTimeRelatedValues(cv, startTime, endTime, 0);
+        assertEquals("P60M", cv.getAsString(Events.DURATION));
+        assertEquals(startTime, cv.getAsLong(Events.DTSTART));
+        assertNull(cv.getAsLong(Events.DTEND));
+        assertNull(cv.getAsLong(Events.LAST_DATE));
+        assertNull(cv.getAsString(Events.EVENT_TIMEZONE));
+    }
+
+    public void testSetTimeRelatedValues_AllDay() throws IOException {
+        CalendarSyncAdapter adapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+        EasCalendarSyncParser p = adapter.new EasCalendarSyncParser(getTestInputStream(), adapter);
+        ContentValues cv = new ContentValues();
+        GregorianCalendar startCalendar = new GregorianCalendar(2010, 5, 10, 8, 30);
+        Long startTime = startCalendar.getTimeInMillis();
+        GregorianCalendar endCalendar = new GregorianCalendar(2010, 5, 11, 8, 30);
+        Long endTime = endCalendar.getTimeInMillis();
+        cv.put(Events.RRULE, "FREQ=WEEKLY;BYDAY=MO");
+        p.setTimeRelatedValues(cv, startTime, endTime, 1);
+
+        // The start time should have hour/min/sec zero'd out
+        startCalendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+        startCalendar.set(2010, 5, 10, 0, 0, 0);
+        startCalendar.set(GregorianCalendar.MILLISECOND, 0);
+        startTime = startCalendar.getTimeInMillis();
+        assertEquals(startTime, cv.getAsLong(Events.DTSTART));
+
+        // The duration should be in days
+        assertEquals("P1D", cv.getAsString(Events.DURATION));
+        assertNull(cv.getAsLong(Events.DTEND));
+        assertNull(cv.getAsLong(Events.LAST_DATE));
+        // There must be a timezone
+        assertNotNull(cv.getAsString(Events.EVENT_TIMEZONE));
+    }
+
+    public void testSetTimeRelatedValues_Recurring_AllDay_Exception () throws IOException {
+        CalendarSyncAdapter adapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+        EasCalendarSyncParser p = adapter.new EasCalendarSyncParser(getTestInputStream(), adapter);
+        ContentValues cv = new ContentValues();
+
+        // Recurrence exception for all-day event; the exception is NOT all-day
+        GregorianCalendar startCalendar = new GregorianCalendar(2010, 5, 17, 8, 30);
+        Long startTime = startCalendar.getTimeInMillis();
+        GregorianCalendar endCalendar = new GregorianCalendar(2010, 5, 17, 9, 30);
+        Long endTime = endCalendar.getTimeInMillis();
+        cv.put(Events.ORIGINAL_ALL_DAY, 1);
+        GregorianCalendar instanceCalendar = new GregorianCalendar(2010, 5, 17, 8, 30);
+        cv.put(Events.ORIGINAL_INSTANCE_TIME, instanceCalendar.getTimeInMillis());
+        p.setTimeRelatedValues(cv, startTime, endTime, 0);
+
+        // The original instance time should have hour/min/sec zero'd out
+        GregorianCalendar testCalendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+        testCalendar.set(2010, 5, 17, 0, 0, 0);
+        testCalendar.set(GregorianCalendar.MILLISECOND, 0);
+        Long testTime = testCalendar.getTimeInMillis();
+        assertEquals(testTime, cv.getAsLong(Events.ORIGINAL_INSTANCE_TIME));
+
+        // The exception isn't all-day, so we should have DTEND and LAST_DATE and no EVENT_TIMEZONE
+        assertNull(cv.getAsString(Events.DURATION));
+        assertEquals(endTime, cv.getAsLong(Events.DTEND));
+        assertEquals(endTime, cv.getAsLong(Events.LAST_DATE));
+        assertNull(cv.getAsString(Events.EVENT_TIMEZONE));
+    }
+
+    public void testIsValidEventValues() throws IOException {
+        CalendarSyncAdapter adapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+        EasCalendarSyncParser p = adapter.new EasCalendarSyncParser(getTestInputStream(), adapter);
+
+        long validTime = System.currentTimeMillis();
+        String validData = "foo-bar-bletch";
+        String validDuration = "P30M";
+        String validRrule = "FREQ=DAILY";
+
+        ContentValues cv = new ContentValues();
+
+        cv.put(Events.DTSTART, validTime);
+        // Needs _SYNC_DATA and DTEND/DURATION
+        assertFalse(p.isValidEventValues(cv));
+        cv.put(Events.SYNC_DATA2, validData);
+        // Needs DTEND/DURATION since not an exception
+        assertFalse(p.isValidEventValues(cv));
+        cv.put(Events.DURATION, validDuration);
+        // Valid (DTSTART, _SYNC_DATA, DURATION)
+        assertTrue(p.isValidEventValues(cv));
+        cv.remove(Events.DURATION);
+        cv.put(Events.ORIGINAL_INSTANCE_TIME, validTime);
+        // Needs DTEND since it's an exception
+        assertFalse(p.isValidEventValues(cv));
+        cv.put(Events.DTEND, validTime);
+        // Valid (DTSTART, DTEND, ORIGINAL_INSTANCE_TIME)
+        cv.remove(Events.ORIGINAL_INSTANCE_TIME);
+        // Valid (DTSTART, _SYNC_DATA, DTEND)
+        assertTrue(p.isValidEventValues(cv));
+        cv.remove(Events.DTSTART);
+        // Needs DTSTART
+        assertFalse(p.isValidEventValues(cv));
+        cv.put(Events.DTSTART, validTime);
+        cv.put(Events.RRULE, validRrule);
+        // With RRULE, needs DURATION
+        assertFalse(p.isValidEventValues(cv));
+        cv.put(Events.DURATION, "P30M");
+        // Valid (DTSTART, RRULE, DURATION)
+        assertTrue(p.isValidEventValues(cv));
+        cv.put(Events.ALL_DAY, "1");
+        // Needs DURATION in the form P<n>D
+        assertFalse(p.isValidEventValues(cv));
+        // Valid (DTSTART, RRULE, ALL_DAY, DURATION(P<n>D)
+        cv.put(Events.DURATION, "P1D");
+        assertTrue(p.isValidEventValues(cv));
+    }
+
+    private void addAttendeesToSerializer(Serializer s, int num) throws IOException {
+        for (int i = 0; i < num; i++) {
+            s.start(Tags.CALENDAR_ATTENDEE);
+            s.data(Tags.CALENDAR_ATTENDEE_EMAIL, "frederick" + num +
+                    ".flintstone@this.that.verylongservername.com");
+            s.data(Tags.CALENDAR_ATTENDEE_TYPE, "1");
+            s.data(Tags.CALENDAR_ATTENDEE_NAME, "Frederick" + num + " Flintstone, III");
+            s.end();
+        }
+    }
+
+    private void addAttendeeToSerializer(Serializer s, String email, String name)
+            throws IOException {
+        s.start(Tags.CALENDAR_ATTENDEE);
+        s.data(Tags.CALENDAR_ATTENDEE_EMAIL, email);
+        s.data(Tags.CALENDAR_ATTENDEE_TYPE, "1");
+        s.data(Tags.CALENDAR_ATTENDEE_NAME, name);
+        s.end();
+    }
+
+    private int countInsertOperationsForTable(CalendarOperations ops, String tableName) {
+        int cnt = 0;
+        for (Operation op: ops) {
+            ContentProviderOperation cpo =
+                    AbstractSyncAdapter.operationToContentProviderOperation(op, 0);
+            List<String> segments = cpo.getUri().getPathSegments();
+            if (segments.get(0).equalsIgnoreCase(tableName) &&
+                    cpo.getType() == ContentProviderOperation.TYPE_INSERT) {
+                cnt++;
+            }
+        }
+        return cnt;
+    }
+
+    class TestEvent extends Serializer {
+        CalendarSyncAdapter mAdapter;
+        EasCalendarSyncParser mParser;
+        Serializer mSerializer;
+
+        TestEvent() throws IOException {
+            super(false);
+            mAdapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+            mParser = mAdapter.new EasCalendarSyncParser(getTestInputStream(), mAdapter);
+        }
+
+        void setUserEmailAddress(String addr) {
+            mAdapter.mAccount.mEmailAddress = addr;
+            mAdapter.mEmailAddress = addr;
+        }
+
+        EasCalendarSyncParser getParser() throws IOException {
+            // Set up our parser's input and eat the initial tag
+            mParser.resetInput(new ByteArrayInputStream(toByteArray()));
+            mParser.nextTag(0);
+            return mParser;
+        }
+
+        // setupPreAttendees and setupPostAttendees initialize calendar data in the order in which
+        // they would appear in an actual EAS session.  Between these two calls, we initialize
+        // attendee data, which varies between the following tests
+        TestEvent setupPreAttendees() throws IOException {
+            start(Tags.SYNC_APPLICATION_DATA);
+            data(Tags.CALENDAR_TIME_ZONE, TEST_TIME_ZONE);
+            data(Tags.CALENDAR_DTSTAMP, "20100518T213156Z");
+            data(Tags.CALENDAR_START_TIME, "20100518T220000Z");
+            data(Tags.CALENDAR_SUBJECT, "Documentation");
+            data(Tags.CALENDAR_UID, "4417556B-27DE-4ECE-B679-A63EFE1F9E85");
+            data(Tags.CALENDAR_ORGANIZER_NAME, "Fred Squatibuquitas");
+            data(Tags.CALENDAR_ORGANIZER_EMAIL, "fred.squatibuquitas@prettylongdomainname.com");
+            return this;
+        }
+
+        TestEvent setupPostAttendees()throws IOException {
+            data(Tags.CALENDAR_LOCATION, "CR SF 601T2/North Shore Presentation Self Service (16)");
+            data(Tags.CALENDAR_END_TIME, "20100518T223000Z");
+            start(Tags.BASE_BODY);
+            data(Tags.BASE_BODY_PREFERENCE, "1");
+            data(Tags.BASE_ESTIMATED_DATA_SIZE, "69105"); // The number is ignored by the parser
+            data(Tags.BASE_DATA,
+                    "This is the event description; we should probably make it longer");
+            end(); // BASE_BODY
+            start(Tags.CALENDAR_RECURRENCE);
+            data(Tags.CALENDAR_RECURRENCE_TYPE, "1"); // weekly
+            data(Tags.CALENDAR_RECURRENCE_INTERVAL, "1");
+            data(Tags.CALENDAR_RECURRENCE_OCCURRENCES, "10");
+            data(Tags.CALENDAR_RECURRENCE_DAYOFWEEK, "12"); // tue, wed
+            data(Tags.CALENDAR_RECURRENCE_UNTIL, "2005-04-14T00:00:00.000Z");
+            end();  // CALENDAR_RECURRENCE
+            data(Tags.CALENDAR_SENSITIVITY, "0");
+            data(Tags.CALENDAR_BUSY_STATUS, "2");
+            data(Tags.CALENDAR_ALL_DAY_EVENT, "0");
+            data(Tags.CALENDAR_MEETING_STATUS, "3");
+            data(Tags.BASE_NATIVE_BODY_TYPE, "3");
+            end().done(); // SYNC_APPLICATION_DATA
+            return this;
+        }
+    }
+
+    public void testAddEvent() throws IOException {
+        TestEvent event = new TestEvent();
+        event.setupPreAttendees();
+        event.start(Tags.CALENDAR_ATTENDEES);
+        addAttendeesToSerializer(event, 10);
+        event.end(); // CALENDAR_ATTENDEES
+        event.setupPostAttendees();
+
+        EasCalendarSyncParser p = event.getParser();
+        p.addEvent(p.mOps, "1:1", false);
+        // There should be 1 event
+        assertEquals(1, countInsertOperationsForTable(p.mOps, "events"));
+        // Two attendees (organizer and 10 attendees)
+        assertEquals(11, countInsertOperationsForTable(p.mOps, "attendees"));
+        // dtstamp, meeting status, attendees, attendees redacted, and upsync prohibited
+        assertEquals(5, countInsertOperationsForTable(p.mOps, "extendedproperties"));
+    }
+
+    public void testAddEventIllegal() throws IOException {
+        // We don't send a start time; the event is illegal and nothing should be added
+        TestEvent event = new TestEvent();
+        event.start(Tags.SYNC_APPLICATION_DATA);
+        event.data(Tags.CALENDAR_TIME_ZONE, TEST_TIME_ZONE);
+        event.data(Tags.CALENDAR_DTSTAMP, "20100518T213156Z");
+        event.data(Tags.CALENDAR_SUBJECT, "Documentation");
+        event.data(Tags.CALENDAR_UID, "4417556B-27DE-4ECE-B679-A63EFE1F9E85");
+        event.data(Tags.CALENDAR_ORGANIZER_NAME, "Fred Squatibuquitas");
+        event.data(Tags.CALENDAR_ORGANIZER_EMAIL, "fred.squatibuquitas@prettylongdomainname.com");
+        event.start(Tags.CALENDAR_ATTENDEES);
+        addAttendeesToSerializer(event, 10);
+        event.end(); // CALENDAR_ATTENDEES
+        event.setupPostAttendees();
+
+        EasCalendarSyncParser p = event.getParser();
+        p.addEvent(p.mOps, "1:1", false);
+        assertEquals(0, countInsertOperationsForTable(p.mOps, "events"));
+        assertEquals(0, countInsertOperationsForTable(p.mOps, "attendees"));
+        assertEquals(0, countInsertOperationsForTable(p.mOps, "extendedproperties"));
+    }
+
+    public void testAddEventRedactedAttendees() throws IOException {
+        TestEvent event = new TestEvent();
+        event.setupPreAttendees();
+        event.start(Tags.CALENDAR_ATTENDEES);
+        addAttendeesToSerializer(event, 100);
+        event.end(); // CALENDAR_ATTENDEES
+        event.setupPostAttendees();
+
+        EasCalendarSyncParser p = event.getParser();
+        p.addEvent(p.mOps, "1:1", false);
+        // There should be 1 event
+        assertEquals(1, countInsertOperationsForTable(p.mOps, "events"));
+        // One attendees (organizer; all others are redacted)
+        assertEquals(1, countInsertOperationsForTable(p.mOps, "attendees"));
+        // dtstamp, meeting status, and attendees redacted
+        assertEquals(3, countInsertOperationsForTable(p.mOps, "extendedproperties"));
+    }
+
+    /**
+     * Setup for the following three tests, which check attendee status of an added event
+     * @param userEmail the email address of the user
+     * @param update whether or not the event is an update (rather than new)
+     * @return a Cursor to the Attendee records added to our MockProvider
+     * @throws IOException
+     * @throws RemoteException
+     * @throws OperationApplicationException
+     */
+    private Cursor setupAddEventOneAttendee(String userEmail, boolean update)
+            throws IOException, RemoteException, OperationApplicationException {
+        TestEvent event = new TestEvent();
+        event.setupPreAttendees();
+        event.start(Tags.CALENDAR_ATTENDEES);
+        addAttendeeToSerializer(event, SINGLE_ATTENDEE_EMAIL, SINGLE_ATTENDEE_NAME);
+        event.setUserEmailAddress(userEmail);
+        event.end(); // CALENDAR_ATTENDEES
+        event.setupPostAttendees();
+
+        EasCalendarSyncParser p = event.getParser();
+        p.addEvent(p.mOps, "1:1", update);
+        // Send the CPO's to the mock provider
+        ArrayList<ContentProviderOperation> cpos = new ArrayList<ContentProviderOperation>();
+        for (Operation op: p.mOps) {
+            cpos.add(AbstractSyncAdapter.operationToContentProviderOperation(op, 0));
+        }
+        mMockResolver.applyBatch(MockProvider.AUTHORITY, cpos);
+        return mMockResolver.query(MockProvider.uri(Attendees.CONTENT_URI), ATTENDEE_PROJECTION,
+                null, null, null);
+    }
+
+    public void testAddEventOneAttendee() throws IOException, RemoteException,
+            OperationApplicationException {
+        Cursor c = setupAddEventOneAttendee("foo@bar.com", false);
+        assertEquals(2, c.getCount());
+        // The organizer should be "accepted", the unknown attendee "none"
+        while (c.moveToNext()) {
+            if (SINGLE_ATTENDEE_EMAIL.equals(c.getString(ATTENDEE_EMAIL))) {
+                assertEquals(Attendees.ATTENDEE_STATUS_NONE, c.getInt(ATTENDEE_STATUS));
+            } else {
+                assertEquals(Attendees.ATTENDEE_STATUS_ACCEPTED, c.getInt(ATTENDEE_STATUS));
+            }
+        }
+    }
+
+    public void testAddEventSelfAttendee() throws IOException, RemoteException,
+            OperationApplicationException {
+        Cursor c = setupAddEventOneAttendee(SINGLE_ATTENDEE_EMAIL, false);
+        // The organizer should be "accepted", and our user/attendee should be "done" even though
+        // the busy status = 2 (because we can't tell from a status of 2 on new events)
+        while (c.moveToNext()) {
+            if (SINGLE_ATTENDEE_EMAIL.equals(c.getString(ATTENDEE_EMAIL))) {
+                assertEquals(Attendees.ATTENDEE_STATUS_NONE, c.getInt(ATTENDEE_STATUS));
+            } else {
+                assertEquals(Attendees.ATTENDEE_STATUS_ACCEPTED, c.getInt(ATTENDEE_STATUS));
+            }
+        }
+    }
+
+    public void testAddEventSelfAttendeeUpdate() throws IOException, RemoteException,
+            OperationApplicationException {
+        Cursor c = setupAddEventOneAttendee(SINGLE_ATTENDEE_EMAIL, true);
+        // The organizer should be "accepted", and our user/attendee should be "accepted" (because
+        // busy status = 2 and this is an update
+        while (c.moveToNext()) {
+            if (SINGLE_ATTENDEE_EMAIL.equals(c.getString(ATTENDEE_EMAIL))) {
+                assertEquals(Attendees.ATTENDEE_STATUS_ACCEPTED, c.getInt(ATTENDEE_STATUS));
+            } else {
+                assertEquals(Attendees.ATTENDEE_STATUS_ACCEPTED, c.getInt(ATTENDEE_STATUS));
+            }
+        }
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java b/exchange2/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
new file mode 100644
index 0000000..1ee64fe
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.Body;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.EmailContent.MessageColumns;
+import com.android.emailcommon.provider.EmailContent.SyncColumns;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
+import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser.ServerChange;
+import com.android.exchange.provider.EmailContentSetupUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+@SmallTest
+public class EmailSyncAdapterTests extends SyncAdapterTestCase<EmailSyncAdapter> {
+
+    private static final String WHERE_ACCOUNT_KEY = Message.ACCOUNT_KEY + "=?";
+    private static final String[] ACCOUNT_ARGUMENT = new String[1];
+
+    // A server id that is guaranteed to be test-related
+    private static final String TEST_SERVER_ID = "__1:22";
+
+    public EmailSyncAdapterTests() {
+        super();
+    }
+
+    /**
+     * Check functionality for getting mime type from a file name (using its extension)
+     * The default for all unknown files is application/octet-stream
+     */
+    public void testGetMimeTypeFromFileName() throws IOException {
+        EasSyncService service = getTestService();
+        EmailSyncAdapter adapter = new EmailSyncAdapter(service);
+        EasEmailSyncParser p = adapter.new EasEmailSyncParser(getTestInputStream(), adapter);
+        // Test a few known types
+        String mimeType = p.getMimeTypeFromFileName("foo.jpg");
+        assertEquals("image/jpeg", mimeType);
+        // Make sure this is case insensitive
+        mimeType = p.getMimeTypeFromFileName("foo.JPG");
+        assertEquals("image/jpeg", mimeType);
+        mimeType = p.getMimeTypeFromFileName("this_is_a_weird_filename.gif");
+        assertEquals("image/gif", mimeType);
+        // Test an illegal file name ending with the extension prefix
+        mimeType = p.getMimeTypeFromFileName("foo.");
+        assertEquals("application/octet-stream", mimeType);
+        // Test a really awful name
+        mimeType = p.getMimeTypeFromFileName(".....");
+        assertEquals("application/octet-stream", mimeType);
+        // Test a bare file name (no extension)
+        mimeType = p.getMimeTypeFromFileName("foo");
+        assertEquals("application/octet-stream", mimeType);
+        // And no name at all (null isn't a valid input)
+        mimeType = p.getMimeTypeFromFileName("");
+        assertEquals("application/octet-stream", mimeType);
+    }
+
+    public void testFormatDateTime() throws IOException {
+        EmailSyncAdapter adapter = getTestSyncAdapter(EmailSyncAdapter.class);
+        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+        // Calendar is odd, months are zero based, so the first 11 below is December...
+        calendar.set(2008, 11, 11, 18, 19, 20);
+        String date = adapter.formatDateTime(calendar);
+        assertEquals("2008-12-11T18:19:20.000Z", date);
+        calendar.clear();
+        calendar.set(2012, 0, 2, 23, 0, 1);
+        date = adapter.formatDateTime(calendar);
+        assertEquals("2012-01-02T23:00:01.000Z", date);
+    }
+
+    public void testSendDeletedItems() throws IOException {
+        setupAccountMailboxAndMessages(0);
+        // Setup our adapter and parser
+        setupSyncParserAndAdapter(mAccount, mMailbox);
+
+        Serializer s = new Serializer();
+        ArrayList<Long> ids = new ArrayList<Long>();
+        ArrayList<Long> deletedIds = new ArrayList<Long>();
+
+        // Create account and two mailboxes
+        mSyncAdapter.mAccount = mAccount;
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox("box1", mAccount.mId, true,
+                mProviderContext);
+        mSyncAdapter.mMailbox = box1;
+
+        // Create 3 messages
+        Message msg1 = EmailContentSetupUtils.setupMessage("message1", mAccount.mId, box1.mId,
+                true, true, mProviderContext);
+        ids.add(msg1.mId);
+        Message msg2 = EmailContentSetupUtils.setupMessage("message2", mAccount.mId, box1.mId,
+                true, true, mProviderContext);
+        ids.add(msg2.mId);
+        Message msg3 = EmailContentSetupUtils.setupMessage("message3", mAccount.mId, box1.mId,
+                true, true, mProviderContext);
+        ids.add(msg3.mId);
+        assertEquals(3, EmailContent.count(mProviderContext, Message.CONTENT_URI, WHERE_ACCOUNT_KEY,
+                getAccountArgument(mAccount.mId)));
+
+        // Delete them
+        for (long id: ids) {
+            mResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id),
+                    null, null);
+        }
+
+        // Confirm that the messages are in the proper table
+        assertEquals(0, EmailContent.count(mProviderContext, Message.CONTENT_URI, WHERE_ACCOUNT_KEY,
+                getAccountArgument(mAccount.mId)));
+        assertEquals(3, EmailContent.count(mProviderContext, Message.DELETED_CONTENT_URI,
+                WHERE_ACCOUNT_KEY, getAccountArgument(mAccount.mId)));
+
+        // Call code to send deletions; the id's of the ones actually deleted will be in the
+        // deletedIds list
+        mSyncAdapter.sendDeletedItems(s, deletedIds, true);
+        assertEquals(3, deletedIds.size());
+
+        // Clear this out for the next test
+        deletedIds.clear();
+
+        // Create a new message
+        Message msg4 = EmailContentSetupUtils.setupMessage("message4", mAccount.mId, box1.mId,
+                true, true, mProviderContext);
+        assertEquals(1, EmailContent.count(mProviderContext, Message.CONTENT_URI, WHERE_ACCOUNT_KEY,
+                getAccountArgument(mAccount.mId)));
+        // Find the body for this message
+        Body body = Body.restoreBodyWithMessageId(mProviderContext, msg4.mId);
+        // Set its source message to msg2's id
+        ContentValues values = new ContentValues();
+        values.put(Body.SOURCE_MESSAGE_KEY, msg2.mId);
+        body.update(mProviderContext, values);
+
+        // Now send deletions again; this time only two should get deleted; msg2 should NOT be
+        // deleted as it's referenced by msg4
+        mSyncAdapter.sendDeletedItems(s, deletedIds, true);
+        assertEquals(2, deletedIds.size());
+        assertFalse(deletedIds.contains(msg2.mId));
+    }
+
+    private String[] getAccountArgument(long id) {
+        ACCOUNT_ARGUMENT[0] = Long.toString(id);
+        return ACCOUNT_ARGUMENT;
+    }
+
+    void setupSyncParserAndAdapter(Account account, Mailbox mailbox) throws IOException {
+        EasSyncService service = getTestService(account, mailbox);
+        mSyncAdapter = new EmailSyncAdapter(service);
+        mSyncParser = mSyncAdapter.new EasEmailSyncParser(getTestInputStream(), mSyncAdapter);
+    }
+
+    ArrayList<Long> setupAccountMailboxAndMessages(int numMessages) {
+        ArrayList<Long> ids = new ArrayList<Long>();
+
+        // Create account and two mailboxes
+        mAccount = EmailContentSetupUtils.setupAccount("account", true, mProviderContext);
+        mMailbox = EmailContentSetupUtils.setupMailbox("box1", mAccount.mId, true,
+                mProviderContext);
+
+        for (int i = 0; i < numMessages; i++) {
+            Message msg = EmailContentSetupUtils.setupMessage("message" + i, mAccount.mId,
+                    mMailbox.mId, true, true, mProviderContext);
+            ids.add(msg.mId);
+        }
+
+        assertEquals(numMessages, EmailContent.count(mProviderContext, Message.CONTENT_URI,
+                WHERE_ACCOUNT_KEY, getAccountArgument(mAccount.mId)));
+        return ids;
+    }
+
+    public void testDeleteParser() throws IOException {
+        // Setup some messages
+        ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
+        ContentValues cv = new ContentValues();
+        cv.put(SyncColumns.SERVER_ID, TEST_SERVER_ID);
+        long deleteMessageId = messageIds.get(1);
+        mResolver.update(ContentUris.withAppendedId(Message.CONTENT_URI, deleteMessageId), cv,
+                null, null);
+
+        // Setup our adapter and parser
+        setupSyncParserAndAdapter(mAccount, mMailbox);
+
+        // Set up an input stream with a delete command
+        Serializer s = new Serializer(false);
+        s.start(Tags.SYNC_DELETE).data(Tags.SYNC_SERVER_ID, TEST_SERVER_ID).end().done();
+        byte[] bytes = s.toByteArray();
+        mSyncParser.resetInput(new ByteArrayInputStream(bytes));
+        mSyncParser.nextTag(0);
+
+        // Run the delete parser
+        ArrayList<Long> deleteList = new ArrayList<Long>();
+        mSyncParser.deleteParser(deleteList, Tags.SYNC_DELETE);
+        // It should have found the message
+        assertEquals(1, deleteList.size());
+        long id = deleteList.get(0);
+        // And the id's should match
+        assertEquals(deleteMessageId, id);
+    }
+
+    public void testChangeParser() throws IOException {
+        // Setup some messages
+        ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
+        ContentValues cv = new ContentValues();
+        int randomFlags = Message.FLAG_INCOMING_MEETING_CANCEL | Message.FLAG_TYPE_FORWARD;
+        cv.put(SyncColumns.SERVER_ID, TEST_SERVER_ID);
+        cv.put(MessageColumns.FLAGS, randomFlags);
+        long changeMessageId = messageIds.get(1);
+        mResolver.update(ContentUris.withAppendedId(Message.CONTENT_URI, changeMessageId), cv,
+                null, null);
+
+        // Setup our adapter and parser
+        setupSyncParserAndAdapter(mAccount, mMailbox);
+
+        // Set up an input stream with a change command (marking TEST_SERVER_ID unread)
+        // Note that the test message creation code sets read to "true"
+        Serializer s = new Serializer(false);
+        s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, TEST_SERVER_ID);
+        s.start(Tags.SYNC_APPLICATION_DATA);
+        s.data(Tags.EMAIL_READ, "0");
+        s.data(Tags.EMAIL2_LAST_VERB_EXECUTED,
+                Integer.toString(EmailSyncAdapter.LAST_VERB_FORWARD));
+        s.end().end().done();
+        byte[] bytes = s.toByteArray();
+        mSyncParser.resetInput(new ByteArrayInputStream(bytes));
+        mSyncParser.nextTag(0);
+
+        // Run the delete parser
+        ArrayList<ServerChange> changeList = new ArrayList<ServerChange>();
+        mSyncParser.changeParser(changeList);
+        // It should have found the message
+        assertEquals(1, changeList.size());
+        // And the id's should match
+        ServerChange change = changeList.get(0);
+        assertEquals(changeMessageId, change.id);
+        assertNotNull(change.read);
+        assertFalse(change.read);
+        // Make sure we see the forwarded flag AND that the original flags are preserved
+        assertEquals((Integer)(randomFlags | Message.FLAG_FORWARDED), change.flags);
+    }
+
+    public void testCleanup() throws IOException {
+        // Setup some messages
+        ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
+        // Setup our adapter and parser
+        setupSyncParserAndAdapter(mAccount, mMailbox);
+
+        // Delete two of the messages, change one
+        long id = messageIds.get(0);
+        mResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id),
+                null, null);
+        mSyncAdapter.mDeletedIdList.add(id);
+        id = messageIds.get(1);
+        mResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,
+                id), null, null);
+        mSyncAdapter.mDeletedIdList.add(id);
+        id = messageIds.get(2);
+        ContentValues cv = new ContentValues();
+        cv.put(Message.FLAG_READ, 0);
+        mResolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,
+                id), cv, null, null);
+        mSyncAdapter.mUpdatedIdList.add(id);
+
+        // The changed message should still exist
+        assertEquals(1, EmailContent.count(mProviderContext, Message.CONTENT_URI, WHERE_ACCOUNT_KEY,
+                getAccountArgument(mAccount.mId)));
+
+        // As well, the two deletions and one update
+        assertEquals(2, EmailContent.count(mProviderContext, Message.DELETED_CONTENT_URI,
+                WHERE_ACCOUNT_KEY, getAccountArgument(mAccount.mId)));
+        assertEquals(1, EmailContent.count(mProviderContext, Message.UPDATED_CONTENT_URI,
+                WHERE_ACCOUNT_KEY, getAccountArgument(mAccount.mId)));
+
+        // Cleanup (i.e. after sync); should remove items from delete/update tables
+        mSyncAdapter.cleanup();
+
+        // The three should be gone
+        assertEquals(0, EmailContent.count(mProviderContext, Message.DELETED_CONTENT_URI,
+                WHERE_ACCOUNT_KEY, getAccountArgument(mAccount.mId)));
+        assertEquals(0, EmailContent.count(mProviderContext, Message.UPDATED_CONTENT_URI,
+                WHERE_ACCOUNT_KEY, getAccountArgument(mAccount.mId)));
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java b/exchange2/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java
new file mode 100644
index 0000000..dc5d15b
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.content.ContentResolver;
+import android.content.res.AssetManager;
+import android.database.Cursor;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.service.SyncWindow;
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.provider.EmailContentSetupUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.adapter.FolderSyncParserTests exchange
+ */
+@MediumTest
+public class FolderSyncParserTests extends SyncAdapterTestCase<EmailSyncAdapter> {
+
+    // We increment this to generate unique server id's
+    private int mServerIdCount = 0;
+    private final long mCreationTime = System.currentTimeMillis();
+    private final String[] mMailboxQueryArgs = new String[2];
+
+    public FolderSyncParserTests() {
+        super();
+    }
+
+    public void testIsValidMailFolder() throws IOException {
+        EasSyncService service = getTestService();
+        EmailSyncAdapter adapter = new EmailSyncAdapter(service);
+        FolderSyncParser parser = new FolderSyncParser(getTestInputStream(), adapter);
+        HashMap<String, Mailbox> mailboxMap = new HashMap<String, Mailbox>();
+        // The parser needs the mAccount set
+        parser.mAccount = mAccount;
+        mAccount.save(getContext());
+
+        // Don't save the box; just create it, and give it a server id
+        Mailbox boxMailType = EmailContentSetupUtils.setupMailbox("box1", mAccount.mId, false,
+                mProviderContext, Mailbox.TYPE_MAIL);
+        boxMailType.mServerId = "__1:1";
+        // Automatically valid since TYPE_MAIL
+        assertTrue(parser.isValidMailFolder(boxMailType, mailboxMap));
+
+        Mailbox boxCalendarType = EmailContentSetupUtils.setupMailbox("box", mAccount.mId, false,
+                mProviderContext, Mailbox.TYPE_CALENDAR);
+        Mailbox boxContactsType = EmailContentSetupUtils.setupMailbox("box", mAccount.mId, false,
+                mProviderContext, Mailbox.TYPE_CONTACTS);
+        Mailbox boxTasksType = EmailContentSetupUtils.setupMailbox("box", mAccount.mId, false,
+                mProviderContext, Mailbox.TYPE_TASKS);
+        // Automatically invalid since TYPE_CALENDAR and TYPE_CONTACTS
+        assertFalse(parser.isValidMailFolder(boxCalendarType, mailboxMap));
+        assertFalse(parser.isValidMailFolder(boxContactsType, mailboxMap));
+        assertFalse(parser.isValidMailFolder(boxTasksType, mailboxMap));
+
+        // Unknown boxes are invalid unless they have a parent that's valid
+        Mailbox boxUnknownType = EmailContentSetupUtils.setupMailbox("box", mAccount.mId, false,
+                mProviderContext, Mailbox.TYPE_UNKNOWN);
+        assertFalse(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+        boxUnknownType.mParentServerId = boxMailType.mServerId;
+        // We shouldn't find the parent yet
+        assertFalse(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+        // Put the mailbox in the map; the unknown box should now be valid
+        mailboxMap.put(boxMailType.mServerId, boxMailType);
+        assertTrue(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+
+        // Clear the map, but save away the parent box
+        mailboxMap.clear();
+        assertFalse(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+        boxMailType.save(mProviderContext);
+        // The box should now be valid
+        assertTrue(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+
+        // Somewhat harder case.  The parent will be in the map, but also unknown.  The parent's
+        // parent will be in the database.
+        Mailbox boxParentUnknownType = EmailContentSetupUtils.setupMailbox("box", mAccount.mId,
+                false, mProviderContext, Mailbox.TYPE_UNKNOWN);
+        assertFalse(parser.isValidMailFolder(boxParentUnknownType, mailboxMap));
+        // Give the unknown type parent a parent (boxMailType)
+        boxParentUnknownType.mServerId = "__1:2";
+        boxParentUnknownType.mParentServerId = boxMailType.mServerId;
+        // Give our unknown box an unknown parent
+        boxUnknownType.mParentServerId = boxParentUnknownType.mServerId;
+        // Confirm the box is still invalid
+        assertFalse(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+        // Put the unknown type parent into the mailbox map
+        mailboxMap.put(boxParentUnknownType.mServerId, boxParentUnknownType);
+        // Our unknown box should now be valid, because 1) the parent is unknown, BUT 2) the
+        // parent's parent is a mail type
+        assertTrue(parser.isValidMailFolder(boxUnknownType, mailboxMap));
+    }
+
+    private Mailbox setupBoxSync(int interval, int lookback, String serverId) {
+        // Don't save the box; just create it, and give it a server id
+        Mailbox box = EmailContentSetupUtils.setupMailbox("box1", mAccount.mId, false,
+                mProviderContext, Mailbox.TYPE_MAIL);
+        box.mSyncInterval = interval;
+        box.mSyncLookback = lookback;
+        if (serverId != null) {
+            box.mServerId = serverId;
+        } else {
+            box.mServerId = "serverId-" + mCreationTime + '-' + mServerIdCount++;
+        }
+        box.save(mProviderContext);
+        return box;
+    }
+
+    private boolean syncOptionsSame(Mailbox a, Mailbox b) {
+        if (a.mSyncInterval != b.mSyncInterval) return false;
+        if (a.mSyncLookback != b.mSyncLookback) return false;
+        return true;
+    }
+
+    public void testSaveAndRestoreMailboxSyncOptions() throws IOException {
+        EasSyncService service = getTestService();
+        EmailSyncAdapter adapter = new EmailSyncAdapter(service);
+        FolderSyncParser parser = new FolderSyncParser(getTestInputStream(), adapter);
+        mAccount.save(mProviderContext);
+
+        parser.mAccount = mAccount;
+        parser.mAccountId = mAccount.mId;
+        parser.mAccountIdAsString = Long.toString(mAccount.mId);
+        parser.mContext = mProviderContext;
+        parser.mContentResolver = mProviderContext.getContentResolver();
+
+        // Don't save the box; just create it, and give it a server id
+        Mailbox box1 = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                null);
+        Mailbox box2 = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                null);
+        Mailbox boxa = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_1_MONTH,
+                null);
+        Mailbox boxb = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_2_WEEKS,
+                null);
+        Mailbox boxc = setupBoxSync(Account.CHECK_INTERVAL_PUSH, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                null);
+        Mailbox boxd = setupBoxSync(Account.CHECK_INTERVAL_PUSH, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                null);
+        Mailbox boxe = setupBoxSync(Account.CHECK_INTERVAL_PUSH, SyncWindow.SYNC_WINDOW_1_DAY,
+                null);
+
+        // Save the options (for a, b, c, d, e);
+        parser.saveMailboxSyncOptions();
+        // There should be 5 entries in the map, and they should be the correct ones
+        assertNotNull(parser.mSyncOptionsMap.get(boxa.mServerId));
+        assertNotNull(parser.mSyncOptionsMap.get(boxb.mServerId));
+        assertNotNull(parser.mSyncOptionsMap.get(boxc.mServerId));
+        assertNotNull(parser.mSyncOptionsMap.get(boxd.mServerId));
+        assertNotNull(parser.mSyncOptionsMap.get(boxe.mServerId));
+
+        // Delete all the mailboxes in the account
+        ContentResolver cr = mProviderContext.getContentResolver();
+        cr.delete(Mailbox.CONTENT_URI, Mailbox.ACCOUNT_KEY + "=?",
+                new String[] {parser.mAccountIdAsString});
+
+        // Create new boxes, all with default values for interval & window
+        Mailbox box1x = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                box1.mServerId);
+        Mailbox box2x = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                box2.mServerId);
+        Mailbox boxax = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                boxa.mServerId);
+        Mailbox boxbx = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                boxb.mServerId);
+        Mailbox boxcx = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                boxc.mServerId);
+        Mailbox boxdx = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                boxd.mServerId);
+        Mailbox boxex = setupBoxSync(Account.CHECK_INTERVAL_NEVER, SyncWindow.SYNC_WINDOW_UNKNOWN,
+                boxe.mServerId);
+
+        // Restore the sync options
+        parser.restoreMailboxSyncOptions();
+        box1x = Mailbox.restoreMailboxWithId(mProviderContext, box1x.mId);
+        box2x = Mailbox.restoreMailboxWithId(mProviderContext, box2x.mId);
+        boxax = Mailbox.restoreMailboxWithId(mProviderContext, boxax.mId);
+        boxbx = Mailbox.restoreMailboxWithId(mProviderContext, boxbx.mId);
+        boxcx = Mailbox.restoreMailboxWithId(mProviderContext, boxcx.mId);
+        boxdx = Mailbox.restoreMailboxWithId(mProviderContext, boxdx.mId);
+        boxex = Mailbox.restoreMailboxWithId(mProviderContext, boxex.mId);
+
+        assertTrue(syncOptionsSame(box1, box1x));
+        assertTrue(syncOptionsSame(box2, box2x));
+        assertTrue(syncOptionsSame(boxa, boxax));
+        assertTrue(syncOptionsSame(boxb, boxbx));
+        assertTrue(syncOptionsSame(boxc, boxcx));
+        assertTrue(syncOptionsSame(boxd, boxdx));
+        assertTrue(syncOptionsSame(boxe, boxex));
+    }
+
+    private static class MockFolderSyncParser extends FolderSyncParser {
+        private BufferedReader mReader;
+        private int mDepth = 0;
+        private String[] mStack = new String[32];
+        private HashMap<String, Integer> mTagMap;
+
+
+        public MockFolderSyncParser(String fileName, AbstractSyncAdapter adapter)
+                throws IOException {
+            super(null, adapter);
+            AssetManager am = mContext.getAssets();
+            InputStream is = am.open(fileName);
+            if (is != null) {
+                mReader = new BufferedReader(new InputStreamReader(is));
+            }
+            mInUnitTest = true;
+        }
+
+        private void initTagMap() {
+            mTagMap = new HashMap<String, Integer>();
+            int pageNum = 0;
+            for (String[] page: Tags.pages) {
+                int tagNum = 5;
+                for (String tag: page) {
+                    if (mTagMap.containsKey(tag)) {
+                        System.err.println("Duplicate tag: " + tag);
+                    }
+                    int val = (pageNum << Tags.PAGE_SHIFT) + tagNum;
+                    mTagMap.put(tag, val);
+                    tagNum++;
+                }
+                pageNum++;
+            }
+        }
+
+        private int lookupTag(String tagName) {
+            if (mTagMap == null) {
+                initTagMap();
+            }
+            int res = mTagMap.get(tagName);
+            return res;
+        }
+
+        private String getLine() throws IOException {
+            while (true) {
+                String line = mReader.readLine();
+                if (line == null) {
+                    return null;
+                }
+                int start = line.indexOf("| ");
+                if (start > 2) {
+                    return line.substring(start + 2);
+                }
+                // Keep looking for a suitable line
+            }
+        }
+
+        @Override
+        public int getValueInt() throws IOException {
+            return Integer.parseInt(getValue());
+        }
+
+        @Override
+        public String getValue() throws IOException {
+            String line = getLine();
+            if (line == null) throw new IOException();
+            int start = line.indexOf(": ");
+            if (start < 0) throw new IOException("Line has no value: " + line);
+            try {
+                return line.substring(start + 2).trim();
+            } finally {
+                if (nextTag(0) != END) {
+                    throw new IOException("Value not followed by end tag: " + name);
+                }
+            }
+        }
+
+        @Override
+        public void skipTag() throws IOException {
+            if (nextTag(0) == -1) {
+                nextTag(0);
+            }
+        }
+
+        @Override
+        public int nextTag(int endingTag) throws IOException {
+            String line = getLine();
+            if (line == null) {
+                return DONE;
+            }
+            if (line.startsWith("</")) {
+                int end = line.indexOf('>');
+                String tagName = line.substring(2, end).trim();
+                if (!tagName.equals(mStack[--mDepth])) {
+                    throw new IOException("Tag end doesn't match tag");
+                }
+                mStack[mDepth] = null;
+                return END;
+            } else if (line.startsWith("<")) {
+                int end = line.indexOf('>');
+                String tagName = line.substring(1, end).trim();
+                mStack[mDepth++] = tagName;
+                tag = lookupTag(tagName);
+                return tag;
+            } else {
+                return -1;
+            }
+        }
+    }
+
+    private Mailbox getMailboxWithName(String folderName) {
+        mMailboxQueryArgs[1] = folderName;
+        Cursor c = mResolver.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
+                Mailbox.ACCOUNT_KEY + "=? AND " + Mailbox.DISPLAY_NAME + "=?", mMailboxQueryArgs,
+                null);
+        try {
+            assertTrue(c.getCount() == 1);
+            c.moveToFirst();
+            Mailbox m = new Mailbox();
+            m.restore(c);
+            return m;
+        } finally {
+            c.close();
+        }
+    }
+
+    private boolean isTopLevel(String folderName) {
+        Mailbox m = getMailboxWithName(folderName);
+        assertNotNull(m);
+        return m.mParentKey == Mailbox.NO_MAILBOX;
+    }
+
+    private boolean isSubfolder(String parentName, String childName) {
+        Mailbox parent = getMailboxWithName(parentName);
+        Mailbox child = getMailboxWithName(childName);
+        assertNotNull(parent);
+        assertNotNull(child);
+        assertTrue((parent.mFlags & Mailbox.FLAG_HAS_CHILDREN) != 0);
+        return child.mParentKey == parent.mId;
+    }
+
+    /**
+     * Parse a set of EAS FolderSync commands and create the Mailbox tree accordingly
+     *
+     * @param fileName the name of the file containing emaillog data for folder sync
+     * @throws IOException
+     * @throws CommandStatusException
+     */
+    private void testComplexFolderListParse(String fileName) throws IOException,
+    CommandStatusException {
+        EasSyncService service = getTestService();
+        EmailSyncAdapter adapter = new EmailSyncAdapter(service);
+        FolderSyncParser parser = new MockFolderSyncParser(fileName, adapter);
+        mAccount.save(mProviderContext);
+        mMailboxQueryArgs[0] = Long.toString(mAccount.mId);
+        parser.mAccount = mAccount;
+        parser.mAccountId = mAccount.mId;
+        parser.mAccountIdAsString = Long.toString(mAccount.mId);
+        parser.mContext = mProviderContext;
+        parser.mContentResolver = mResolver;
+
+        parser.parse();
+
+        assertTrue(isTopLevel("Inbox"));
+        assertTrue(isSubfolder("Inbox", "Gecko"));
+        assertTrue(isSubfolder("Inbox", "Wombat"));
+        assertTrue(isSubfolder("Inbox", "Laslo"));
+        assertTrue(isSubfolder("Inbox", "Tomorrow"));
+        assertTrue(isSubfolder("Inbox", "Vader"));
+        assertTrue(isSubfolder("Inbox", "Personal"));
+        assertTrue(isSubfolder("Laslo", "Lego"));
+        assertTrue(isSubfolder("Tomorrow", "HomeRun"));
+        assertTrue(isSubfolder("Tomorrow", "Services"));
+        assertTrue(isSubfolder("HomeRun", "Review"));
+        assertTrue(isSubfolder("Vader", "Max"));
+        assertTrue(isSubfolder("Vader", "Parser"));
+        assertTrue(isSubfolder("Vader", "Scott"));
+        assertTrue(isSubfolder("Vader", "Surfing"));
+        assertTrue(isSubfolder("Max", "Thomas"));
+        assertTrue(isSubfolder("Personal", "Famine"));
+        assertTrue(isSubfolder("Personal", "Bar"));
+        assertTrue(isSubfolder("Personal", "Bill"));
+        assertTrue(isSubfolder("Personal", "Boss"));
+        assertTrue(isSubfolder("Personal", "Houston"));
+        assertTrue(isSubfolder("Personal", "Mistake"));
+        assertTrue(isSubfolder("Personal", "Online"));
+        assertTrue(isSubfolder("Personal", "Sports"));
+        assertTrue(isSubfolder("Famine", "Buffalo"));
+        assertTrue(isSubfolder("Famine", "CornedBeef"));
+        assertTrue(isSubfolder("Houston", "Rebar"));
+        assertTrue(isSubfolder("Mistake", "Intro"));
+    }
+
+    // FolderSyncParserTest.txt is based on customer data (all names changed) that failed to
+    // properly create the Mailbox list
+    public void testComplexFolderListParse1() throws CommandStatusException, IOException {
+        testComplexFolderListParse("FolderSyncParserTest.txt");
+    }
+
+    // As above, with the order changed (putting children before parents; a more difficult case
+    public void testComplexFolderListParse2() throws CommandStatusException, IOException {
+        testComplexFolderListParse("FolderSyncParserTest2.txt");
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/ProvisionParserTests.java b/exchange2/tests/src/com/android/exchange/adapter/ProvisionParserTests.java
new file mode 100644
index 0000000..95b76a6
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/ProvisionParserTests.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import com.android.emailcommon.provider.Policy;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.adapter.ProvisionParserTests exchange
+ */
+@SmallTest
+public class ProvisionParserTests extends SyncAdapterTestCase {
+    private final ByteArrayInputStream mTestInputStream =
+        new ByteArrayInputStream("ABCDEFG".getBytes());
+
+    // A good sample of an Exchange 2003 (WAP) provisioning document for end-to-end testing
+    private String mWapProvisioningDoc1 =
+        "<wap-provisioningdoc>" +
+            "<characteristic type=\"SecurityPolicy\"><parm name=\"4131\" value=\"0\"/>" +
+            "</characteristic>" +
+            "<characteristic type=\"Registry\">" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\AE\\" +
+                        "{50C13377-C66D-400C-889E-C316FC4AB374}\">" +
+                    "<parm name=\"AEFrequencyType\" value=\"1\"/>" +
+                    "<parm name=\"AEFrequencyValue\" value=\"5\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\">" +
+                    "<parm name=\"DeviceWipeThreshold\" value=\"20\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\">" +
+                    "<parm name=\"CodewordFrequency\" value=\"5\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\LAP\\lap_pw\">" +
+                    "<parm name=\"MinimumPasswordLength\" value=\"8\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\LAP\\lap_pw\">" +
+                    "<parm name=\"PasswordComplexity\" value=\"0\"/>" +
+                "</characteristic>" +
+            "</characteristic>" +
+        "</wap-provisioningdoc>";
+
+    // Provisioning document with passwords turned off
+    private String mWapProvisioningDoc2 =
+        "<wap-provisioningdoc>" +
+            "<characteristic type=\"SecurityPolicy\"><parm name=\"4131\" value=\"1\"/>" +
+            "</characteristic>" +
+            "<characteristic type=\"Registry\">" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\AE\\" +
+                        "{50C13377-C66D-400C-889E-C316FC4AB374}\">" +
+                    "<parm name=\"AEFrequencyType\" value=\"0\"/>" +
+                    "<parm name=\"AEFrequencyValue\" value=\"5\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\">" +
+                    "<parm name=\"DeviceWipeThreshold\" value=\"20\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\">" +
+                    "<parm name=\"CodewordFrequency\" value=\"5\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\LAP\\lap_pw\">" +
+                    "<parm name=\"MinimumPasswordLength\" value=\"8\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\LAP\\lap_pw\">" +
+                    "<parm name=\"PasswordComplexity\" value=\"0\"/>" +
+                "</characteristic>" +
+            "</characteristic>" +
+        "</wap-provisioningdoc>";
+
+    // Provisioning document with simple password, 4 chars, 5 failures
+    private String mWapProvisioningDoc3 =
+        "<wap-provisioningdoc>" +
+            "<characteristic type=\"SecurityPolicy\"><parm name=\"4131\" value=\"0\"/>" +
+            "</characteristic>" +
+            "<characteristic type=\"Registry\">" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\AE\\" +
+                        "{50C13377-C66D-400C-889E-C316FC4AB374}\">" +
+                    "<parm name=\"AEFrequencyType\" value=\"1\"/>" +
+                    "<parm name=\"AEFrequencyValue\" value=\"2\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\">" +
+                    "<parm name=\"DeviceWipeThreshold\" value=\"5\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\">" +
+                    "<parm name=\"CodewordFrequency\" value=\"5\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\LAP\\lap_pw\">" +
+                    "<parm name=\"MinimumPasswordLength\" value=\"4\"/>" +
+                "</characteristic>" +
+                "<characteristic type=\"HKLM\\Comm\\Security\\Policy\\LASSD\\LAP\\lap_pw\">" +
+                    "<parm name=\"PasswordComplexity\" value=\"1\"/>" +
+                "</characteristic>" +
+            "</characteristic>" +
+        "</wap-provisioningdoc>";
+
+    public void testWapProvisionParser1() throws IOException {
+         ProvisionParser parser = new ProvisionParser(mTestInputStream, getTestService());
+        parser.parseProvisionDocXml(mWapProvisioningDoc1);
+        Policy policy = parser.getPolicy();
+        assertNotNull(policy);
+        // Check the settings to make sure they were parsed correctly
+        assertEquals(5*60, policy.mMaxScreenLockTime);  // Screen lock time is in seconds
+        assertEquals(8, policy.mPasswordMinLength);
+        assertEquals(Policy.PASSWORD_MODE_STRONG, policy.mPasswordMode);
+        assertEquals(20, policy.mPasswordMaxFails);
+        assertTrue(policy.mRequireRemoteWipe);
+    }
+
+    public void testWapProvisionParser2() throws IOException {
+        ProvisionParser parser = new ProvisionParser(mTestInputStream, getTestService());
+        parser.parseProvisionDocXml(mWapProvisioningDoc2);
+        Policy policy = parser.getPolicy();
+        assertNotNull(policy);
+        // Password should be set to none; others are ignored in this case.
+        assertEquals(Policy.PASSWORD_MODE_NONE, policy.mPasswordMode);
+    }
+
+    public void testWapProvisionParser3() throws IOException {
+        ProvisionParser parser = new ProvisionParser(mTestInputStream, getTestService());
+        parser.parseProvisionDocXml(mWapProvisioningDoc3);
+        Policy policy = parser.getPolicy();
+        assertNotNull(policy);
+        // Password should be set to simple
+        assertEquals(2*60, policy.mMaxScreenLockTime);  // Screen lock time is in seconds
+        assertEquals(4, policy.mPasswordMinLength);
+        assertEquals(Policy.PASSWORD_MODE_SIMPLE, policy.mPasswordMode);
+        assertEquals(5, policy.mPasswordMaxFails);
+        assertTrue(policy.mRequireRemoteWipe);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/SerializerTests.java b/exchange2/tests/src/com/android/exchange/adapter/SerializerTests.java
new file mode 100644
index 0000000..c26bcab
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/SerializerTests.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.content.ContentValues;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/** You can run this entire test case with:
+ *   runtest -c com.android.exchange.adapter.SerializerTests exchange
+ */
+public class SerializerTests extends AndroidTestCase {
+
+    private static final byte[] BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5};
+    private static final int BYTE_ARRAY_LENGTH = 5;
+    private static final String ID = "ID";
+    private static final String KEY = "Key";
+
+    // Basic test for use of start, end, tag, data, opaque, and done
+    public void testSerializer() throws IOException {
+        ContentValues values = new ContentValues();
+        // Create a test stream
+        Serializer s = new Serializer();
+        s.start(Tags.COMPOSE_SEND_MAIL);
+
+        // Test writeStringValue without and with data
+        s.writeStringValue(values, KEY, Tags.COMPOSE_ACCOUNT_ID);
+        values.put(KEY, ID);
+        s.writeStringValue(values, KEY, Tags.COMPOSE_ACCOUNT_ID);
+
+        s.data(Tags.COMPOSE_CLIENT_ID, ID);
+        s.tag(Tags.COMPOSE_SAVE_IN_SENT_ITEMS);
+        s.start(Tags.COMPOSE_MIME);
+        s.opaque(new ByteArrayInputStream(BYTE_ARRAY), BYTE_ARRAY_LENGTH);
+        s.end();  // COMPOSE_MIME
+        s.end();  // COMPOSE_SEND_MAIL
+        s.done(); // DOCUMENT
+        // Get the bytes for the stream
+        byte[] bytes = s.toByteArray();
+        // These are the expected bytes (self-explanatory)
+        byte[] expectedBytes = new byte[] {
+                3,      // Version 1.3
+                1,      // unknown or missing public identifier
+                106,    // UTF-8
+                0,      // String array length
+                Wbxml.SWITCH_PAGE,
+                Tags.COMPOSE,
+                Tags.COMPOSE_SEND_MAIL - Tags.COMPOSE_PAGE + Wbxml.WITH_CONTENT,
+                Tags.COMPOSE_ACCOUNT_ID - Tags.COMPOSE_PAGE,
+                Tags.COMPOSE_ACCOUNT_ID - Tags.COMPOSE_PAGE + Wbxml.WITH_CONTENT,
+                Wbxml.STR_I,    // 0-terminated string
+                (byte)ID.charAt(0),
+                (byte)ID.charAt(1),
+                0,
+                Wbxml.END,  // COMPOSE_ACCOUNT_ID
+                Tags.COMPOSE_CLIENT_ID - Tags.COMPOSE_PAGE + Wbxml.WITH_CONTENT,
+                Wbxml.STR_I,    // 0-terminated string
+                (byte)ID.charAt(0),
+                (byte)ID.charAt(1),
+                0,
+                Wbxml.END,  // COMPOSE_CLIENT_ID
+                Tags.COMPOSE_SAVE_IN_SENT_ITEMS - Tags.COMPOSE_PAGE,
+                Tags.COMPOSE_MIME - Tags.COMPOSE_PAGE + Wbxml.WITH_CONTENT,
+                (byte)Wbxml.OPAQUE,
+                BYTE_ARRAY_LENGTH,
+                BYTE_ARRAY[0],
+                BYTE_ARRAY[1],
+                BYTE_ARRAY[2],
+                BYTE_ARRAY[3],
+                BYTE_ARRAY[4],
+                Wbxml.END,  // COMPOSE_MIME
+                Wbxml.END   // COMPOSE_SEND_MAIL
+         };
+        // Make sure we get what's expected
+        MoreAsserts.assertEquals("Serializer mismatch", bytes, expectedBytes);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/adapter/SyncAdapterTestCase.java b/exchange2/tests/src/com/android/exchange/adapter/SyncAdapterTestCase.java
new file mode 100644
index 0000000..e8553ca
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/adapter/SyncAdapterTestCase.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.adapter;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.EasSyncService;
+import com.android.exchange.adapter.AbstractSyncAdapter;
+import com.android.exchange.adapter.EmailSyncAdapter;
+import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+public class SyncAdapterTestCase<T extends AbstractSyncAdapter> extends AndroidTestCase {
+    public Context mContext;
+    public Context mProviderContext;
+    public ContentResolver mResolver;
+    public Mailbox mMailbox;
+    public Account mAccount;
+    public EmailSyncAdapter mSyncAdapter;
+    public EasEmailSyncParser mSyncParser;
+
+    public SyncAdapterTestCase() {
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mContext = getContext();
+        // This could be used with a MockContext if we switch over
+        mProviderContext = mContext;
+        mResolver = mContext.getContentResolver();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        // If we've created and saved an account, delete it
+        if (mAccount != null && mAccount.mId > 0) {
+            mResolver.delete(ContentUris.withAppendedId(Account.CONTENT_URI, mAccount.mId), null,
+                    null);
+        }
+    }
+
+    /**
+     * Create and return a short, simple InputStream that has at least four bytes, which is all
+     * that's required to initialize an EasParser (the parent class of EasEmailSyncParser)
+     * @return the InputStream
+     */
+    public InputStream getTestInputStream() {
+        return new ByteArrayInputStream(new byte[] {0, 0, 0, 0, 0});
+    }
+
+    EasSyncService getTestService() {
+        mAccount = new Account();
+        mAccount.mEmailAddress = "__test__@android.com";
+        mAccount.mId = -1;
+        Mailbox mailbox = new Mailbox();
+        mailbox.mId = -1;
+        return getTestService(mAccount, mailbox);
+    }
+
+    EasSyncService getTestService(Account account, Mailbox mailbox) {
+        EasSyncService service = new EasSyncService();
+        service.mContext = mContext;
+        service.mMailbox = mailbox;
+        service.mAccount = account;
+        service.mContentResolver = mContext.getContentResolver();
+        return service;
+    }
+
+    protected T getTestSyncAdapter(Class<T> klass) {
+        EasSyncService service = getTestService();
+        Constructor<T> c;
+        try {
+            c = klass.getDeclaredConstructor(new Class[] {EasSyncService.class});
+            return c.newInstance(service);
+        } catch (SecurityException e) {
+        } catch (NoSuchMethodException e) {
+        } catch (IllegalArgumentException e) {
+        } catch (InstantiationException e) {
+        } catch (IllegalAccessException e) {
+        } catch (InvocationTargetException e) {
+        }
+        return null;
+    }
+
+}
diff --git a/exchange2/tests/src/com/android/exchange/provider/EmailContentSetupUtils.java b/exchange2/tests/src/com/android/exchange/provider/EmailContentSetupUtils.java
new file mode 100644
index 0000000..c302b02
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/provider/EmailContentSetupUtils.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.Mailbox;
+
+import android.content.Context;
+
+/**
+ * Simplified EmailContent class setup (condensed from ProviderTestUtils in com.android.email)
+ */
+public class EmailContentSetupUtils {
+
+    /**
+     * No constructor - statics only
+     */
+    private EmailContentSetupUtils() {
+    }
+
+    /**
+     * Create an account for test purposes
+     */
+    public static Account setupAccount(String name, boolean saveIt, Context context) {
+        Account account = new Account();
+
+        account.mDisplayName = name;
+        account.mEmailAddress = name + "@android.com";
+        account.mProtocolVersion = "2.5" + name;
+        if (saveIt) {
+            account.save(context);
+        }
+        return account;
+    }
+
+    /**
+     * Create a mailbox for test purposes
+     */
+    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
+            Context context) {
+        return setupMailbox(name, accountId, saveIt, context, Mailbox.TYPE_MAIL, null);
+    }
+
+    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
+            Context context, int type) {
+        return setupMailbox(name, accountId, saveIt, context, type, null);
+    }
+
+    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
+            Context context, int type, Mailbox parentBox) {
+        Mailbox box = new Mailbox();
+
+        box.mDisplayName = name;
+        box.mAccountKey = accountId;
+        box.mSyncKey = "sync-key-" + name;
+        box.mSyncLookback = 2;
+        box.mSyncInterval = Account.CHECK_INTERVAL_NEVER;
+        box.mType = type;
+        box.mServerId = "serverid-" + name;
+        box.mParentServerId = parentBox != null ? parentBox.mServerId : "parent-serverid-" + name;
+
+        if (saveIt) {
+            box.save(context);
+        }
+        return box;
+    }
+
+    /**
+     * Create a message for test purposes
+     */
+    public static Message setupMessage(String name, long accountId, long mailboxId,
+            boolean addBody, boolean saveIt, Context context) {
+        // Default starred, read,  (backword compatibility)
+        return setupMessage(name, accountId, mailboxId, addBody, saveIt, context, true, true);
+    }
+
+    /**
+     * Create a message for test purposes
+     */
+    public static Message setupMessage(String name, long accountId, long mailboxId,
+            boolean addBody, boolean saveIt, Context context, boolean starred, boolean read) {
+        Message message = new Message();
+
+        message.mDisplayName = name;
+        message.mMailboxKey = mailboxId;
+        message.mAccountKey = accountId;
+        message.mFlagRead = read;
+        message.mFlagLoaded = Message.FLAG_LOADED_UNLOADED;
+        message.mFlagFavorite = starred;
+        message.mServerId = "serverid " + name;
+
+        if (addBody) {
+            message.mText = "body text " + name;
+            message.mHtml = "body html " + name;
+        }
+
+        if (saveIt) {
+            message.save(context);
+        }
+        return message;
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/provider/ExchangeDirectoryProviderTests.java b/exchange2/tests/src/com/android/exchange/provider/ExchangeDirectoryProviderTests.java
new file mode 100644
index 0000000..e4bd791
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/provider/ExchangeDirectoryProviderTests.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import com.android.emailcommon.mail.PackedString;
+import com.android.emailcommon.provider.Account;
+import com.android.exchange.provider.GalResult.GalData;
+import com.android.exchange.utility.ExchangeTestCase;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.provider.ExchangeDirectoryProviderTests exchange
+ */
+@SmallTest
+public class ExchangeDirectoryProviderTests extends ExchangeTestCase {
+
+    public ExchangeDirectoryProviderTests() {
+    }
+
+    // Create a test projection; we should only get back values for display name and email address
+    private static final String[] GAL_RESULT_PROJECTION =
+        new String[] {Contacts.DISPLAY_NAME, CommonDataKinds.Email.ADDRESS, Contacts.CONTENT_TYPE,
+            Contacts.LOOKUP_KEY};
+    private static final int GAL_RESULT_COLUMN_DISPLAY_NAME = 0;
+    private static final int GAL_RESULT_COLUMN_EMAIL_ADDRESS = 1;
+    private static final int GAL_RESULT_COLUMN_CONTENT_TYPE = 2;
+    private static final int GAL_RESULT_COLUMN_LOOKUP_KEY = 3;
+
+    public void testBuildSimpleGalResultCursor() {
+        GalResult result = new GalResult();
+        result.addGalData(1, "Alice Aardvark", "alice@aardvark.com");
+        result.addGalData(2, "Bob Badger", "bob@badger.com");
+        result.addGalData(3, "Clark Cougar", "clark@cougar.com");
+        result.addGalData(4, "Dan Dolphin", "dan@dolphin.com");
+        // Make sure our returned cursor has the expected contents
+        ExchangeDirectoryProvider provider = new ExchangeDirectoryProvider();
+        Cursor c = provider.buildGalResultCursor(GAL_RESULT_PROJECTION, result);
+        assertNotNull(c);
+        assertEquals(MatrixCursor.class, c.getClass());
+        assertEquals(4, c.getCount());
+        for (int i = 0; i < 4; i++) {
+            GalData data = result.galData.get(i);
+            assertTrue(c.moveToNext());
+            assertEquals(data.displayName, c.getString(GAL_RESULT_COLUMN_DISPLAY_NAME));
+            assertEquals(data.emailAddress, c.getString(GAL_RESULT_COLUMN_EMAIL_ADDRESS));
+            assertNull(c.getString(GAL_RESULT_COLUMN_CONTENT_TYPE));
+        }
+    }
+
+    private static final String[][] DISPLAY_NAME_TEST_FIELDS = {
+        {"Alice", "Aardvark", "Another Name"},
+        {"Alice", "Aardvark", null},
+        {"Alice", null, null},
+        {null, "Aardvark", null},
+        {null, null, null}
+    };
+    private static final int TEST_FIELD_FIRST_NAME = 0;
+    private static final int TEST_FIELD_LAST_NAME = 1;
+    private static final int TEST_FIELD_DISPLAY_NAME = 2;
+    private static final String[] EXPECTED_DISPLAY_NAMES = new String[] {"Another Name",
+        "Alice Aardvark", "Alice", "Aardvark", null};
+
+    private GalResult getTestDisplayNameResult() {
+        GalResult result = new GalResult();
+        for (int i = 0; i < DISPLAY_NAME_TEST_FIELDS.length; i++) {
+            GalData galData = new GalData();
+            String[] names = DISPLAY_NAME_TEST_FIELDS[i];
+            galData.put(GalData.FIRST_NAME, names[TEST_FIELD_FIRST_NAME]);
+            galData.put(GalData.LAST_NAME, names[TEST_FIELD_LAST_NAME]);
+            galData.put(GalData.DISPLAY_NAME, names[TEST_FIELD_DISPLAY_NAME]);
+            result.addGalData(galData);
+        }
+        return result;
+    }
+
+    public void testDisplayNameLogic() {
+        GalResult result = getTestDisplayNameResult();
+        // Make sure our returned cursor has the expected contents
+        ExchangeDirectoryProvider provider = new ExchangeDirectoryProvider();
+        Cursor c = provider.buildGalResultCursor(GAL_RESULT_PROJECTION, result);
+        assertNotNull(c);
+        assertEquals(MatrixCursor.class, c.getClass());
+        assertEquals(DISPLAY_NAME_TEST_FIELDS.length, c.getCount());
+        for (int i = 0; i < EXPECTED_DISPLAY_NAMES.length; i++) {
+            assertTrue(c.moveToNext());
+            assertEquals(EXPECTED_DISPLAY_NAMES[i], c.getString(GAL_RESULT_COLUMN_DISPLAY_NAME));
+        }
+    }
+
+    public void testLookupKeyLogic() {
+        GalResult result = getTestDisplayNameResult();
+        // Make sure our returned cursor has the expected contents
+        ExchangeDirectoryProvider provider = new ExchangeDirectoryProvider();
+        Cursor c = provider.buildGalResultCursor(GAL_RESULT_PROJECTION, result);
+        assertNotNull(c);
+        assertEquals(MatrixCursor.class, c.getClass());
+        assertEquals(DISPLAY_NAME_TEST_FIELDS.length, c.getCount());
+        for (int i = 0; i < EXPECTED_DISPLAY_NAMES.length; i++) {
+            assertTrue(c.moveToNext());
+            PackedString ps =
+                new PackedString(Uri.decode(c.getString(GAL_RESULT_COLUMN_LOOKUP_KEY)));
+            String[] testFields = DISPLAY_NAME_TEST_FIELDS[i];
+            assertEquals(testFields[TEST_FIELD_FIRST_NAME], ps.get(GalData.FIRST_NAME));
+            assertEquals(testFields[TEST_FIELD_LAST_NAME], ps.get(GalData.LAST_NAME));
+            assertEquals(EXPECTED_DISPLAY_NAMES[i], ps.get(GalData.DISPLAY_NAME));
+        }
+    }
+
+    public void testGetAccountIdByName() {
+        Context context = getContext(); //getMockContext();
+        ExchangeDirectoryProvider provider = new ExchangeDirectoryProvider();
+        // Nothing up my sleeve
+        assertNull(provider.mAccountIdMap.get("foo@android.com"));
+        assertNull(provider.mAccountIdMap.get("bar@android.com"));
+        // Create accounts; the email addresses will be the first argument + "@android.com"
+        Account acctFoo = setupTestAccount("foo", true);
+        Account acctBar = setupTestAccount("bar", true);
+        // Make sure we can retrieve them, and that the map is populated
+        assertEquals(acctFoo.mId, provider.getAccountIdByName(context, "foo@android.com"));
+        assertEquals(acctBar.mId, provider.getAccountIdByName(context, "bar@android.com"));
+        assertEquals((Long)acctFoo.mId, provider.mAccountIdMap.get("foo@android.com"));
+        assertEquals((Long)acctBar.mId, provider.mAccountIdMap.get("bar@android.com"));
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java b/exchange2/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java
new file mode 100644
index 0000000..a7425d7
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java
@@ -0,0 +1,762 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
+import com.android.emailcommon.provider.Mailbox;
+import com.android.exchange.utility.ExchangeTestCase;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.test.suitebuilder.annotation.MediumTest;
+
+/**
+ * Tests of MailboxUtilities.
+ *
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.provider.MailboxUtilitiesTests exchange
+ */
+@MediumTest
+public class MailboxUtilitiesTests extends ExchangeTestCase {
+
+    // All tests must build their accounts in mAccount so it will be deleted from live data
+    private Account mAccount;
+    private ContentResolver mResolver;
+    private ContentValues mNullParentKey;
+
+    // Flag sets found in regular email folders that are parents or children
+    private static final int PARENT_FLAGS =
+            Mailbox.FLAG_ACCEPTS_MOVED_MAIL | Mailbox.FLAG_HOLDS_MAIL |
+            Mailbox.FLAG_HAS_CHILDREN | Mailbox.FLAG_CHILDREN_VISIBLE;
+    private static final int CHILD_FLAGS =
+            Mailbox.FLAG_ACCEPTS_MOVED_MAIL | Mailbox.FLAG_HOLDS_MAIL;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mAccount = null;
+        mResolver = mProviderContext.getContentResolver();
+        mNullParentKey = new ContentValues();
+        mNullParentKey.putNull(Mailbox.PARENT_KEY);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        // If we've created and saved an account, delete it
+        if (mAccount != null && mAccount.mId > 0) {
+            mResolver.delete(
+                    ContentUris.withAppendedId(Account.CONTENT_URI, mAccount.mId), null, null);
+        }
+    }
+
+    public void testSetupParentKeyAndFlag() {
+        // Set up account and various mailboxes with/without parents
+        mAccount = setupTestAccount("acct1", true);
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox("box1", mAccount.mId, true,
+                mProviderContext, Mailbox.TYPE_DRAFTS);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox("box2", mAccount.mId, true,
+                mProviderContext, Mailbox.TYPE_OUTBOX, box1);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox("box3", mAccount.mId, true,
+                mProviderContext, Mailbox.TYPE_ATTACHMENT, box1);
+        Mailbox box4 = EmailContentSetupUtils.setupMailbox("box4", mAccount.mId, true,
+                mProviderContext, Mailbox.TYPE_NOT_SYNCABLE + 64, box3);
+        Mailbox box5 = EmailContentSetupUtils.setupMailbox("box5", mAccount.mId, true,
+                mProviderContext, Mailbox.TYPE_MAIL, box3);
+
+        // To make this work, we need to manually set parentKey to null for all mailboxes
+        // This simulates an older database needing update
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Hand-create the account selector for our account
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Fix up the database and restore the mailboxes
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+        box4 = Mailbox.restoreMailboxWithId(mProviderContext, box4.mId);
+        box5 = Mailbox.restoreMailboxWithId(mProviderContext, box5.mId);
+
+        // Test that flags and parent key are set properly
+        assertEquals(Mailbox.FLAG_HOLDS_MAIL | Mailbox.FLAG_HAS_CHILDREN |
+                Mailbox.FLAG_CHILDREN_VISIBLE, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(Mailbox.FLAG_HOLDS_MAIL, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(Mailbox.FLAG_HAS_CHILDREN | Mailbox.FLAG_CHILDREN_VISIBLE, box3.mFlags);
+        assertEquals(box1.mId, box3.mParentKey);
+
+        assertEquals(0, box4.mFlags);
+        assertEquals(box3.mId, box4.mParentKey);
+
+        assertEquals(Mailbox.FLAG_HOLDS_MAIL | Mailbox.FLAG_ACCEPTS_MOVED_MAIL, box5.mFlags);
+        assertEquals(box3.mId, box5.mParentKey);
+    }
+
+    private void simulateFolderSyncChangeHandling(String accountSelector, Mailbox...mailboxes) {
+        // Run the parent key analyzer and reload the mailboxes
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        for (Mailbox mailbox: mailboxes) {
+            String serverId = mailbox.mServerId;
+            MailboxUtilities.setFlagsAndChildrensParentKey(mProviderContext, accountSelector,
+                    serverId);
+        }
+    }
+
+    /**
+     * Test three cases of adding a folder to an existing hierarchy.  Case 1:  Add to parent.
+     */
+    public void testParentKeyAddFolder1() {
+        // Set up account and various mailboxes with/without parents
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Run the parent key analyzer to set up the initial hierarchy.
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        // The specific test:  Create a 3rd mailbox and attach it to box1 (already a parent)
+
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box1);
+        box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED;
+        box3.save(mProviderContext);
+        simulateFolderSyncChangeHandling(accountSelector, box1 /*box3's parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(box1.mId, box3.mParentKey);
+    }
+
+    /**
+     * Test three cases of adding a folder to an existing hierarchy.  Case 2:  Add to child.
+     */
+    public void testParentKeyAddFolder2() {
+        // Set up account and various mailboxes with/without parents
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Run the parent key analyzer to set up the initial hierarchy.
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+
+        // Skipping tests of initial hierarchy - see testParentKeyAddFolder1()
+
+        // The specific test:  Create a 3rd mailbox and attach it to box2 (currently a child)
+
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box2);
+        box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED;
+        box3.save(mProviderContext);
+        simulateFolderSyncChangeHandling(accountSelector, box3 /*box3's parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(PARENT_FLAGS, box2.mFlags);    // should become a parent
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);     // should be child of box2
+        assertEquals(box2.mId, box3.mParentKey);
+    }
+
+    /**
+     * Test three cases of adding a folder to an existing hierarchy.  Case 3:  Add to root.
+     */
+    public void testParentKeyAddFolder3() {
+        // Set up account and various mailboxes with/without parents
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Run the parent key analyzer to set up the initial hierarchy.
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+
+        // Skipping tests of initial hierarchy - see testParentKeyAddFolder1()
+
+        // The specific test:  Create a 3rd mailbox and give it no parent (it's top-level).
+
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL);
+        box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED;
+        box3.save(mProviderContext);
+
+        simulateFolderSyncChangeHandling(accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(-1, box3.mParentKey);
+    }
+
+    /**
+     * Test three cases of removing a folder from the hierarchy.  Case 1:  Remove from parent.
+     */
+    public void testParentKeyRemoveFolder1() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has two children.
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(box1.mId, box3.mParentKey);
+
+        // The specific test:  Delete box3 and check remaining configuration
+        mResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), null, null);
+        simulateFolderSyncChangeHandling(accountSelector, box1 /*box3's parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);        // Should still be a parent
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertNull(box3);
+    }
+
+    /**
+     * Test three cases of removing a folder from the hierarchy.  Case 2:  Remove from child.
+     */
+    public void testParentKeyRemoveFolder2() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has box2 and box2 has box3.
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box2);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(PARENT_FLAGS, box2.mFlags);    // becomes a parent
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(box2.mId, box3.mParentKey);
+
+        // The specific test:  Delete box3 and check remaining configuration
+        mResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), null, null);
+        simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);        // Should still be a parent
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);         // Becomes a child
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertNull(box3);
+    }
+
+    /**
+     * Test three cases of removing a folder from the hierarchy.  Case 3:  Remove from root.
+     */
+    public void testParentKeyRemoveFolder3() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has box2, box3 is also at root.
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(-1, box3.mParentKey);
+
+        // The specific test:  Delete box3 and check remaining configuration
+        mResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), null, null);
+        simulateFolderSyncChangeHandling(accountSelector);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);        // Should still be a parent
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);         // Should still be a child
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertNull(box3);
+    }
+
+    /**
+     * Test changing a parent from none
+     */
+    public void testChangeFromNoParentToParent() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has box2, box3 is also at root.
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(-1, box3.mParentKey);
+
+        // The specific test:  Give box 3 a new parent (box 2) and check remaining configuration
+        ContentValues values = new ContentValues();
+        values.put(Mailbox.PARENT_SERVER_ID, box2.mServerId);
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), values,
+                null, null);
+        simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's new parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);        // Should still be a parent
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(PARENT_FLAGS, box2.mFlags);        // Should now be a parent
+        assertEquals(box1.mId, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);         // Should still be a child (of box2)
+        assertEquals(box2.mId, box3.mParentKey);
+    }
+
+    /**
+     * Test changing to no parent from a parent
+     */
+    public void testChangeFromParentToNoParent() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has box2, box3 is also at root.
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(box1.mId, box2.mParentKey);
+
+        // The specific test:  Remove the parent from box2 and check remaining configuration
+        ContentValues values = new ContentValues();
+        values.putNull(Mailbox.PARENT_SERVER_ID);
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2.mId), values,
+                null, null);
+        // Note: FolderSync handling of changed folder would cause parent key to be uninitialized
+        // so we do so here
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2.mId), mNullParentKey,
+                null, null);
+        simulateFolderSyncChangeHandling(accountSelector, box1 /*box2's old parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(CHILD_FLAGS, box1.mFlags);        // Should no longer be a parent
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);        // Should still be a child (no parent)
+        assertEquals(-1, box2.mParentKey);
+    }
+
+    /**
+     * Test a mailbox that has no server id (Hotmail Outbox is an example of this)
+     */
+    public void testNoServerId() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has no serverId, box2 is a child of box1
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL);
+        box1.mServerId = null;
+        box1.save(mProviderContext);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_OUTBOX, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+
+        // Box 1 should be a child, even though it is defined as the parent of box2, because it
+        // has no serverId (presumably, this case can't happen, because a child stores the parent's
+        // serverId, but it's nice to know it's handled properly). Box 1 should have no parent.
+        assertEquals(Mailbox.NO_MAILBOX, box1.mParentKey);
+        assertEquals(CHILD_FLAGS, box1.mFlags);
+        // Box 2 should be a child with no parent (see above).  Since it's an outbox, the flags are
+        // only "holds mail".
+        assertEquals(Mailbox.NO_MAILBOX, box2.mParentKey);
+        assertEquals(Mailbox.FLAG_HOLDS_MAIL, box2.mFlags);
+    }
+
+    /**
+     * Test changing a parent from one mailbox to another
+     */
+    public void testChangeParent() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+
+        // Initial configuration for this test:  box1 has box2, box3 is also at root.
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(-1, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(box1.mId, box3.mParentKey);
+
+        // The specific test:  Give box 3 a new parent (box 2) and check remaining configuration
+        ContentValues values = new ContentValues();
+        values.put(Mailbox.PARENT_SERVER_ID, box2.mServerId);
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), values,
+                null, null);
+        // Changes to old and new parent
+        simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's new parent*/,
+                box1 /*box3's old parent*/);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(CHILD_FLAGS, box1.mFlags);        // Should no longer be a parent
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(PARENT_FLAGS, box2.mFlags);        // Should now be a parent
+        assertEquals(-1, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);         // Should still be a child (of box2)
+        assertEquals(box2.mId, box3.mParentKey);
+    }
+
+
+    /**
+     * Tests the proper separation of two accounts using the methodology from the previous test.
+     * This test will fail if MailboxUtilities fails to distinguish between mailboxes in different
+     * accounts that happen to have the same serverId
+     */
+    public void testChangeParentTwoAccounts() {
+        // Set up account and mailboxes
+        mAccount = setupTestAccount("acct1", true);
+        Account acct2 = setupTestAccount("acct2", true);
+
+        String accountSelector1 = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")";
+        String accountSelector2 = MailboxColumns.ACCOUNT_KEY + " IN (" + acct2.mId + ")";
+
+        // Box3 is in Box1
+        Mailbox box1 = EmailContentSetupUtils.setupMailbox(
+                "box1", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL);
+        box1.mServerId = "1:1";
+        box1.save(mProviderContext);
+        Mailbox box2 = EmailContentSetupUtils.setupMailbox(
+                "box2", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL);
+        box2.mServerId = "1:2";
+        box2.save(mProviderContext);
+        Mailbox box3 = EmailContentSetupUtils.setupMailbox(
+                "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box1);
+        box3.mServerId = "1:3";
+        box3.save(mProviderContext);
+
+        // Box5 is in Box4; Box 6 is in Box5
+        // Note that the three serverId's are identical to those in acct1; we want to make sure
+        // that children get associated only with boxes in their own account
+        Mailbox box4 = EmailContentSetupUtils.setupMailbox(
+                "box4", acct2.mId, false, mProviderContext, Mailbox.TYPE_MAIL, null);
+        box4.mServerId = "1:1";
+        box4.save(mProviderContext);
+        Mailbox box5 = EmailContentSetupUtils.setupMailbox(
+                "box5", acct2.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box4);
+        box5.mServerId = "1:2";
+        box5.save(mProviderContext);
+        Mailbox box6 = EmailContentSetupUtils.setupMailbox(
+                "box6", acct2.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box5);
+        box6.mServerId = "1:3";
+        box6.save(mProviderContext);
+
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+
+        // Confirm initial configuration as expected for mAccount
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector1);
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(-1, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(box1.mId, box3.mParentKey);
+
+        // Confirm initial configuration as expected for acct2
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector2);
+        box4 = Mailbox.restoreMailboxWithId(mProviderContext, box4.mId);
+        box5 = Mailbox.restoreMailboxWithId(mProviderContext, box5.mId);
+        box6 = Mailbox.restoreMailboxWithId(mProviderContext, box6.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(PARENT_FLAGS, box4.mFlags);
+        assertEquals(-1, box4.mParentKey);
+
+        assertEquals(PARENT_FLAGS, box5.mFlags);
+        assertEquals(box4.mId, box5.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box6.mFlags);
+        assertEquals(box5.mId, box6.mParentKey);
+
+        // The specific test:  Change box1 to have a different serverId
+        ContentValues values = new ContentValues();
+        values.put(MailboxColumns.SERVER_ID, "1:4");
+        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1.mId), values,
+                null, null);
+        // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade
+        mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null);
+        // Fix up the parent keys
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector1);
+
+        // Make sure that box1 reflects the change properly AND that other boxes remain correct
+        // The reason for all of the seemingly-duplicated tests is to make sure that the fixup of
+        // any account doesn't end up affecting the other account's mailboxes
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(CHILD_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(-1, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(-1, box3.mParentKey);
+
+        // Fix up the 2nd account now, and check that ALL boxes are correct
+        MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector2);
+
+        box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
+        box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
+        box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId);
+
+        // Confirm flags and parent key(s) as expected
+        assertEquals(CHILD_FLAGS, box1.mFlags);
+        assertEquals(-1, box1.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box2.mFlags);
+        assertEquals(-1, box2.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box3.mFlags);
+        assertEquals(-1, box3.mParentKey);
+
+        box4 = Mailbox.restoreMailboxWithId(mProviderContext, box4.mId);
+        box5 = Mailbox.restoreMailboxWithId(mProviderContext, box5.mId);
+        box6 = Mailbox.restoreMailboxWithId(mProviderContext, box6.mId);
+
+        assertEquals(PARENT_FLAGS, box4.mFlags);
+        assertEquals(-1, box4.mParentKey);
+
+        assertEquals(PARENT_FLAGS, box5.mFlags);
+        assertEquals(box4.mId, box5.mParentKey);
+
+        assertEquals(CHILD_FLAGS, box6.mFlags);
+        assertEquals(box5.mId, box6.mParentKey);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/provider/MockProvider.java b/exchange2/tests/src/com/android/exchange/provider/MockProvider.java
new file mode 100644
index 0000000..177ec55
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/provider/MockProvider.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * MockProvider is a ContentProvider that can be used to simulate the storage and retrieval of
+ * records from any ContentProvider, even if that ContentProvider does not exist in the caller's
+ * package.  It is specifically designed to enable testing of sync adapters that create
+ * ContentProviderOperations (CPOs) that are then executed using ContentResolver.applyBatch()
+ *
+ * Why is this useful?  Because we can't instantiate CalendarProvider or ContactsProvider from our
+ * package, as required by MockContentResolver.addProvider()
+ *
+ * Usage:
+ *     ContentResolver.applyBatch(MockProvider.AUTHORITY, batch) will cause the CPOs to be executed,
+ *     returning an array of ContentProviderResult; in the case of inserts, the result will include
+ *     a Uri that can be used via query().  Note that the CPOs in the batch can contain references
+ *     to any authority.
+ *
+ *     query() does not allow non-null selection, selectionArgs, or sortOrder arguments; the
+ *     presence of these will result in an UnsupportedOperationException
+ *
+ *     insert() acts as expected, returning a Uri that can be directly used in a query
+ *
+ *     delete() and update() do not allow non-null selection or selectionArgs arguments; the
+ *     presence of these will result in an UnsupportedOperationException
+ *
+ *     NOTE: When using any operation other than applyBatch, the Uri to be used must be created
+ *     with MockProvider.uri(yourUri).  This guarantees that the operation is sent to MockProvider
+ *
+ *     NOTE: MockProvider only simulates direct storage/retrieval of rows; it does not (and can not)
+ *     simulate other actions (e.g. creation of ancillary data) that the actual provider might
+ *     perform
+ *
+ *     NOTE: See MockProviderTests for usage examples
+ **/
+public class MockProvider extends ContentProvider {
+    public static final String AUTHORITY = "com.android.exchange.mock.provider";
+    /*package*/ static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    /*package*/ static final int TABLE = 100;
+    /*package*/ static final int RECORD = 101;
+
+    public static final String ID_COLUMN = "_id";
+
+    public MockProvider(Context context) {
+        super(context, null, null, null);
+    }
+
+    public MockProvider() {
+        super();
+    }
+
+    // We'll store our values here
+    private HashMap<String, ContentValues> mMockStore = new HashMap<String, ContentValues>();
+    // And we'll generate new id's from here
+    long mMockId = 1;
+
+    /**
+     * Create a Uri for MockProvider from a given Uri
+     * @param uri the Uri from which the MockProvider Uri will be created
+     * @return a Uri that can be used with MockProvider
+     */
+    public static Uri uri(Uri uri) {
+        return new Uri.Builder().scheme("content").authority(AUTHORITY)
+            .path(uri.getPath().substring(1)).build();
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        if (selection != null || selectionArgs != null) {
+            throw new UnsupportedOperationException();
+        }
+        String path = uri.getPath();
+        if (mMockStore.containsKey(path)) {
+            mMockStore.remove(path);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        // Remove the leading slash
+        String table = uri.getPath().substring(1);
+        long id = mMockId++;
+        Uri newUri = new Uri.Builder().scheme("content").authority(AUTHORITY).path(table)
+            .appendPath(Long.toString(id)).build();
+        // Remember to store the _id
+        values.put(ID_COLUMN, id);
+        mMockStore.put(newUri.getPath(), values);
+        int match = sURIMatcher.match(uri);
+        if (match == UriMatcher.NO_MATCH) {
+            sURIMatcher.addURI(AUTHORITY, table, TABLE);
+            sURIMatcher.addURI(AUTHORITY, table + "/#", RECORD);
+        }
+        return newUri;
+    }
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        if (selection != null || selectionArgs != null || sortOrder != null || projection == null) {
+            throw new UnsupportedOperationException();
+        }
+        final int match = sURIMatcher.match(uri(uri));
+        ArrayList<ContentValues> valuesList = new ArrayList<ContentValues>();
+        switch(match) {
+            case TABLE:
+                Set<Entry<String, ContentValues>> entrySet = mMockStore.entrySet();
+                String prefix = uri.getPath() + "/";
+                for (Entry<String, ContentValues> entry: entrySet) {
+                    if (entry.getKey().startsWith(prefix)) {
+                        valuesList.add(entry.getValue());
+                    }
+                }
+                break;
+            case RECORD:
+                ContentValues values = mMockStore.get(uri.getPath());
+                if (values != null) {
+                    valuesList.add(values);
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+        MatrixCursor cursor = new MatrixCursor(projection, 1);
+        for (ContentValues cv: valuesList) {
+            Object[] rowValues = new Object[projection.length];
+            int i = 0;
+            for (String column: projection) {
+                rowValues[i++] = cv.get(column);
+            }
+            cursor.addRow(rowValues);
+        }
+        return cursor;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues newValues, String selection, String[] selectionArgs) {
+        if (selection != null || selectionArgs != null) {
+            throw new UnsupportedOperationException();
+        }
+        final int match = sURIMatcher.match(uri(uri));
+        ArrayList<ContentValues> updateValuesList = new ArrayList<ContentValues>();
+        String path = uri.getPath();
+        switch(match) {
+            case TABLE:
+                Set<Entry<String, ContentValues>> entrySet = mMockStore.entrySet();
+                String prefix = path + "/";
+                for (Entry<String, ContentValues> entry: entrySet) {
+                    if (entry.getKey().startsWith(prefix)) {
+                        updateValuesList.add(entry.getValue());
+                    }
+                }
+                break;
+            case RECORD:
+                ContentValues cv = mMockStore.get(path);
+                if (cv != null) {
+                    updateValuesList.add(cv);
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+        Set<Entry<String, Object>> newValuesSet = newValues.valueSet();
+        for (Entry<String, Object> entry: newValuesSet) {
+            String key = entry.getKey();
+            Object value = entry.getValue();
+            for (ContentValues targetValues: updateValuesList) {
+                if (value instanceof Integer) {
+                    targetValues.put(key, (Integer)value);
+                } else if (value instanceof Long) {
+                    targetValues.put(key, (Long)value);
+                } else if (value instanceof String) {
+                    targetValues.put(key, (String)value);
+                } else if (value instanceof Boolean) {
+                    targetValues.put(key, (Boolean)value);
+                } else {
+                    throw new IllegalArgumentException();
+                }
+            }
+        }
+        for (ContentValues targetValues: updateValuesList) {
+            mMockStore.put(path + "/" + targetValues.getAsLong(ID_COLUMN), targetValues);
+        }
+        return updateValuesList.size();
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/provider/MockProviderTests.java b/exchange2/tests/src/com/android/exchange/provider/MockProviderTests.java
new file mode 100644
index 0000000..897f0d8
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/provider/MockProviderTests.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.provider;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.test.ProviderTestCase2;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.ArrayList;
+
+/**
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.provider.MockProviderTests exchange
+ */
+@SmallTest
+public class MockProviderTests extends ProviderTestCase2<MockProvider> {
+    Context mMockContext;
+    MockContentResolver mMockResolver;
+
+    private static final String CANHAZ_AUTHORITY = "com.android.canhaz";
+    private static final String PONY_TABLE = "pony";
+    private static final String PONY_COLUMN_NAME = "name";
+    private static final String PONY_COLUMN_TYPE = "type";
+    private static final String PONY_COLUMN_LEGS= "legs";
+    private static final String PONY_COLUMN_CAN_RIDE = "canRide";
+    private static final String[] PONY_PROJECTION = {MockProvider.ID_COLUMN, PONY_COLUMN_NAME,
+        PONY_COLUMN_TYPE, PONY_COLUMN_LEGS, PONY_COLUMN_CAN_RIDE};
+    private static final int PONY_ID = 0;
+    private static final int PONY_NAME = 1;
+    private static final int PONY_TYPE = 2;
+    private static final int PONY_LEGS = 3;
+    private static final int PONY_CAN_RIDE = 4;
+
+    public MockProviderTests() {
+        super(MockProvider.class, MockProvider.AUTHORITY);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mMockContext = getMockContext();
+        mMockResolver = (MockContentResolver)mMockContext.getContentResolver();
+        mMockResolver.addProvider(CANHAZ_AUTHORITY, new MockProvider(mMockContext));
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    private ContentValues ponyValues(String name, String type, int legs, boolean canRide) {
+        ContentValues cv = new ContentValues();
+        cv.put(PONY_COLUMN_NAME, name);
+        cv.put(PONY_COLUMN_TYPE, type);
+        cv.put(PONY_COLUMN_LEGS, legs);
+        cv.put(PONY_COLUMN_CAN_RIDE, canRide ? 1 : 0);
+        return cv;
+    }
+
+    private ContentProviderResult[] setupPonies() throws RemoteException,
+            OperationApplicationException {
+        // The Uri is content://com.android.canhaz/pony
+        Uri uri = new Uri.Builder().scheme("content").authority(CANHAZ_AUTHORITY)
+            .path(PONY_TABLE).build();
+        // Our array of CPO's to be used with applyBatch
+        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+
+        // Insert two ponies
+        ContentValues pony1 = ponyValues("Flicka", "wayward", 4, true);
+        ops.add(ContentProviderOperation.newInsert(uri).withValues(pony1).build());
+        ContentValues pony2 = ponyValues("Elise", "dastardly", 3, false);
+        ops.add(ContentProviderOperation.newInsert(uri).withValues(pony2).build());
+        // Apply the batch with one insert operation
+        return mMockResolver.applyBatch(MockProvider.AUTHORITY, ops);
+    }
+
+    private Uri getPonyUri() {
+        return new Uri.Builder().scheme("content").authority(CANHAZ_AUTHORITY)
+            .path(PONY_TABLE).build();
+    }
+
+    public void testInsertQueryandDelete() throws RemoteException, OperationApplicationException {
+        // The Uri is content://com.android.canhaz/pony
+        ContentProviderResult[] results = setupPonies();
+        Uri uri = getPonyUri();
+
+        // Check the results
+        assertNotNull(results);
+        assertEquals(2, results.length);
+        // Make sure that we've created matcher entries for pony and pony/#
+        assertEquals(MockProvider.TABLE, MockProvider.sURIMatcher.match(MockProvider.uri(uri)));
+        assertEquals(MockProvider.RECORD,
+                MockProvider.sURIMatcher.match(MockProvider.uri(results[0].uri)));
+        Cursor c = mMockResolver.query(MockProvider.uri(uri), PONY_PROJECTION, null, null, null);
+        assertNotNull(c);
+        assertEquals(2, c.getCount());
+        long eliseId = -1;
+        long flickaId = -1;
+        while (c.moveToNext()) {
+            String name = c.getString(PONY_NAME);
+            if ("Flicka".equals(name)) {
+                assertEquals("Flicka", c.getString(PONY_NAME));
+                assertEquals("wayward", c.getString(PONY_TYPE));
+                assertEquals(4, c.getInt(PONY_LEGS));
+                assertEquals(1, c.getInt(PONY_CAN_RIDE));
+                flickaId = c.getLong(PONY_ID);
+            } else if ("Elise".equals(name)) {
+                assertEquals("dastardly", c.getString(PONY_TYPE));
+                assertEquals(3, c.getInt(PONY_LEGS));
+                assertEquals(0, c.getInt(PONY_CAN_RIDE));
+                eliseId = c.getLong(PONY_ID);
+            } else {
+                fail("Wrong record: " + name);
+            }
+        }
+
+        // eliseId and flickaId should have been set
+        assertNotSame(-1, eliseId);
+        assertNotSame(-1, flickaId);
+        // Delete the elise record
+        assertEquals(1, mMockResolver.delete(ContentUris.withAppendedId(MockProvider.uri(uri),
+                eliseId), null, null));
+        c = mMockResolver.query(MockProvider.uri(uri), PONY_PROJECTION, null, null, null);
+        assertNotNull(c);
+        // There should be one left (Flicka)
+        assertEquals(1, c.getCount());
+        assertTrue(c.moveToNext());
+        assertEquals("Flicka", c.getString(PONY_NAME));
+    }
+
+    public void testUpdate() throws RemoteException, OperationApplicationException {
+        // The Uri is content://com.android.canhaz/pony
+        Uri uri = getPonyUri();
+        setupPonies();
+        Cursor c = mMockResolver.query(MockProvider.uri(uri), PONY_PROJECTION, null, null, null);
+        assertNotNull(c);
+        assertEquals(2, c.getCount());
+        // Give all the ponies 5 legs
+        ContentValues cv = new ContentValues();
+        cv.put(PONY_COLUMN_LEGS, 5);
+        assertEquals(2, mMockResolver.update(MockProvider.uri(uri), cv, null, null));
+        c = mMockResolver.query(MockProvider.uri(uri), PONY_PROJECTION, null, null, null);
+        assertNotNull(c);
+        // We should still have two records, and each should have 5 legs, but otherwise be the same
+        assertEquals(2, c.getCount());
+        long eliseId = -1;
+        long flickaId = -1;
+        while (c.moveToNext()) {
+            String name = c.getString(PONY_NAME);
+            if ("Flicka".equals(name)) {
+                assertEquals("Flicka", c.getString(PONY_NAME));
+                assertEquals("wayward", c.getString(PONY_TYPE));
+                assertEquals(5, c.getInt(PONY_LEGS));
+                assertEquals(1, c.getInt(PONY_CAN_RIDE));
+                flickaId = c.getLong(PONY_ID);
+            } else if ("Elise".equals(name)) {
+                assertEquals("dastardly", c.getString(PONY_TYPE));
+                assertEquals(5, c.getInt(PONY_LEGS));
+                assertEquals(0, c.getInt(PONY_CAN_RIDE));
+                eliseId = c.getLong(PONY_ID);
+            } else {
+                fail("Wrong record: " + name);
+            }
+        }
+        // eliseId and flickaId should have been set
+        assertNotSame(-1, eliseId);
+        assertNotSame(-1, flickaId);
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java b/exchange2/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java
new file mode 100644
index 0000000..0ecdb8f
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java
@@ -0,0 +1,1003 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.utility;
+
+import android.content.ContentValues;
+import android.content.Entity;
+import android.content.res.Resources;
+import android.provider.CalendarContract.Attendees;
+import android.provider.CalendarContract.Events;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import com.android.emailcommon.mail.Address;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent.Attachment;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.utility.Utility;
+import com.android.exchange.R;
+import com.android.exchange.adapter.CalendarSyncAdapter;
+import com.android.exchange.adapter.CalendarSyncAdapter.EasCalendarSyncParser;
+import com.android.exchange.adapter.Parser;
+import com.android.exchange.adapter.Serializer;
+import com.android.exchange.adapter.SyncAdapterTestCase;
+import com.android.exchange.adapter.Tags;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.TimeZone;
+
+/**
+ * Tests of EAS Calendar Utilities
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.utility.CalendarUtilitiesTests exchange
+ *
+ * Please see RFC2445 for RRULE definition
+ * http://www.ietf.org/rfc/rfc2445.txt
+ */
+@MediumTest
+public class CalendarUtilitiesTests extends SyncAdapterTestCase<CalendarSyncAdapter> {
+
+    // Some prebuilt time zones, Base64 encoded (as they arrive from EAS)
+    // More time zones to be added over time
+
+    // Not all time zones are appropriate for testing.  For example, ISRAEL_STANDARD_TIME cannot be
+    // used because DST is determined from year to year in a non-standard way (related to the lunar
+    // calendar); therefore, the test would only work during the year in which it was created
+
+    // This time zone has no DST
+    private static final String ASIA_CALCUTTA_TIME =
+        "tv7//0kAbgBkAGkAYQAgAFMAdABhAG4AZABhAHIAZAAgAFQAaQBtAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkAbgBkAGkAYQAgAEQAYQB5AGwAaQBnAGgAdAAgAFQAaQBtAGUA" +
+        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
+
+    // This time zone is equivalent to PST and uses DST
+    private static final String AMERICA_DAWSON_TIME =
+        "4AEAAFAAYQBjAGkAZgBpAGMAIABTAHQAYQBuAGQAYQByAGQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAAsAAAABAAIAAAAAAAAAAAAAAFAAYQBjAGkAZgBpAGMAIABEAGEAeQBsAGkAZwBoAHQAIABUAGkA" +
+        "bQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAACAAIAAAAAAAAAxP///w==";
+
+    // Test a southern hemisphere time zone w/ DST
+    private static final String AUSTRALIA_ACT_TIME =
+        "qP3//0EAVQBTACAARQBhAHMAdABlAHIAbgAgAFMAdABhAG4AZABhAHIAZAAgAFQAaQBtAGUAAAAAAAAAAAAA" +
+        "AAAAAAAAAAQAAAABAAMAAAAAAAAAAAAAAEEAVQBTACAARQBhAHMAdABlAHIAbgAgAEQAYQB5AGwAaQBnAGgA" +
+        "dAAgAFQAaQBtAGUAAAAAAAAAAAAAAAAAAAAAAAoAAAABAAIAAAAAAAAAxP///w==";
+
+    // Test a timezone with GMT bias but bogus DST parameters (there is no equivalent time zone
+    // in the database)
+    private static final String GMT_UNKNOWN_DAYLIGHT_TIME =
+        "AAAAACgARwBNAFQAKwAwADAAOgAwADAAKQAgAFQAaQBtAGUAIABaAG8AbgBlAAAAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAACgARwBNAFQAKwAwADAAOgAwADAAKQAgAFQAaQBtAGUAIABaAG8A" +
+        "bgBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAFAAEAAAAAAAAAxP///w==";
+
+    // This time zone has no DST, but earlier, buggy code retrieved a TZ WITH DST
+    private static final String ARIZONA_TIME =
+        "pAEAAFUAUwAgAE0AbwB1AG4AdABhAGkAbgAgAFMAdABhAG4AZABhAHIAZAAgAFQAaQBtAGUAAAAAAAAAAAAA" +
+        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUAUwAgAE0AbwB1AG4AdABhAGkAbgAgAEQAYQB5AGwAaQBnAGgA" +
+        "dAAgAFQAaQBtAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
+
+    private static final String HAWAII_TIME =
+        "WAIAAEgAYQB3AGEAaQBpAGEAbgAgAFMAdABhAG4AZABhAHIAZAAgAFQAaQBtAGUAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAYQB3AGEAaQBpAGEAbgAgAEQAYQB5AGwAaQBnAGgAdAAgAFQA" +
+        "aQBtAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
+
+    // This is time zone sent by Exchange 2007, apparently; the start time of DST for the eastern
+    // time zone (EST) is off by two hours, which we should correct in our new "lenient" code
+    private static final String LENIENT_EASTERN_TIME =
+        "LAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAAsAAAABAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAACAAAAAAAAAAAAxP///w==";
+
+    private static final String ORGANIZER = "organizer@server.com";
+    private static final String ATTENDEE = "attendee@server.com";
+
+    public void testGetSet() {
+        byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
+
+        // First, check that getWord/Long are properly little endian
+        assertEquals(0x0100, CalendarUtilities.getWord(bytes, 0));
+        assertEquals(0x03020100, CalendarUtilities.getLong(bytes, 0));
+        assertEquals(0x07060504, CalendarUtilities.getLong(bytes, 4));
+
+        // Set some words and longs
+        CalendarUtilities.setWord(bytes, 0, 0xDEAD);
+        CalendarUtilities.setLong(bytes, 2, 0xBEEFBEEF);
+        CalendarUtilities.setWord(bytes, 6, 0xCEDE);
+
+        // Retrieve them
+        assertEquals(0xDEAD, CalendarUtilities.getWord(bytes, 0));
+        assertEquals(0xBEEFBEEF, CalendarUtilities.getLong(bytes, 2));
+        assertEquals(0xCEDE, CalendarUtilities.getWord(bytes, 6));
+    }
+
+    public void testParseTimeZoneEndToEnd() {
+        TimeZone tz = CalendarUtilities.tziStringToTimeZone(AMERICA_DAWSON_TIME);
+        assertEquals("America/Dawson", tz.getID());
+        tz = CalendarUtilities.tziStringToTimeZone(ASIA_CALCUTTA_TIME);
+        assertEquals("Asia/Calcutta", tz.getID());
+        tz = CalendarUtilities.tziStringToTimeZone(AUSTRALIA_ACT_TIME);
+        assertEquals("Australia/ACT", tz.getID());
+
+        // Test peculiar MS sent EST data with and without lenient precision; send standard
+        // precision + 1 (i.e. 1ms) to make sure the code doesn't automatically flip to lenient
+        // when the tz isn't found
+        tz = CalendarUtilities.tziStringToTimeZoneImpl(LENIENT_EASTERN_TIME,
+                CalendarUtilities.STANDARD_DST_PRECISION+1);
+        assertEquals("America/Atikokan", tz.getID());
+        tz = CalendarUtilities.tziStringToTimeZoneImpl(LENIENT_EASTERN_TIME,
+                CalendarUtilities.LENIENT_DST_PRECISION);
+        assertEquals("America/Detroit", tz.getID());
+
+        tz = CalendarUtilities.tziStringToTimeZone(GMT_UNKNOWN_DAYLIGHT_TIME);
+        int bias = tz.getOffset(System.currentTimeMillis());
+        assertEquals(0, bias);
+        // Make sure non-DST TZ's work properly when the tested zone is the default zone
+        TimeZone.setDefault(TimeZone.getTimeZone("America/Phoenix"));
+        tz = CalendarUtilities.tziStringToTimeZone(ARIZONA_TIME);
+        assertEquals("America/Phoenix", tz.getID());
+        TimeZone.setDefault(TimeZone.getTimeZone("Pacific/Honolulu"));
+        tz = CalendarUtilities.tziStringToTimeZone(HAWAII_TIME);
+        assertEquals("Pacific/Honolulu", tz.getID());
+        // Make sure non-DST TZ's get the proper offset and DST status otherwise
+        CalendarUtilities.clearTimeZoneCache();
+        TimeZone azTime = TimeZone.getTimeZone("America/Phoenix");
+        TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+        tz = CalendarUtilities.tziStringToTimeZone(ARIZONA_TIME);
+        assertFalse("America/Phoenix".equals(tz.getID()));
+        assertFalse(tz.useDaylightTime());
+        // It doesn't matter what time is passed in, since neither TZ has dst
+        long now = System.currentTimeMillis();
+        assertEquals(azTime.getOffset(now), tz.getOffset(now));
+    }
+
+    public void testGenerateEasDayOfWeek() {
+        String byDay = "TU,WE,SA";
+        // TU = 4, WE = 8; SA = 64;
+        assertEquals("76", CalendarUtilities.generateEasDayOfWeek(byDay));
+        // MO = 2, TU = 4; WE = 8; TH = 16; FR = 32
+        byDay = "MO,TU,WE,TH,FR";
+        assertEquals("62", CalendarUtilities.generateEasDayOfWeek(byDay));
+        // SU = 1
+        byDay = "SU";
+        assertEquals("1", CalendarUtilities.generateEasDayOfWeek(byDay));
+    }
+
+    public void testTokenFromRrule() {
+        String rrule = "FREQ=DAILY;INTERVAL=1;BYDAY=WE,TH,SA;BYMONTHDAY=17";
+        assertEquals("DAILY", CalendarUtilities.tokenFromRrule(rrule, "FREQ="));
+        assertEquals("1", CalendarUtilities.tokenFromRrule(rrule, "INTERVAL="));
+        assertEquals("17", CalendarUtilities.tokenFromRrule(rrule, "BYMONTHDAY="));
+        assertEquals("WE,TH,SA", CalendarUtilities.tokenFromRrule(rrule, "BYDAY="));
+        assertNull(CalendarUtilities.tokenFromRrule(rrule, "UNTIL="));
+    }
+
+    public void testRecurrenceUntilToEasUntil() {
+        TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+        // Case where local time crosses into next day in GMT
+        assertEquals("20110730T000000Z",
+                CalendarUtilities.recurrenceUntilToEasUntil("20110731T025959Z"));
+        // Case where local time does not cross into next day in GMT
+        assertEquals("20110730T000000Z",
+                CalendarUtilities.recurrenceUntilToEasUntil("20110730T235959Z"));
+    }
+
+    public void testParseEmailDateTimeToMillis(String date) {
+        // Format for email date strings is 2010-02-23T16:00:00.000Z
+        String dateString = "2010-02-23T15:16:17.000Z";
+        long dateTime = Utility.parseEmailDateTimeToMillis(dateString);
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.setTimeInMillis(dateTime);
+        cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+        assertEquals(cal.get(Calendar.YEAR), 2010);
+        assertEquals(cal.get(Calendar.MONTH), 1);  // 0 based
+        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
+        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 16);
+        assertEquals(cal.get(Calendar.MINUTE), 16);
+        assertEquals(cal.get(Calendar.SECOND), 17);
+    }
+
+    public void testParseDateTimeToMillis(String date) {
+        // Format for calendar date strings is 20100223T160000000Z
+        String dateString = "20100223T151617000Z";
+        long dateTime = Utility.parseDateTimeToMillis(dateString);
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.setTimeInMillis(dateTime);
+        cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+        assertEquals(cal.get(Calendar.YEAR), 2010);
+        assertEquals(cal.get(Calendar.MONTH), 1);  // 0 based
+        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
+        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 16);
+        assertEquals(cal.get(Calendar.MINUTE), 16);
+        assertEquals(cal.get(Calendar.SECOND), 17);
+    }
+
+    private Entity setupTestEventEntity(String organizer, String attendee, String title) {
+        // Create an Entity for an Event
+        ContentValues entityValues = new ContentValues();
+        Entity entity = new Entity(entityValues);
+
+        // Set up values for the Event
+        String location = "Meeting Location";
+
+        // Fill in times, location, title, and organizer
+        entityValues.put("DTSTAMP",
+                CalendarUtilities.convertEmailDateTimeToCalendarDateTime("2010-04-05T14:30:51Z"));
+        entityValues.put(Events.DTSTART,
+                Utility.parseEmailDateTimeToMillis("2010-04-12T18:30:00Z"));
+        entityValues.put(Events.DTEND,
+                Utility.parseEmailDateTimeToMillis("2010-04-12T19:30:00Z"));
+        entityValues.put(Events.EVENT_LOCATION, location);
+        entityValues.put(Events.TITLE, title);
+        entityValues.put(Events.ORGANIZER, organizer);
+        entityValues.put(Events.SYNC_DATA2, "31415926535");
+
+        // Add the attendee
+        ContentValues attendeeValues = new ContentValues();
+        attendeeValues.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
+        attendeeValues.put(Attendees.ATTENDEE_EMAIL, attendee);
+        entity.addSubValue(Attendees.CONTENT_URI, attendeeValues);
+
+        // Add the organizer
+        ContentValues organizerValues = new ContentValues();
+        organizerValues.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ORGANIZER);
+        organizerValues.put(Attendees.ATTENDEE_EMAIL, organizer);
+        entity.addSubValue(Attendees.CONTENT_URI, organizerValues);
+        return entity;
+    }
+
+    private Entity setupTestExceptionEntity(String organizer, String attendee, String title) {
+        Entity entity = setupTestEventEntity(organizer, attendee, title);
+        ContentValues entityValues = entity.getEntityValues();
+        entityValues.put(Events.ORIGINAL_SYNC_ID, 69);
+        // The exception will be on April 26th
+        entityValues.put(Events.ORIGINAL_INSTANCE_TIME,
+                Utility.parseEmailDateTimeToMillis("2010-04-26T18:30:00Z"));
+        return entity;
+    }
+
+    public void testCreateMessageForEntity_Reply() {
+        // Set up the "event"
+        String title = "Discuss Unit Tests";
+        Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
+
+        // Create a dummy account for the attendee
+        Account account = new Account();
+        account.mEmailAddress = ATTENDEE;
+
+        // The uid is required, but can be anything
+        String uid = "31415926535";
+
+        // Create the outgoing message
+        Message msg = CalendarUtilities.createMessageForEntity(mContext, entity,
+                Message.FLAG_OUTGOING_MEETING_ACCEPT, uid, account);
+
+        // First, we should have a message
+        assertNotNull(msg);
+
+        // Now check some of the fields of the message
+        assertEquals(Address.pack(new Address[] {new Address(ORGANIZER)}), msg.mTo);
+        Resources resources = getContext().getResources();
+        String accept = resources.getString(R.string.meeting_accepted, title);
+        assertEquals(accept, msg.mSubject);
+        assertNotNull(msg.mText);
+        assertTrue(msg.mText.contains(resources.getString(R.string.meeting_where, "")));
+
+        // And make sure we have an attachment
+        assertNotNull(msg.mAttachments);
+        assertEquals(1, msg.mAttachments.size());
+        Attachment att = msg.mAttachments.get(0);
+        // And that the attachment has the correct elements
+        assertEquals("invite.ics", att.mFileName);
+        assertEquals(Attachment.FLAG_ICS_ALTERNATIVE_PART,
+                att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
+        assertEquals("text/calendar; method=REPLY", att.mMimeType);
+        assertNotNull(att.mContentBytes);
+        assertEquals(att.mSize, att.mContentBytes.length);
+
+        //TODO Check the contents of the attachment using an iCalendar parser
+    }
+
+    public void testCreateMessageForEntity_Invite_AllDay() throws IOException {
+        // Set up the "event"
+        String title = "Discuss Unit Tests";
+        Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
+        ContentValues entityValues = entity.getEntityValues();
+        entityValues.put(Events.ALL_DAY, 1);
+        entityValues.put(Events.DURATION, "P1D");
+        entityValues.remove(Events.DTEND);
+
+        // Create a dummy account for the attendee
+        Account account = new Account();
+        account.mEmailAddress = ORGANIZER;
+
+        // The uid is required, but can be anything
+        String uid = "31415926535";
+
+        // Create the outgoing message
+        Message msg = CalendarUtilities.createMessageForEntity(mContext, entity,
+                Message.FLAG_OUTGOING_MEETING_INVITE, uid, account);
+
+        // First, we should have a message
+        assertNotNull(msg);
+
+        // Now check some of the fields of the message
+        assertEquals(Address.pack(new Address[] {new Address(ATTENDEE)}), msg.mTo);
+        assertEquals(title, msg.mSubject);
+
+        // And make sure we have an attachment
+        assertNotNull(msg.mAttachments);
+        assertEquals(1, msg.mAttachments.size());
+        Attachment att = msg.mAttachments.get(0);
+        // And that the attachment has the correct elements
+        assertEquals("invite.ics", att.mFileName);
+        assertEquals(Attachment.FLAG_ICS_ALTERNATIVE_PART,
+                att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
+        assertEquals("text/calendar; method=REQUEST", att.mMimeType);
+        assertNotNull(att.mContentBytes);
+        assertEquals(att.mSize, att.mContentBytes.length);
+
+        // We'll check the contents of the ics file here
+        BlockHash vcalendar = parseIcsContent(att.mContentBytes);
+        assertNotNull(vcalendar);
+
+        // We should have a VCALENDAR with a REQUEST method
+        assertEquals("VCALENDAR", vcalendar.name);
+        assertEquals("REQUEST", vcalendar.get("METHOD"));
+
+        // We should have one block under VCALENDAR
+        assertEquals(1, vcalendar.blocks.size());
+        BlockHash vevent = vcalendar.blocks.get(0);
+        // It's a VEVENT with the following fields
+        assertEquals("VEVENT", vevent.name);
+        assertEquals("Meeting Location", vevent.get("LOCATION"));
+        assertEquals("0", vevent.get("SEQUENCE"));
+        assertEquals("Discuss Unit Tests", vevent.get("SUMMARY"));
+        assertEquals(uid, vevent.get("UID"));
+        assertEquals("MAILTO:" + ATTENDEE,
+                vevent.get("ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE"));
+
+        // These next two fields should have a date only
+        assertEquals("20100412", vevent.get("DTSTART;VALUE=DATE"));
+        assertEquals("20100413", vevent.get("DTEND;VALUE=DATE"));
+        // This should be set to TRUE for all-day events
+        assertEquals("TRUE", vevent.get("X-MICROSOFT-CDO-ALLDAYEVENT"));
+    }
+
+    public void testCreateMessageForEntity_Invite() throws IOException {
+        // Set up the "event"
+        String title = "Discuss Unit Tests";
+        Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
+
+        // Create a dummy account for the attendee
+        Account account = new Account();
+        account.mEmailAddress = ORGANIZER;
+
+        // The uid is required, but can be anything
+        String uid = "31415926535";
+
+        // Create the outgoing message
+        Message msg = CalendarUtilities.createMessageForEntity(mContext, entity,
+                Message.FLAG_OUTGOING_MEETING_INVITE, uid, account);
+
+        // First, we should have a message
+        assertNotNull(msg);
+
+        // Now check some of the fields of the message
+        assertEquals(Address.pack(new Address[] {new Address(ATTENDEE)}), msg.mTo);
+        assertEquals(title, msg.mSubject);
+
+        // And make sure we have an attachment
+        assertNotNull(msg.mAttachments);
+        assertEquals(1, msg.mAttachments.size());
+        Attachment att = msg.mAttachments.get(0);
+        // And that the attachment has the correct elements
+        assertEquals("invite.ics", att.mFileName);
+        assertEquals(Attachment.FLAG_ICS_ALTERNATIVE_PART,
+                att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
+        assertEquals("text/calendar; method=REQUEST", att.mMimeType);
+        assertNotNull(att.mContentBytes);
+        assertEquals(att.mSize, att.mContentBytes.length);
+
+        // We'll check the contents of the ics file here
+        BlockHash vcalendar = parseIcsContent(att.mContentBytes);
+        assertNotNull(vcalendar);
+
+        // We should have a VCALENDAR with a REQUEST method
+        assertEquals("VCALENDAR", vcalendar.name);
+        assertEquals("REQUEST", vcalendar.get("METHOD"));
+
+        // We should have one block under VCALENDAR
+        assertEquals(1, vcalendar.blocks.size());
+        BlockHash vevent = vcalendar.blocks.get(0);
+        // It's a VEVENT with the following fields
+        assertEquals("VEVENT", vevent.name);
+        assertEquals("Meeting Location", vevent.get("LOCATION"));
+        assertEquals("0", vevent.get("SEQUENCE"));
+        assertEquals("Discuss Unit Tests", vevent.get("SUMMARY"));
+        assertEquals(uid, vevent.get("UID"));
+        assertEquals("MAILTO:" + ATTENDEE,
+                vevent.get("ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE"));
+
+        // These next two fields should exist (without the VALUE=DATE suffix)
+        assertNotNull(vevent.get("DTSTART"));
+        assertNotNull(vevent.get("DTEND"));
+        assertNull(vevent.get("DTSTART;VALUE=DATE"));
+        assertNull(vevent.get("DTEND;VALUE=DATE"));
+        // This shouldn't exist for this event
+        assertNull(vevent.get("X-MICROSOFT-CDO-ALLDAYEVENT"));
+    }
+
+    public void testCreateMessageForEntity_Recurring() throws IOException {
+        // Set up the "event"
+        String title = "Discuss Unit Tests";
+        Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
+        // Set up a RRULE for this event
+        entity.getEntityValues().put(Events.RRULE, "FREQ=DAILY");
+
+        // Create a dummy account for the attendee
+        Account account = new Account();
+        account.mEmailAddress = ORGANIZER;
+
+        // The uid is required, but can be anything
+        String uid = "31415926535";
+
+        // Create the outgoing message
+        Message msg = CalendarUtilities.createMessageForEntity(mContext, entity,
+                Message.FLAG_OUTGOING_MEETING_INVITE, uid, account);
+
+        // First, we should have a message
+        assertNotNull(msg);
+
+        // Now check some of the fields of the message
+        assertEquals(Address.pack(new Address[] {new Address(ATTENDEE)}), msg.mTo);
+        assertEquals(title, msg.mSubject);
+
+        // And make sure we have an attachment
+        assertNotNull(msg.mAttachments);
+        assertEquals(1, msg.mAttachments.size());
+        Attachment att = msg.mAttachments.get(0);
+        // And that the attachment has the correct elements
+        assertEquals("invite.ics", att.mFileName);
+        assertEquals(Attachment.FLAG_ICS_ALTERNATIVE_PART,
+                att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
+        assertEquals("text/calendar; method=REQUEST", att.mMimeType);
+        assertNotNull(att.mContentBytes);
+        assertEquals(att.mSize, att.mContentBytes.length);
+
+        // We'll check the contents of the ics file here
+        BlockHash vcalendar = parseIcsContent(att.mContentBytes);
+        assertNotNull(vcalendar);
+
+        // We should have a VCALENDAR with a REQUEST method
+        assertEquals("VCALENDAR", vcalendar.name);
+        assertEquals("REQUEST", vcalendar.get("METHOD"));
+
+        // We should have two blocks under VCALENDAR (VTIMEZONE and VEVENT)
+        assertEquals(2, vcalendar.blocks.size());
+
+        // This is the time zone that should be used
+        TimeZone timeZone = TimeZone.getDefault();
+
+        BlockHash vtimezone = vcalendar.blocks.get(0);
+        // It should be a VTIMEZONE for timeZone
+        assertEquals("VTIMEZONE", vtimezone.name);
+        assertEquals(timeZone.getID(), vtimezone.get("TZID"));
+
+        BlockHash vevent = vcalendar.blocks.get(1);
+        // It's a VEVENT with the following fields
+        assertEquals("VEVENT", vevent.name);
+        assertEquals("Meeting Location", vevent.get("LOCATION"));
+        assertEquals("0", vevent.get("SEQUENCE"));
+        assertEquals("Discuss Unit Tests", vevent.get("SUMMARY"));
+        assertEquals(uid, vevent.get("UID"));
+        assertEquals("MAILTO:" + ATTENDEE,
+                vevent.get("ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE"));
+
+        // We should have DTSTART/DTEND with time zone
+        assertNotNull(vevent.get("DTSTART;TZID=" + timeZone.getID()));
+        assertNotNull(vevent.get("DTEND;TZID=" + timeZone.getID()));
+        assertNull(vevent.get("DTSTART"));
+        assertNull(vevent.get("DTEND"));
+        assertNull(vevent.get("DTSTART;VALUE=DATE"));
+        assertNull(vevent.get("DTEND;VALUE=DATE"));
+        // This shouldn't exist for this event
+        assertNull(vevent.get("X-MICROSOFT-CDO-ALLDAYEVENT"));
+    }
+
+    public void testCreateMessageForEntity_Exception_Cancel() throws IOException {
+        // Set up the "exception"...
+        String title = "Discuss Unit Tests";
+        Entity entity = setupTestExceptionEntity(ORGANIZER, ATTENDEE, title);
+        
+        ContentValues entityValues = entity.getEntityValues();
+        // Mark the Exception as dirty
+        entityValues.put(Events.DIRTY, 1);
+        // And mark it canceled
+        entityValues.put(Events.STATUS, Events.STATUS_CANCELED);
+
+        // Create a dummy account for the attendee
+        Account account = new Account();
+        account.mEmailAddress = ORGANIZER;
+
+        // The uid is required, but can be anything
+        String uid = "31415926535";
+
+        // Create the outgoing message
+        Message msg = CalendarUtilities.createMessageForEntity(mContext, entity,
+                Message.FLAG_OUTGOING_MEETING_CANCEL, uid, account);
+
+        // First, we should have a message
+        assertNotNull(msg);
+
+        // Now check some of the fields of the message
+        assertEquals(Address.pack(new Address[] {new Address(ATTENDEE)}), msg.mTo);
+        String cancel = getContext().getResources().getString(R.string.meeting_canceled, title);
+        assertEquals(cancel, msg.mSubject);
+
+        // And make sure we have an attachment
+        assertNotNull(msg.mAttachments);
+        assertEquals(1, msg.mAttachments.size());
+        Attachment att = msg.mAttachments.get(0);
+        // And that the attachment has the correct elements
+        assertEquals("invite.ics", att.mFileName);
+        assertEquals(Attachment.FLAG_ICS_ALTERNATIVE_PART,
+                att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
+        assertEquals("text/calendar; method=CANCEL", att.mMimeType);
+        assertNotNull(att.mContentBytes);
+
+        // We'll check the contents of the ics file here
+        BlockHash vcalendar = parseIcsContent(att.mContentBytes);
+        assertNotNull(vcalendar);
+
+        // We should have a VCALENDAR with a CANCEL method
+        assertEquals("VCALENDAR", vcalendar.name);
+        assertEquals("CANCEL", vcalendar.get("METHOD"));
+
+        // This is the time zone that should be used
+        TimeZone timeZone = TimeZone.getDefault();
+
+        // We should have two blocks under VCALENDAR (VTIMEZONE and VEVENT)
+        assertEquals(2, vcalendar.blocks.size());
+
+        BlockHash vtimezone = vcalendar.blocks.get(0);
+        // It should be a VTIMEZONE for timeZone
+        assertEquals("VTIMEZONE", vtimezone.name);
+        assertEquals(timeZone.getID(), vtimezone.get("TZID"));
+
+        BlockHash vevent = vcalendar.blocks.get(1);
+        // It's a VEVENT with the following fields
+        assertEquals("VEVENT", vevent.name);
+        assertEquals("Meeting Location", vevent.get("LOCATION"));
+        assertEquals("0", vevent.get("SEQUENCE"));
+        assertEquals("Discuss Unit Tests", vevent.get("SUMMARY"));
+        assertEquals(uid, vevent.get("UID"));
+        assertEquals("MAILTO:" + ATTENDEE,
+                vevent.get("ATTENDEE;ROLE=REQ-PARTICIPANT"));
+        long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
+        assertNotSame(0, originalTime);
+        // For an exception, RECURRENCE-ID is critical
+        assertEquals(CalendarUtilities.millisToEasDateTime(originalTime, timeZone,
+                true /*withTime*/), vevent.get("RECURRENCE-ID" + ";TZID=" + timeZone.getID()));
+    }
+
+    public void testUtcOffsetString() {
+        assertEquals(CalendarUtilities.utcOffsetString(540), "+0900");
+        assertEquals(CalendarUtilities.utcOffsetString(-480), "-0800");
+        assertEquals(CalendarUtilities.utcOffsetString(0), "+0000");
+    }
+
+    public void testFindTransitionDate() {
+        // We'll find some transitions and make sure that we're properly in or out of daylight time
+        // on either side of the transition.
+        // Use CST for testing (any other will do as well, as long as it has DST)
+        TimeZone tz = TimeZone.getTimeZone("US/Central");
+        // Confirm that this time zone uses DST
+        assertTrue(tz.useDaylightTime());
+        // Get a calendar at January 1st of the current year
+        GregorianCalendar calendar = new GregorianCalendar(tz);
+        calendar.set(CalendarUtilities.sCurrentYear, Calendar.JANUARY, 1);
+        // Get start and end times at start and end of year
+        long startTime = calendar.getTimeInMillis();
+        long endTime = startTime + (365*CalendarUtilities.DAYS);
+        // Find the first transition
+        GregorianCalendar transitionCalendar =
+            CalendarUtilities.findTransitionDate(tz, startTime, endTime, false);
+        long transitionTime = transitionCalendar.getTimeInMillis();
+        // Before should be in standard time; after in daylight time
+        Date beforeDate = new Date(transitionTime - CalendarUtilities.HOURS);
+        Date afterDate = new Date(transitionTime + CalendarUtilities.HOURS);
+        assertFalse(tz.inDaylightTime(beforeDate));
+        assertTrue(tz.inDaylightTime(afterDate));
+
+        // Find the next one...
+        transitionCalendar = CalendarUtilities.findTransitionDate(tz, transitionTime +
+                CalendarUtilities.DAYS, endTime, true);
+        transitionTime = transitionCalendar.getTimeInMillis();
+        // This time, Before should be in daylight time; after in standard time
+        beforeDate = new Date(transitionTime - CalendarUtilities.HOURS);
+        afterDate = new Date(transitionTime + CalendarUtilities.HOURS);
+        assertTrue(tz.inDaylightTime(beforeDate));
+        assertFalse(tz.inDaylightTime(afterDate));
+
+        // Kinshasa has no daylight savings time
+        tz = TimeZone.getTimeZone("Africa/Kinshasa");
+        // Confirm that there's no DST for this time zone
+        assertFalse(tz.useDaylightTime());
+        // Get a calendar at January 1st of the current year
+        calendar = new GregorianCalendar(tz);
+        calendar.set(CalendarUtilities.sCurrentYear, Calendar.JANUARY, 1);
+        // Get start and end times at start and end of year
+        startTime = calendar.getTimeInMillis();
+        endTime = startTime + (365*CalendarUtilities.DAYS);
+        // Find the first transition
+        transitionCalendar = CalendarUtilities.findTransitionDate(tz, startTime, endTime, false);
+        // There had better not be one
+        assertNull(transitionCalendar);
+    }
+
+    public void testRruleFromRecurrence() {
+        // Every Monday for 2 weeks
+        String rrule = CalendarUtilities.rruleFromRecurrence(
+                1 /*Weekly*/, 2 /*Occurrences*/, 1 /*Interval*/, 2 /*Monday*/, 0, 0, 0, null);
+        assertEquals("FREQ=WEEKLY;COUNT=2;INTERVAL=1;BYDAY=MO", rrule);
+        // Every Tuesday and Friday
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                1 /*Weekly*/, 0 /*Occurrences*/, 0 /*Interval*/, 36 /*Tue&Fri*/, 0, 0, 0, null);
+        assertEquals("FREQ=WEEKLY;BYDAY=TU,FR", rrule);
+        // The last Saturday of the month
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                1 /*Weekly*/, 0, 0, 64 /*Sat*/, 0, 5 /*Last*/, 0, null);
+        assertEquals("FREQ=WEEKLY;BYDAY=-1SA", rrule);
+        // The third Wednesday and Thursday of the month
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                1 /*Weekly*/, 0, 0, 24 /*Wed&Thu*/, 0, 3 /*3rd*/, 0, null);
+        assertEquals("FREQ=WEEKLY;BYDAY=3WE,3TH", rrule);
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                3 /*Monthly/Day*/, 0, 0, 127 /*LastDay*/, 0, 0, 0, null);
+        assertEquals("FREQ=MONTHLY;BYMONTHDAY=-1", rrule);
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                3 /*Monthly/Day*/, 0, 0, 62 /*M-F*/, 0, 5 /*Last week*/, 0, null);
+        assertEquals("FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1", rrule);
+        // The 14th of the every month
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                2 /*Monthly/Date*/, 0, 0, 0, 14 /*14th*/, 0, 0, null);
+        assertEquals("FREQ=MONTHLY;BYMONTHDAY=14", rrule);
+        // Every 31st of October
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                5 /*Yearly/Date*/, 0, 0, 0, 31 /*31st*/, 0, 10 /*October*/, null);
+        assertEquals("FREQ=YEARLY;BYMONTHDAY=31;BYMONTH=10", rrule);
+        // The first Tuesday of June
+        rrule = CalendarUtilities.rruleFromRecurrence(
+                6 /*Yearly/Month/DayOfWeek*/, 0, 0, 4 /*Tue*/, 0, 1 /*1st*/, 6 /*June*/, null);
+        assertEquals("FREQ=YEARLY;BYDAY=1TU;BYMONTH=6", rrule);
+    }
+
+    /**
+     * Given a CalendarSyncAdapter and an RRULE, serialize the RRULE via recurrentFromRrule and
+     * then parse the result.  Assert that the resulting RRULE is the same as the original.
+     * @param adapter a CalendarSyncAdapter
+     * @param rrule an RRULE string that will be tested
+     * @throws IOException
+     */
+    private void testSingleRecurrenceFromRrule(CalendarSyncAdapter adapter, String rrule)
+            throws IOException {
+        Serializer s = new Serializer();
+        CalendarUtilities.recurrenceFromRrule(rrule, 0, s);
+        s.done();
+        EasCalendarSyncParser parser = adapter.new EasCalendarSyncParser(
+                new ByteArrayInputStream(s.toByteArray()), adapter);
+        // The first element should be the outer CALENDAR_RECURRENCE tag
+        assertEquals(Tags.CALENDAR_RECURRENCE, parser.nextTag(Parser.START_DOCUMENT));
+        assertEquals(rrule, parser.recurrenceParser());
+    }
+
+    /**
+     * Round-trip test of RRULE handling; we serialize an RRULE and then parse the result; the
+     * result should be identical to the original RRULE
+     */
+    public void testRecurrenceFromRrule() throws IOException {
+        // A test sync adapter we can use throughout the test
+        CalendarSyncAdapter adapter = getTestSyncAdapter(CalendarSyncAdapter.class);
+
+        testSingleRecurrenceFromRrule(adapter, "FREQ=WEEKLY;COUNT=2;INTERVAL=1;BYDAY=MO");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=WEEKLY;BYDAY=TU,FR");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=WEEKLY;BYDAY=-1SA");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=WEEKLY;BYDAY=3WE,3TH");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=MONTHLY;BYMONTHDAY=17");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=YEARLY;BYMONTHDAY=31;BYMONTH=10");
+        testSingleRecurrenceFromRrule(adapter, "FREQ=YEARLY;BYDAY=1TU;BYMONTH=6");
+    }
+
+    /**
+     * For debugging purposes, to help keep track of parsing errors.
+     */
+    private class UnterminatedBlockException extends IOException {
+        private static final long serialVersionUID = 1L;
+        UnterminatedBlockException(String name) {
+            super(name);
+        }
+    }
+
+    /**
+     * A lightweight representation of block object containing a hash of individual values and an
+     * array of inner blocks.  The object is build by pulling elements from a BufferedReader.
+     * NOTE: Multiple values of a given field are not supported.  We'd see this with ATTENDEEs, for
+     * example, and possibly RDATEs in VTIMEZONEs without an RRULE; these cases will be handled
+     * at a later time.
+     */
+    private class BlockHash {
+        String name;
+        HashMap<String, String> hash = new HashMap<String, String>();
+        ArrayList<BlockHash> blocks = new ArrayList<BlockHash>();
+
+        BlockHash (String _name, BufferedReader reader) throws IOException {
+            name = _name;
+            String lastField = null;
+            String lastValue = null;
+            while (true) {
+                // Get a line; we're done if it's null
+                String line = reader.readLine();
+                if (line == null) {
+                    throw new UnterminatedBlockException(name);
+                }
+                int length = line.length();
+                if (length == 0) {
+                    // We shouldn't ever see an empty line
+                    throw new IllegalArgumentException();
+                }
+                // A line starting with tab is a continuation
+                if (line.charAt(0) == '\t') {
+                    // Remember the line and length
+                    lastValue = line.substring(1);
+                    // Save the concatenation of old and new values
+                    hash.put(lastField, hash.get(lastField) + lastValue);
+                    continue;
+                }
+                // Find the field delimiter
+                int pos = line.indexOf(':');
+                // If not found, or at EOL, this is a bad ics
+                if (pos < 0 || pos >= length) {
+                    throw new IllegalArgumentException();
+                }
+                // Remember the field, value, and length
+                lastField = line.substring(0, pos);
+                lastValue = line.substring(pos + 1);
+                if (lastField.equals("BEGIN")) {
+                    blocks.add(new BlockHash(lastValue, reader));
+                    continue;
+                } else if (lastField.equals("END")) {
+                    if (!lastValue.equals(name)) {
+                        throw new UnterminatedBlockException(name);
+                    }
+                    break;
+                }
+
+                // Save it away and continue
+                hash.put(lastField, lastValue);
+            }
+        }
+
+        String get(String field) {
+            return hash.get(field);
+        }
+    }
+
+    private BlockHash parseIcsContent(byte[] bytes) throws IOException {
+        BufferedReader reader = new BufferedReader(new StringReader(Utility.fromUtf8(bytes)));
+        String line = reader.readLine();
+        if (!line.equals("BEGIN:VCALENDAR")) {
+            throw new IllegalArgumentException();
+        }
+        return new BlockHash("VCALENDAR", reader);
+    }
+
+    public void testBuildMessageTextFromEntityValues() {
+        // Set up a test event
+        String title = "Event Title";
+        Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
+        ContentValues entityValues = entity.getEntityValues();
+
+        // Save this away; we'll use it a few times below
+        Resources resources = mContext.getResources();
+        Date date = new Date(entityValues.getAsLong(Events.DTSTART));
+        String dateTimeString = DateFormat.getDateTimeInstance().format(date);
+
+        // Get the text for this message
+        StringBuilder sb = new StringBuilder();
+        CalendarUtilities.buildMessageTextFromEntityValues(mContext, entityValues, sb);
+        String text = sb.toString();
+        // We'll just check the when and where
+        assertTrue(text.contains(resources.getString(R.string.meeting_when, dateTimeString)));
+        String location = entityValues.getAsString(Events.EVENT_LOCATION);
+        assertTrue(text.contains(resources.getString(R.string.meeting_where, location)));
+
+        // Make this event recurring
+        entity.getEntityValues().put(Events.RRULE, "FREQ=WEEKLY;BYDAY=MO");
+        sb = new StringBuilder();
+        CalendarUtilities.buildMessageTextFromEntityValues(mContext, entityValues, sb);
+        text = sb.toString();
+        assertTrue(text.contains(resources.getString(R.string.meeting_recurring, dateTimeString)));
+    }
+
+    /**
+     * Sanity test for time zone generation.  Most important, make sure that we can run through
+     * all of the time zones without generating an exception.  Second, make sure that we're finding
+     * rules for at least 90% of time zones that use daylight time (empirically, it's more like
+     * 95%).  Log those without rules.
+     * @throws IOException
+     */
+    public void testTimeZoneToVTimezone() throws IOException {
+        SimpleIcsWriter writer = new SimpleIcsWriter();
+        int rule = 0;
+        int nodst = 0;
+        int norule = 0;
+        ArrayList<String> norulelist = new ArrayList<String>();
+        for (String tzs: TimeZone.getAvailableIDs()) {
+            TimeZone tz = TimeZone.getTimeZone(tzs);
+            writer = new SimpleIcsWriter();
+            CalendarUtilities.timeZoneToVTimezone(tz, writer);
+            String vc = writer.toString();
+            boolean hasRule = vc.indexOf("RRULE") > 0;
+            if (hasRule) {
+                rule++;
+            } else if (tz.useDaylightTime()) {
+                norule++;
+                norulelist.add(tz.getID());
+            } else {
+                nodst++;
+            }
+        }
+        Log.d("TimeZoneGeneration",
+                "Rule: " + rule + ", No DST: " + nodst + ", No rule: " + norule);
+        for (String nr: norulelist) {
+            Log.d("TimeZoneGeneration", "No rule: " + nr);
+        }
+        // This is an empirical sanity test; we shouldn't have too many time zones with DST and
+        // without a rule.
+        assertTrue(norule < rule/8);
+    }
+
+    public void testGetUidFromGlobalObjId() {
+        // This is a "foreign" uid (from some vCalendar client)
+        String globalObjId = "BAAAAIIA4AB0xbcQGoLgCAAAAAAAAAAAAAAAAAAAAAAAAAAAMQAAA" +
+                "HZDYWwtVWlkAQAAADI3NjU1NmRkLTg1MzAtNGZiZS1iMzE0LThiM2JlYTYwMjE0OQA=";
+        String uid = CalendarUtilities.getUidFromGlobalObjId(globalObjId);
+        assertEquals(uid, "276556dd-8530-4fbe-b314-8b3bea602149");
+        // This is a native EAS uid
+        globalObjId =
+            "BAAAAIIA4AB0xbcQGoLgCAAAAADACTu7KbPKAQAAAAAAAAAAEAAAAObgsG6HVt1Fmy+7GlLbGhY=";
+        uid = CalendarUtilities.getUidFromGlobalObjId(globalObjId);
+        assertEquals(uid, "040000008200E00074C5B7101A82E00800000000C0093BBB29B3CA" +
+                "01000000000000000010000000E6E0B06E8756DD459B2FBB1A52DB1A16");
+    }
+
+    public void testSelfAttendeeStatusFromBusyStatus() {
+        assertEquals(Attendees.ATTENDEE_STATUS_ACCEPTED,
+                CalendarUtilities.attendeeStatusFromBusyStatus(
+                        CalendarUtilities.BUSY_STATUS_BUSY));
+        assertEquals(Attendees.ATTENDEE_STATUS_TENTATIVE,
+                CalendarUtilities.attendeeStatusFromBusyStatus(
+                        CalendarUtilities.BUSY_STATUS_TENTATIVE));
+        assertEquals(Attendees.ATTENDEE_STATUS_NONE,
+                CalendarUtilities.attendeeStatusFromBusyStatus(
+                        CalendarUtilities.BUSY_STATUS_FREE));
+        assertEquals(Attendees.ATTENDEE_STATUS_NONE,
+                CalendarUtilities.attendeeStatusFromBusyStatus(
+                        CalendarUtilities.BUSY_STATUS_OUT_OF_OFFICE));
+    }
+
+    public void testBusyStatusFromSelfStatus() {
+        assertEquals(CalendarUtilities.BUSY_STATUS_FREE,
+                CalendarUtilities.busyStatusFromAttendeeStatus(
+                        Attendees.ATTENDEE_STATUS_DECLINED));
+        assertEquals(CalendarUtilities.BUSY_STATUS_FREE,
+                CalendarUtilities.busyStatusFromAttendeeStatus(
+                        Attendees.ATTENDEE_STATUS_NONE));
+        assertEquals(CalendarUtilities.BUSY_STATUS_FREE,
+                CalendarUtilities.busyStatusFromAttendeeStatus(
+                        Attendees.ATTENDEE_STATUS_INVITED));
+        assertEquals(CalendarUtilities.BUSY_STATUS_TENTATIVE,
+                CalendarUtilities.busyStatusFromAttendeeStatus(
+                        Attendees.ATTENDEE_STATUS_TENTATIVE));
+        assertEquals(CalendarUtilities.BUSY_STATUS_BUSY,
+                CalendarUtilities.busyStatusFromAttendeeStatus(
+                        Attendees.ATTENDEE_STATUS_ACCEPTED));
+    }
+
+    public void testGetUtcAllDayCalendarTime() {
+        GregorianCalendar correctUtc = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+        correctUtc.set(2011, 2, 10, 0, 0, 0);
+        long correctUtcTime = correctUtc.getTimeInMillis();
+
+        TimeZone localTimeZone = TimeZone.getTimeZone("GMT-0700");
+        GregorianCalendar localCalendar = new GregorianCalendar(localTimeZone);
+        localCalendar.set(2011, 2, 10, 12, 23, 34);
+        long localTimeMillis = localCalendar.getTimeInMillis();
+        long convertedUtcTime =
+            CalendarUtilities.getUtcAllDayCalendarTime(localTimeMillis, localTimeZone);
+        // Milliseconds aren't zeroed out and may not be the same
+        assertEquals(convertedUtcTime/1000, correctUtcTime/1000);
+
+        localTimeZone = TimeZone.getTimeZone("GMT+0700");
+        localCalendar = new GregorianCalendar(localTimeZone);
+        localCalendar.set(2011, 2, 10, 12, 23, 34);
+        localTimeMillis = localCalendar.getTimeInMillis();
+        convertedUtcTime =
+            CalendarUtilities.getUtcAllDayCalendarTime(localTimeMillis, localTimeZone);
+        assertEquals(convertedUtcTime/1000, correctUtcTime/1000);
+    }
+
+    public void testGetLocalAllDayCalendarTime() {
+        TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
+        TimeZone localTimeZone = TimeZone.getTimeZone("GMT-0700");
+        GregorianCalendar correctLocal = new GregorianCalendar(localTimeZone);
+        correctLocal.set(2011, 2, 10, 0, 0, 0);
+        long correctLocalTime = correctLocal.getTimeInMillis();
+
+        GregorianCalendar utcCalendar = new GregorianCalendar(utcTimeZone);
+        utcCalendar.set(2011, 2, 10, 12, 23, 34);
+        long utcTimeMillis = utcCalendar.getTimeInMillis();
+        long convertedLocalTime =
+            CalendarUtilities.getLocalAllDayCalendarTime(utcTimeMillis, localTimeZone);
+        // Milliseconds aren't zeroed out and may not be the same
+        assertEquals(convertedLocalTime/1000, correctLocalTime/1000);
+
+        localTimeZone = TimeZone.getTimeZone("GMT+0700");
+        correctLocal = new GregorianCalendar(localTimeZone);
+        correctLocal.set(2011, 2, 10, 0, 0, 0);
+        correctLocalTime = correctLocal.getTimeInMillis();
+
+        utcCalendar = new GregorianCalendar(utcTimeZone);
+        utcCalendar.set(2011, 2, 10, 12, 23, 34);
+        utcTimeMillis = utcCalendar.getTimeInMillis();
+        convertedLocalTime =
+            CalendarUtilities.getLocalAllDayCalendarTime(utcTimeMillis, localTimeZone);
+        // Milliseconds aren't zeroed out and may not be the same
+        assertEquals(convertedLocalTime/1000, correctLocalTime/1000);
+    }
+
+    public void testGetIntegerValueAsBoolean() {
+        ContentValues cv = new ContentValues();
+        cv.put("A", 1);
+        cv.put("B", 69);
+        cv.put("C", 0);
+        assertTrue(CalendarUtilities.getIntegerValueAsBoolean(cv, "A"));
+        assertTrue(CalendarUtilities.getIntegerValueAsBoolean(cv, "B"));
+        assertFalse(CalendarUtilities.getIntegerValueAsBoolean(cv, "C"));
+        assertFalse(CalendarUtilities.getIntegerValueAsBoolean(cv, "D"));
+    }
+}
+
+    // TODO Planned unit tests
+    // findNextTransition
+    // recurrenceFromRrule
+    // timeZoneToTziStringImpl
+    // getDSTCalendars
+    // millisToVCalendarTime
+    // millisToEasDateTime
+    // getTrueTransitionMinute
+    // getTrueTransitionHour
+
diff --git a/exchange2/tests/src/com/android/exchange/utility/ExchangeTestCase.java b/exchange2/tests/src/com/android/exchange/utility/ExchangeTestCase.java
new file mode 100644
index 0000000..86ea0c5
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/utility/ExchangeTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.utility;
+
+import com.android.emailcommon.provider.Account;
+import com.android.exchange.provider.EmailContentSetupUtils;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+
+public abstract class ExchangeTestCase extends AndroidTestCase {
+    private final ArrayList<Long> mCreatedAccountIds = new ArrayList<Long>();
+    protected Context mProviderContext;
+    
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mContext = getContext();
+        // Could use MockContext here if we switch over
+        mProviderContext = mContext;
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        ContentResolver resolver = mProviderContext.getContentResolver();
+        for (Long accountId: mCreatedAccountIds) {
+            resolver.delete(ContentUris.withAppendedId(Account.CONTENT_URI, accountId), null,
+                    null);
+        }
+    }
+
+    /**
+     * Add an account to our list of test accounts; we'll delete it automatically in tearDown()
+     * @param account the account to be added to our list of test accounts
+     */
+    protected void addTestAccount(Account account) {
+        if (account.mId > 0) {
+            mCreatedAccountIds.add(account.mId);
+        }
+    }
+    
+    /**
+     * Create a test account that will be automatically deleted when the test is finished
+     * @param name the name of the account
+     * @param saveIt whether or not to save the account in EmailProvider
+     * @return the account created
+     */
+    protected Account setupTestAccount(String name, boolean saveIt) {
+        Account account = EmailContentSetupUtils.setupAccount(name, saveIt, mProviderContext);
+        addTestAccount(account);
+        return account;
+    }
+}
diff --git a/exchange2/tests/src/com/android/exchange/utility/SimpleIcsWriterTests.java b/exchange2/tests/src/com/android/exchange/utility/SimpleIcsWriterTests.java
new file mode 100644
index 0000000..94c53b7
--- /dev/null
+++ b/exchange2/tests/src/com/android/exchange/utility/SimpleIcsWriterTests.java
@@ -0,0 +1,115 @@
+/* Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange.utility;
+
+import com.android.emailcommon.utility.Utility;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for {@link SimpleIcsWriter}.
+ * You can run this entire test case with:
+ *   runtest -c com.android.exchange.utility.SimpleIcsWriterTests exchange
+ */
+@SmallTest
+public class SimpleIcsWriterTests extends TestCase {
+    private static final String CRLF = "\r\n";
+    private static final String UTF8_1_BYTE = "a";
+    private static final String UTF8_2_BYTES = "\u00A2";
+    private static final String UTF8_3_BYTES = "\u20AC";
+    private static final String UTF8_4_BYTES = "\uD852\uDF62";
+
+    /**
+     * Test for {@link SimpleIcsWriter#writeTag}.  It also covers {@link SimpleIcsWriter#getBytes()}
+     * and {@link SimpleIcsWriter#escapeTextValue}.
+     */
+    public void testWriteTag() {
+        final SimpleIcsWriter ics = new SimpleIcsWriter();
+        ics.writeTag("TAG1", null);
+        ics.writeTag("TAG2", "");
+        ics.writeTag("TAG3", "xyz");
+        ics.writeTag("SUMMARY", "TEST-TEST,;\r\n\\TEST");
+        ics.writeTag("SUMMARY2", "TEST-TEST,;\r\n\\TEST");
+        final String actual = Utility.fromUtf8(ics.getBytes());
+
+        assertEquals(
+                "TAG3:xyz" + CRLF +
+                "SUMMARY:TEST-TEST\\,\\;\\n\\\\TEST" + CRLF + // escaped
+                "SUMMARY2:TEST-TEST,;\r\n\\TEST" + CRLF // not escaped
+                , actual);
+    }
+
+    /**
+     * Verify that: We're folding lines correctly, and we're not splitting up a UTF-8 character.
+     */
+    public void testWriteLine() {
+        for (String last : new String[] {UTF8_1_BYTE, UTF8_2_BYTES, UTF8_3_BYTES, UTF8_4_BYTES}) {
+            for (int i = 70; i < 160; i++) {
+                String input = stringOfLength(i) + last;
+                checkWriteLine(input);
+            }
+        }
+    }
+
+    /**
+     * @return a String of {@code length} bytes in UTF-8.
+     */
+    private static String stringOfLength(int length) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < length; i++) {
+            sb.append('0' +(i % 10));
+        }
+        return sb.toString();
+    }
+
+    private void checkWriteLine(String input) {
+        final SimpleIcsWriter ics = new SimpleIcsWriter();
+        ics.writeLine(input);
+        final byte[] bytes = ics.getBytes();
+
+        // Verify that no lines are longer than 75 bytes.
+        int numBytes = 0;
+        for (byte b : bytes) {
+            if (b == '\r') {
+                continue; // ignore
+            }
+            if (b == '\n') {
+                assertTrue("input=" + input, numBytes <= 75);
+                numBytes = 0;
+                continue;
+            }
+            numBytes++;
+        }
+        assertTrue("input=" + input, numBytes <= 75);
+
+        // If we're splitting up a UTF-8 character, fromUtf8() won't restore it correctly.
+        // If it becomes the same as input, we're doing the right thing.
+        final String actual = Utility.fromUtf8(bytes);
+        final String unfolded = actual.replace("\r\n\t", "");
+        assertEquals("input=" + input, input + "\r\n", unfolded);
+    }
+
+    public void testQuoteParamValue() {
+        assertNull(SimpleIcsWriter.quoteParamValue(null));
+        assertEquals("\"\"", SimpleIcsWriter.quoteParamValue(""));
+        assertEquals("\"a\"", SimpleIcsWriter.quoteParamValue("a"));
+        assertEquals("\"''\"", SimpleIcsWriter.quoteParamValue("\"'"));
+        assertEquals("\"abc\"", SimpleIcsWriter.quoteParamValue("abc"));
+        assertEquals("\"a'b'c\"", SimpleIcsWriter.quoteParamValue("a\"b\"c"));
+    }
+}
diff --git a/src/com/android/exchange/EasOutboxService.java b/src/com/android/exchange/EasOutboxService.java
index 9ff1ffc..4466925 100644
--- a/src/com/android/exchange/EasOutboxService.java
+++ b/src/com/android/exchange/EasOutboxService.java
@@ -80,7 +80,7 @@
     // failure would probably generate an Exception before timing out anyway
     public static final int SEND_MAIL_TIMEOUT = 15*MINUTES;
 
-    protected EasOutboxService(Context _context, Mailbox _mailbox) {
+    public EasOutboxService(Context _context, Mailbox _mailbox) {
         super(_context, _mailbox);
     }
 
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index f1e544d..148a348 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -28,6 +28,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.provider.CalendarContract.Attendees;
 import android.provider.CalendarContract.Events;
 import android.text.TextUtils;
@@ -42,6 +43,8 @@
 import com.android.emailcommon.mail.PackedString;
 import com.android.emailcommon.provider.Account;
 import com.android.emailcommon.provider.EmailContent.AccountColumns;
+import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
+import com.android.emailcommon.provider.EmailContent.MailboxColumns;
 import com.android.emailcommon.provider.EmailContent.Message;
 import com.android.emailcommon.provider.EmailContent.MessageColumns;
 import com.android.emailcommon.provider.EmailContent.SyncColumns;
@@ -52,7 +55,6 @@
 import com.android.emailcommon.service.EmailServiceConstants;
 import com.android.emailcommon.service.EmailServiceProxy;
 import com.android.emailcommon.service.EmailServiceStatus;
-import com.android.emailcommon.service.PolicyServiceProxy;
 import com.android.emailcommon.utility.EmailClientConnectionManager;
 import com.android.emailcommon.utility.Utility;
 import com.android.exchange.CommandStatusException.CommandStatus;
@@ -66,12 +68,15 @@
 import com.android.exchange.adapter.GalParser;
 import com.android.exchange.adapter.MeetingResponseParser;
 import com.android.exchange.adapter.MoveItemsParser;
+import com.android.exchange.adapter.Parser.EasParserException;
 import com.android.exchange.adapter.Parser.EmptyStreamException;
+import com.android.exchange.adapter.PingParser;
 import com.android.exchange.adapter.ProvisionParser;
 import com.android.exchange.adapter.Serializer;
 import com.android.exchange.adapter.SettingsParser;
 import com.android.exchange.adapter.Tags;
 import com.android.exchange.provider.GalResult;
+import com.android.exchange.provider.MailboxUtilities;
 import com.android.exchange.utility.CalendarUtilities;
 import com.google.common.annotations.VisibleForTesting;
 
@@ -100,12 +105,27 @@
 import java.lang.Thread.State;
 import java.net.URI;
 import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.HashMap;
 
 public class EasSyncService extends AbstractSyncService {
     // DO NOT CHECK IN SET TO TRUE
     public static final boolean DEBUG_GAL_SERVICE = false;
 
-    protected static final String PING_COMMAND = "Ping";
+    private static final String WHERE_ACCOUNT_KEY_AND_SERVER_ID =
+        MailboxColumns.ACCOUNT_KEY + "=? and " + MailboxColumns.SERVER_ID + "=?";
+    private static final String WHERE_ACCOUNT_AND_SYNC_INTERVAL_PING =
+        MailboxColumns.ACCOUNT_KEY + "=? and " + MailboxColumns.SYNC_INTERVAL +
+        '=' + Mailbox.CHECK_INTERVAL_PING;
+    private static final String AND_FREQUENCY_PING_PUSH_AND_NOT_ACCOUNT_MAILBOX = " AND " +
+        MailboxColumns.SYNC_INTERVAL + " IN (" + Mailbox.CHECK_INTERVAL_PING +
+        ',' + Mailbox.CHECK_INTERVAL_PUSH + ") AND " + MailboxColumns.TYPE + "!=\"" +
+        Mailbox.TYPE_EAS_ACCOUNT_MAILBOX + '\"';
+    private static final String WHERE_PUSH_HOLD_NOT_ACCOUNT_MAILBOX =
+        MailboxColumns.ACCOUNT_KEY + "=? and " + MailboxColumns.SYNC_INTERVAL +
+        '=' + Mailbox.CHECK_INTERVAL_PUSH_HOLD;
+
+    static private final String PING_COMMAND = "Ping";
     // Command timeout is the the time allowed for reading data from an open connection before an
     // IOException is thrown.  After a small added allowance, our watchdog alarm goes off (allowing
     // us to detect a silently dropped connection).  The allowance is defined below.
@@ -115,10 +135,17 @@
     // The extra time allowed beyond the COMMAND_TIMEOUT before which our watchdog alarm triggers
     static private final int WATCHDOG_TIMEOUT_ALLOWANCE = 30*SECONDS;
 
+    // The amount of time the account mailbox will sleep if there are no pingable mailboxes
+    // This could happen if the sync time is set to "never"; we always want to check in from time
+    // to time, however, for folder list/policy changes
+    static private final int ACCOUNT_MAILBOX_SLEEP_TIME = 20*MINUTES;
+    static private final String ACCOUNT_MAILBOX_SLEEP_TEXT =
+        "Account mailbox sleeping for " + (ACCOUNT_MAILBOX_SLEEP_TIME / MINUTES) + "m";
+
     static private final String AUTO_DISCOVER_SCHEMA_PREFIX =
         "http://schemas.microsoft.com/exchange/autodiscover/mobilesync/";
     static private final String AUTO_DISCOVER_PAGE = "/autodiscover/autodiscover.xml";
-    static protected final int EAS_REDIRECT_CODE = 451;
+    static private final int EAS_REDIRECT_CODE = 451;
 
     static public final int INTERNAL_SERVER_ERROR_CODE = 500;
 
@@ -126,21 +153,47 @@
     static public final String EAS_2_POLICY_TYPE = "MS-WAP-Provisioning-XML";
 
     static public final int MESSAGE_FLAG_MOVED_MESSAGE = 1 << Message.FLAG_SYNC_ADAPTER_SHIFT;
+
+    /**
+     * We start with an 8 minute timeout, and increase/decrease by 3 minutes at a time.  There's
+     * no point having a timeout shorter than 5 minutes, I think; at that point, we can just let
+     * the ping exception out.  The maximum I use is 17 minutes, which is really an empirical
+     * choice; too long and we risk silent connection loss and loss of push for that period.  Too
+     * short and we lose efficiency/battery life.
+     *
+     * If we ever have to drop the ping timeout, we'll never increase it again.  There's no point
+     * going into hysteresis; the NAT timeout isn't going to change without a change in connection,
+     * which will cause the sync service to be restarted at the starting heartbeat and going through
+     * the process again.
+     */
+    static private final int PING_MINUTES = 60; // in seconds
+    static private final int PING_FUDGE_LOW = 10;
+    static private final int PING_STARTING_HEARTBEAT = (8*PING_MINUTES)-PING_FUDGE_LOW;
+    static private final int PING_HEARTBEAT_INCREMENT = 3*PING_MINUTES;
+
+    // Maximum number of times we'll allow a sync to "loop" with MoreAvailable true before
+    // forcing it to stop.  This number has been determined empirically.
+    static private final int MAX_LOOPING_COUNT = 100;
+
+    static private final int PROTOCOL_PING_STATUS_COMPLETED = 1;
+
     // The amount of time we allow for a thread to release its post lock after receiving an alert
     static private final int POST_LOCK_TIMEOUT = 10*SECONDS;
 
+    // Fallbacks (in minutes) for ping loop failures
+    static private final int MAX_PING_FAILURES = 1;
+    static private final int PING_FALLBACK_INBOX = 5;
+    static private final int PING_FALLBACK_PIM = 25;
+
     // The EAS protocol Provision status for "we implement all of the policies"
     static private final String PROVISION_STATUS_OK = "1";
     // The EAS protocol Provision status meaning "we partially implement the policies"
     static private final String PROVISION_STATUS_PARTIAL = "2";
 
     static /*package*/ final String DEVICE_TYPE = "Android";
-    static final String USER_AGENT = DEVICE_TYPE + '/' + Build.VERSION.RELEASE + '-' +
+    static private final String USER_AGENT = DEVICE_TYPE + '/' + Build.VERSION.RELEASE + '-' +
         Eas.CLIENT_VERSION;
 
-    // Maximum number of times we'll allow a sync to "loop" with MoreAvailable true before
-    // forcing it to stop.  This number has been determined empirically.
-    static private final int MAX_LOOPING_COUNT = 100;
     // Reasonable default
     public String mProtocolVersion = Eas.DEFAULT_PROTOCOL_VERSION;
     public Double mProtocolVersionDouble;
@@ -155,26 +208,39 @@
     public String mUserName;
     public String mPassword;
 
-    // The HttpPost in progress
-    private volatile HttpPost mPendingPost = null;
-    // Whether a POST was aborted due to alarm (watchdog alarm)
-    protected boolean mPostAborted = false;
-    // Whether a POST was aborted due to reset
-    protected boolean mPostReset = false;
-
     // The parameters for the connection must be modified through setConnectionParameters
     private boolean mSsl = true;
     private boolean mTrustSsl = false;
     private String mClientCertAlias = null;
 
     public ContentResolver mContentResolver;
+    private final String[] mBindArguments = new String[2];
+    private ArrayList<String> mPingChangeList;
+    // The HttpPost in progress
+    private volatile HttpPost mPendingPost = null;
+    // Our heartbeat when we are waiting for ping boxes to be ready
+    /*package*/ int mPingForceHeartbeat = 2*PING_MINUTES;
+    // The minimum heartbeat we will send
+    /*package*/ int mPingMinHeartbeat = (5*PING_MINUTES)-PING_FUDGE_LOW;
+    // The maximum heartbeat we will send
+    /*package*/ int mPingMaxHeartbeat = (17*PING_MINUTES)-PING_FUDGE_LOW;
+    // The ping time (in seconds)
+    /*package*/ int mPingHeartbeat = PING_STARTING_HEARTBEAT;
+    // The longest successful ping heartbeat
+    private int mPingHighWaterMark = 0;
+    // Whether we've ever lowered the heartbeat
+    /*package*/ boolean mPingHeartbeatDropped = false;
+    // Whether a POST was aborted due to alarm (watchdog alarm)
+    private boolean mPostAborted = false;
+    // Whether a POST was aborted due to reset
+    private boolean mPostReset = false;
     // Whether or not the sync service is valid (usable)
     public boolean mIsValid = true;
 
     // Whether the most recent upsync failed (status 7)
     public boolean mUpsyncFailed = false;
 
-    protected EasSyncService(Context _context, Mailbox _mailbox) {
+    public EasSyncService(Context _context, Mailbox _mailbox) {
         super(_context, _mailbox);
         mContentResolver = _context.getContentResolver();
         if (mAccount == null) {
@@ -198,17 +264,6 @@
         this("EAS Validation");
     }
 
-    public static EasSyncService getServiceForMailbox(Context context, Mailbox m) {
-        switch(m.mType) {
-            case Mailbox.TYPE_EAS_ACCOUNT_MAILBOX:
-                return new EasAccountService(context, m);
-            case Mailbox.TYPE_OUTBOX:
-                return new EasOutboxService(context, m);
-            default:
-                return new EasSyncService(context, m);
-        }
-    }
-
     /**
      * Try to wake up a sync thread that is waiting on an HttpClient POST and has waited past its
      * socket timeout without having thrown an Exception
@@ -311,7 +366,7 @@
         super.addRequest(request);
     }
 
-    void setupProtocolVersion(EasSyncService service, Header versionHeader)
+    private void setupProtocolVersion(EasSyncService service, Header versionHeader)
             throws MessagingException {
         // The string is a comma separated list of EAS versions in ascending order
         // e.g. 1.0,2.0,2.5,12.0,12.1,14.0,14.1
@@ -407,7 +462,7 @@
      * @param hostAuth the HostAuth we're using to validate
      * @return true if we have an updated HostAuth (with redirect address); false otherwise
      */
-    protected boolean getValidateRedirect(EasResponse resp, HostAuth hostAuth) {
+    private boolean getValidateRedirect(EasResponse resp, HostAuth hostAuth) {
         Header locHeader = resp.getHeader("X-MS-Location");
         if (locHeader != null) {
             String loc;
@@ -541,7 +596,7 @@
                 int status = e.mStatus;
                 if (CommandStatus.isNeedsProvisioning(status)) {
                     // Get the policies and see if we are able to support them
-                    ProvisionParser pp = canProvision(this);
+                    ProvisionParser pp = canProvision();
                     if (pp != null && pp.hasSupportablePolicySet()) {
                         // Set the proper result code and save the PolicySet in our Bundle
                         resultCode = MessagingException.SECURITY_POLICIES_REQUIRED;
@@ -554,12 +609,12 @@
                                 resultCode = MessagingException.ACCESS_DENIED;
                             }
                         }
-                    } else {
+                    } else
                         // If not, set the proper code (the account will not be created)
                         resultCode = MessagingException.SECURITY_POLICIES_UNSUPPORTED;
-                        bundle.putParcelable(EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET,
-                                pp.getPolicy());
-                    }
+                        bundle.putStringArray(
+                                EmailServiceProxy.VALIDATE_BUNDLE_UNSUPPORTED_POLICIES,
+                                ((pp == null) ? null : pp.getUnsupportedPolicies()));
                 } else if (CommandStatus.isDeniedAccess(status)) {
                     userLog("Denied access: ", CommandStatus.toString(status));
                     resultCode = MessagingException.ACCESS_DENIED;
@@ -661,17 +716,6 @@
     }
 
     /**
-     * Convert an EAS server url to a HostAuth host address
-     * @param url a url, as provided by the Exchange server
-     * @return our equivalent host address
-     */
-    protected String autodiscoverUrlToHostAddress(String url) {
-        if (url == null) return null;
-        // We need to extract the server address from a url
-        return Uri.parse(url).getHost();
-    }
-
-    /**
      * Use the Exchange 2007 AutoDiscover feature to try to retrieve server information using
      * only an email address and the password
      *
@@ -821,11 +865,14 @@
                         mobileSync = true;
                     }
                 } else if (mobileSync && name.equals("Url")) {
-                    String hostAddress =
-                        autodiscoverUrlToHostAddress(parser.nextText());
-                    if (hostAddress != null) {
-                        hostAuth.mAddress = hostAddress;
-                        userLog("Autodiscover, server: " + hostAddress);
+                    String url = parser.nextText().toLowerCase();
+                    // This will look like https://<server address>/Microsoft-Server-ActiveSync
+                    // We need to extract the <server address>
+                    if (url.startsWith("https://") &&
+                            url.endsWith("/microsoft-server-activesync")) {
+                        int lastSlash = url.lastIndexOf('/');
+                        hostAuth.mAddress = url.substring(8, lastSlash);
+                        userLog("Autodiscover, server: " + hostAuth.mAddress);
                     }
                 }
             }
@@ -1256,6 +1303,9 @@
 
     protected EasResponse sendPing(byte[] bytes, int heartbeat) throws IOException {
        Thread.currentThread().setName(mAccount.mDisplayName + ": Ping");
+       if (Eas.USER_LOG) {
+           userLog("Send ping, timeout: " + heartbeat + "s, high: " + mPingHighWaterMark + 's');
+       }
        return sendHttpClientPost(PING_COMMAND, new ByteArrayEntity(bytes), (heartbeat+5)*SECONDS);
     }
 
@@ -1351,7 +1401,7 @@
         return EasResponse.fromHttpRequest(getClientConnectionManager(), client, method);
     }
 
-    String getTargetCollectionClassFromCursor(Cursor c) {
+    private String getTargetCollectionClassFromCursor(Cursor c) {
         int type = c.getInt(Mailbox.CONTENT_TYPE_COLUMN);
         if (type == Mailbox.TYPE_CONTACTS) {
             return "Contacts";
@@ -1371,77 +1421,88 @@
      * @return whether or not provisioning has been successful
      * @throws IOException
      */
-    public static boolean tryProvision(EasSyncService svc) throws IOException {
+    private boolean tryProvision() throws IOException {
         // First, see if provisioning is even possible, i.e. do we support the policies required
         // by the server
-        ProvisionParser pp = canProvision(svc);
-        if (pp == null) return false;
-        Context context = svc.mContext;
-        Account account = svc.mAccount;
-        // Get the policies from ProvisionParser
-        Policy policy = pp.getPolicy();
-        Policy oldPolicy = null;
-        // Grab the old policy (if any)
-        if (svc.mAccount.mPolicyKey > 0) {
-            oldPolicy = Policy.restorePolicyWithId(context, account.mPolicyKey);
-        }
-        // Update the account with a null policyKey (the key we've gotten is
-        // temporary and cannot be used for syncing)
-        PolicyServiceProxy.setAccountPolicy(context, account.mId, policy, null);
-        // Make sure mAccount is current (with latest policy key)
-        account.refresh(context);
-        if (pp.getRemoteWipe()) {
-            // We've gotten a remote wipe command
-            ExchangeService.alwaysLog("!!! Remote wipe request received");
-            // Start by setting the account to security hold
-            PolicyServiceProxy.setAccountHoldFlag(context, account, true);
-            // Force a stop to any running syncs for this account (except this one)
-            ExchangeService.stopNonAccountMailboxSyncsForAccount(account.mId);
+        ProvisionParser pp = canProvision();
+        if (pp != null && pp.hasSupportablePolicySet()) {
+            // Get the policies from ProvisionParser
+            Policy policy = pp.getPolicy();
+            Policy oldPolicy = null;
+            // Grab the old policy (if any)
+            if (mAccount.mPolicyKey > 0) {
+                oldPolicy = Policy.restorePolicyWithId(mContext, mAccount.mPolicyKey);
+            }
+            // Update the account with a null policyKey (the key we've gotten is
+            // temporary and cannot be used for syncing)
+            Policy.setAccountPolicy(mContext, mAccount, policy, null);
+            // Make sure mAccount is current (with latest policy key)
+            mAccount.refresh(mContext);
+            // Make sure that SecurityPolicy is up-to-date
+            SecurityPolicyDelegate.policiesUpdated(mContext, mAccount.mId);
+            if (pp.getRemoteWipe()) {
+                // We've gotten a remote wipe command
+                ExchangeService.alwaysLog("!!! Remote wipe request received");
+                // Start by setting the account to security hold
+                SecurityPolicyDelegate.setAccountHoldFlag(mContext, mAccount, true);
+                // Force a stop to any running syncs for this account (except this one)
+                ExchangeService.stopNonAccountMailboxSyncsForAccount(mAccount.mId);
 
-            // First, we've got to acknowledge it, but wrap the wipe in try/catch so that
-            // we wipe the device regardless of any errors in acknowledgment
-            try {
-                ExchangeService.alwaysLog("!!! Acknowledging remote wipe to server");
-                acknowledgeRemoteWipe(svc, pp.getSecuritySyncKey());
-            } catch (Exception e) {
-                // Because remote wipe is such a high priority task, we don't want to
-                // circumvent it if there's an exception in acknowledgment
-            }
-            // Then, tell SecurityPolicy to wipe the device
-            ExchangeService.alwaysLog("!!! Executing remote wipe");
-            PolicyServiceProxy.remoteWipe(context);
-            return false;
-        } else if (pp.hasSupportablePolicySet() && PolicyServiceProxy.isActive(context, policy)) {
-            // See if the required policies are in force; if they are, acknowledge the policies
-            // to the server and get the final policy key
-            // NOTE: For EAS 14.0, we already have the acknowledgment in the ProvisionParser
-            String securitySyncKey;
-            if (svc.mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
-                securitySyncKey = pp.getSecuritySyncKey();
-            } else {
-                securitySyncKey = acknowledgeProvision(svc, pp.getSecuritySyncKey(),
-                        PROVISION_STATUS_OK);
-            }
-            if (securitySyncKey != null) {
-                // If attachment policies have changed, fix up any affected attachment records
-                if (oldPolicy != null) {
-                    if ((oldPolicy.mDontAllowAttachments != policy.mDontAllowAttachments) ||
-                            (oldPolicy.mMaxAttachmentSize != policy.mMaxAttachmentSize)) {
-                        Policy.setAttachmentFlagsForNewPolicy(context, account, policy);
-                    }
+                // If we're not the admin, we can't do the wipe, so just return
+                if (!SecurityPolicyDelegate.isActiveAdmin(mContext)) {
+                    ExchangeService.alwaysLog("!!! Not device admin; can't wipe");
+                    return false;
                 }
-                // Write the final policy key to the Account and say we've been successful
-                PolicyServiceProxy.setAccountPolicy(context, account.mId, policy, securitySyncKey);
-                // Release any mailboxes that might be in a security hold
-                ExchangeService.releaseSecurityHold(account);
-                return true;
+
+                // First, we've got to acknowledge it, but wrap the wipe in try/catch so that
+                // we wipe the device regardless of any errors in acknowledgment
+                try {
+                    ExchangeService.alwaysLog("!!! Acknowledging remote wipe to server");
+                    acknowledgeRemoteWipe(pp.getSecuritySyncKey());
+                } catch (Exception e) {
+                    // Because remote wipe is such a high priority task, we don't want to
+                    // circumvent it if there's an exception in acknowledgment
+                }
+                // Then, tell SecurityPolicy to wipe the device
+                ExchangeService.alwaysLog("!!! Executing remote wipe");
+                SecurityPolicyDelegate.remoteWipe(mContext);
+                return false;
+            } else if (SecurityPolicyDelegate.isActive(mContext, policy)) {
+                // See if the required policies are in force; if they are, acknowledge the policies
+                // to the server and get the final policy key
+                // NOTE: For EAS 14.0, we already have the acknowledgment in the ProvisionParser
+                String securitySyncKey;
+                if (mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
+                    securitySyncKey = pp.getSecuritySyncKey();
+                } else {
+                    securitySyncKey = acknowledgeProvision(pp.getSecuritySyncKey(),
+                            PROVISION_STATUS_OK);
+                }
+                if (securitySyncKey != null) {
+                    // If attachment policies have changed, fix up any affected attachment records
+                    if (oldPolicy != null) {
+                        if ((oldPolicy.mDontAllowAttachments != policy.mDontAllowAttachments) ||
+                                (oldPolicy.mMaxAttachmentSize != policy.mMaxAttachmentSize)) {
+                            Policy.setAttachmentFlagsForNewPolicy(mContext, mAccount, policy);
+                        }
+                    }
+                    // Write the final policy key to the Account and say we've been successful
+                    Policy.setAccountPolicy(mContext, mAccount, policy, securitySyncKey);
+                    // Release any mailboxes that might be in a security hold
+                    ExchangeService.releaseSecurityHold(mAccount);
+                    return true;
+                }
+            } else {
+                // Notify that we are blocked because of policies
+                // TODO: Indicate unsupported policies here?
+                SecurityPolicyDelegate.policiesRequired(mContext, mAccount.mId);
             }
         }
         return false;
     }
 
-    private static String getPolicyType(Double protocolVersion) {
-        return (protocolVersion >=
+    private String getPolicyType() {
+        return (mProtocolVersionDouble >=
             Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) ? EAS_12_POLICY_TYPE : EAS_2_POLICY_TYPE;
     }
 
@@ -1451,11 +1512,10 @@
      * @return the ProvisionParser (holds policies and key) if we receive policies; null otherwise
      * @throws IOException
      */
-    public static ProvisionParser canProvision(EasSyncService svc) throws IOException {
+    private ProvisionParser canProvision() throws IOException {
         Serializer s = new Serializer();
-        Double protocolVersion = svc.mProtocolVersionDouble;
         s.start(Tags.PROVISION_PROVISION);
-        if (svc.mProtocolVersionDouble >= Eas.SUPPORTED_PROTOCOL_EX2010_SP1_DOUBLE) {
+        if (mProtocolVersionDouble >= Eas.SUPPORTED_PROTOCOL_EX2010_SP1_DOUBLE) {
             // Send settings information in 14.1 and greater
             s.start(Tags.SETTINGS_DEVICE_INFORMATION).start(Tags.SETTINGS_SET);
             s.data(Tags.SETTINGS_MODEL, Build.MODEL);
@@ -1465,27 +1525,27 @@
             //s.data(Tags.SETTINGS_OS_LANGUAGE, "");
             //s.data(Tags.SETTINGS_PHONE_NUMBER, "");
             //s.data(Tags.SETTINGS_MOBILE_OPERATOR, "");
-            s.data(Tags.SETTINGS_USER_AGENT, EasSyncService.USER_AGENT);
+            s.data(Tags.SETTINGS_USER_AGENT, USER_AGENT);
             s.end().end();  // SETTINGS_SET, SETTINGS_DEVICE_INFORMATION
         }
         s.start(Tags.PROVISION_POLICIES);
-        s.start(Tags.PROVISION_POLICY);
-        s.data(Tags.PROVISION_POLICY_TYPE, getPolicyType(protocolVersion));
-        s.end().end().end().done(); // PROVISION_POLICY, PROVISION_POLICIES, PROVISION_PROVISION
-        EasResponse resp = svc.sendHttpClientPost("Provision", s.toByteArray());
+        s.start(Tags.PROVISION_POLICY).data(Tags.PROVISION_POLICY_TYPE, getPolicyType()).end();
+        s.end();  // PROVISION_POLICIES
+        s.end().done(); // PROVISION_PROVISION
+        EasResponse resp = sendHttpClientPost("Provision", s.toByteArray());
         try {
             int code = resp.getStatus();
             if (code == HttpStatus.SC_OK) {
                 InputStream is = resp.getInputStream();
-                ProvisionParser pp = new ProvisionParser(is, svc);
+                ProvisionParser pp = new ProvisionParser(is, this);
                 if (pp.parse()) {
                     // The PolicySet in the ProvisionParser will have the requirements for all KNOWN
                     // policies.  If others are required, hasSupportablePolicySet will be false
                     if (pp.hasSupportablePolicySet() &&
-                            svc.mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
+                            mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
                         // In EAS 14.0, we need the final security key in order to use the settings
                         // command
-                        String policyKey = acknowledgeProvision(svc, pp.getSecuritySyncKey(),
+                        String policyKey = acknowledgeProvision(pp.getSecuritySyncKey(),
                                 PROVISION_STATUS_OK);
                         if (policyKey != null) {
                             pp.setSecuritySyncKey(policyKey);
@@ -1495,11 +1555,11 @@
                         // accommodate the required policies).  The server will agree to this if the
                         // "allow non-provisionable devices" setting is enabled on the server
                         ExchangeService.log("PolicySet is NOT fully supportable");
-                        if (acknowledgeProvision(svc, pp.getSecuritySyncKey(),
-                                PROVISION_STATUS_PARTIAL) != null) {
-                            // The server's ok with our inability to support policies, so we'll
-                            // clear them
-                            pp.clearUnsupportablePolicies();
+                        String policyKey = acknowledgeProvision(pp.getSecuritySyncKey(),
+                                PROVISION_STATUS_PARTIAL);
+                        // Return either the parser (success) or null (failure)
+                        if (policyKey != null) {
+                            pp.clearUnsupportedPolicies();
                         }
                     }
                     return pp;
@@ -1520,24 +1580,22 @@
      * @return the final policy key, which can be used for syncing
      * @throws IOException
      */
-    private static void acknowledgeRemoteWipe(EasSyncService svc, String tempKey)
-            throws IOException {
-        acknowledgeProvisionImpl(svc, tempKey, PROVISION_STATUS_OK, true);
+    private void acknowledgeRemoteWipe(String tempKey) throws IOException {
+        acknowledgeProvisionImpl(tempKey, PROVISION_STATUS_OK, true);
     }
 
-    private static String acknowledgeProvision(EasSyncService svc, String tempKey, String result)
-            throws IOException {
-        return acknowledgeProvisionImpl(svc, tempKey, result, false);
+    private String acknowledgeProvision(String tempKey, String result) throws IOException {
+        return acknowledgeProvisionImpl(tempKey, result, false);
     }
 
-    private static String acknowledgeProvisionImpl(EasSyncService svc, String tempKey,
-            String status, boolean remoteWipe) throws IOException {
+    private String acknowledgeProvisionImpl(String tempKey, String status,
+            boolean remoteWipe) throws IOException {
         Serializer s = new Serializer();
         s.start(Tags.PROVISION_PROVISION).start(Tags.PROVISION_POLICIES);
         s.start(Tags.PROVISION_POLICY);
 
         // Use the proper policy type, depending on EAS version
-        s.data(Tags.PROVISION_POLICY_TYPE, getPolicyType(svc.mProtocolVersionDouble));
+        s.data(Tags.PROVISION_POLICY_TYPE, getPolicyType());
 
         s.data(Tags.PROVISION_POLICY_KEY, tempKey);
         s.data(Tags.PROVISION_STATUS, status);
@@ -1548,16 +1606,15 @@
             s.end();
         }
         s.end().done(); // PROVISION_PROVISION
-        EasResponse resp = svc.sendHttpClientPost("Provision", s.toByteArray());
+        EasResponse resp = sendHttpClientPost("Provision", s.toByteArray());
         try {
             int code = resp.getStatus();
             if (code == HttpStatus.SC_OK) {
                 InputStream is = resp.getInputStream();
-                ProvisionParser pp = new ProvisionParser(is, svc);
+                ProvisionParser pp = new ProvisionParser(is, this);
                 if (pp.parse()) {
                     // Return the final policy key from the ProvisionParser
-                    String result = (pp.getSecuritySyncKey() == null) ? "failed" : "confirmed";
-                    ExchangeService.log("Provision " + result + " for " +
+                    ExchangeService.log("Provision confirmation received for " +
                             (PROVISION_STATUS_PARTIAL.equals(status) ? "PART" : "FULL") + " set");
                     return pp.getSecuritySyncKey();
                 }
@@ -1566,7 +1623,7 @@
             resp.close();
         }
         // On failures, log issue and return null
-        ExchangeService.log("Provisioning failed for" +
+        ExchangeService.log("Provision confirmation failed for" +
                 (PROVISION_STATUS_PARTIAL.equals(status) ? "PART" : "FULL") + " set");
         return null;
     }
@@ -1595,7 +1652,662 @@
     }
 
     /**
+     * Translate exit status code to service status code (used in callbacks)
+     * @param exitStatus the service's exit status
+     * @return the corresponding service status
+     */
+    private int exitStatusToServiceStatus(int exitStatus) {
+        switch(exitStatus) {
+            case EXIT_SECURITY_FAILURE:
+                return EmailServiceStatus.SECURITY_FAILURE;
+            case EXIT_LOGIN_FAILURE:
+                return EmailServiceStatus.LOGIN_FAILED;
+            default:
+                return EmailServiceStatus.SUCCESS;
+        }
+    }
+
+    /**
+     * If possible, update the account to the new server address; report result
+     * @param resp the EasResponse from the current POST
+     * @return whether or not the redirect is handled and the POST should be retried
+     */
+    private boolean canHandleAccountMailboxRedirect(EasResponse resp) {
+        userLog("AccountMailbox redirect error");
+        HostAuth ha =
+                HostAuth.restoreHostAuthWithId(mContext, mAccount.mHostAuthKeyRecv);
+        if (ha != null && getValidateRedirect(resp, ha)) {
+            // Update the account's HostAuth with new values
+            ContentValues haValues = new ContentValues();
+            haValues.put(HostAuthColumns.ADDRESS, ha.mAddress);
+            ha.update(mContext, haValues);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Performs FolderSync
+     *
+     * @throws IOException
+     * @throws EasParserException
+     */
+    public void runAccountMailbox() throws IOException, EasParserException {
+        // Check that the account's mailboxes are consistent
+        MailboxUtilities.checkMailboxConsistency(mContext, mAccount.mId);
+        // Initialize exit status to success
+        mExitStatus = EXIT_DONE;
+        try {
+            try {
+                ExchangeService.callback()
+                    .syncMailboxListStatus(mAccount.mId, EmailServiceStatus.IN_PROGRESS, 0);
+            } catch (RemoteException e1) {
+                // Don't care if this fails
+            }
+
+            if (mAccount.mSyncKey == null) {
+                mAccount.mSyncKey = "0";
+                userLog("Account syncKey INIT to 0");
+                ContentValues cv = new ContentValues();
+                cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
+                mAccount.update(mContext, cv);
+            }
+
+            boolean firstSync = mAccount.mSyncKey.equals("0");
+            if (firstSync) {
+                userLog("Initial FolderSync");
+            }
+
+            // When we first start up, change all mailboxes to push.
+            ContentValues cv = new ContentValues();
+            cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
+            if (mContentResolver.update(Mailbox.CONTENT_URI, cv,
+                    WHERE_ACCOUNT_AND_SYNC_INTERVAL_PING,
+                    new String[] {Long.toString(mAccount.mId)}) > 0) {
+                ExchangeService.kick("change ping boxes to push");
+            }
+
+            // Determine our protocol version, if we haven't already and save it in the Account
+            // Also re-check protocol version at least once a day (in case of upgrade)
+            if (mAccount.mProtocolVersion == null || firstSync ||
+                   ((System.currentTimeMillis() - mMailbox.mSyncTime) > DAYS)) {
+                userLog("Determine EAS protocol version");
+                EasResponse resp = sendHttpClientOptions();
+                try {
+                    int code = resp.getStatus();
+                    userLog("OPTIONS response: ", code);
+                    if (code == HttpStatus.SC_OK) {
+                        Header header = resp.getHeader("MS-ASProtocolCommands");
+                        userLog(header.getValue());
+                        header = resp.getHeader("ms-asprotocolversions");
+                        try {
+                            setupProtocolVersion(this, header);
+                        } catch (MessagingException e) {
+                            // Since we've already validated, this can't really happen
+                            // But if it does, we'll rethrow this...
+                            throw new IOException();
+                        }
+                        // Save the protocol version
+                        cv.clear();
+                        // Save the protocol version in the account; if we're using 12.0 or greater,
+                        // set the flag for support of SmartForward
+                        cv.put(Account.PROTOCOL_VERSION, mProtocolVersion);
+                        mAccount.update(mContext, cv);
+                        cv.clear();
+                        // Save the sync time of the account mailbox to current time
+                        cv.put(Mailbox.SYNC_TIME, System.currentTimeMillis());
+                        mMailbox.update(mContext, cv);
+                    } else if (code == EAS_REDIRECT_CODE && canHandleAccountMailboxRedirect(resp)) {
+                        // Cause this to re-run
+                        throw new IOException("Will retry after a brief hold...");
+                    } else {
+                        errorLog("OPTIONS command failed; throwing IOException");
+                        throw new IOException();
+                    }
+                } finally {
+                    resp.close();
+                }
+            }
+
+            // Make sure we've upgraded flags for ICS if we're using v12.0 or later
+            if (mProtocolVersionDouble >= 12.0 &&
+                    (mAccount.mFlags & Account.FLAGS_SUPPORTS_SEARCH) == 0) {
+                cv.clear();
+                mAccount.mFlags = mAccount.mFlags | Account.FLAGS_SUPPORTS_SMART_FORWARD |
+                        Account.FLAGS_SUPPORTS_SEARCH | Account.FLAGS_SUPPORTS_GLOBAL_SEARCH;
+                cv.put(AccountColumns.FLAGS, mAccount.mFlags);
+                mAccount.update(mContext, cv);
+            }
+
+            // Change all pushable boxes to push when we start the account mailbox
+            if (mAccount.mSyncInterval == Account.CHECK_INTERVAL_PUSH) {
+                cv.clear();
+                cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
+                if (mContentResolver.update(Mailbox.CONTENT_URI, cv,
+                        ExchangeService.WHERE_IN_ACCOUNT_AND_PUSHABLE,
+                        new String[] {Long.toString(mAccount.mId)}) > 0) {
+                    userLog("Push account; set pushable boxes to push...");
+                }
+            }
+
+            while (!mStop) {
+                // If we're not allowed to sync (e.g. roaming policy), leave now
+                if (!ExchangeService.canAutoSync(mAccount)) return;
+                userLog("Sending Account syncKey: ", mAccount.mSyncKey);
+                Serializer s = new Serializer();
+                s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY)
+                    .text(mAccount.mSyncKey).end().end().done();
+                EasResponse resp = sendHttpClientPost("FolderSync", s.toByteArray());
+                try {
+                    if (mStop) break;
+                    int code = resp.getStatus();
+                    if (code == HttpStatus.SC_OK) {
+                        if (!resp.isEmpty()) {
+                            InputStream is = resp.getInputStream();
+                            // Returns true if we need to sync again
+                            if (new FolderSyncParser(is, new AccountSyncAdapter(this)).parse()) {
+                                continue;
+                            }
+                        }
+                    } else if (EasResponse.isProvisionError(code)) {
+                        userLog("FolderSync provisioning error: ", code);
+                        throw new CommandStatusException(CommandStatus.NEEDS_PROVISIONING);
+                    } else if (EasResponse.isAuthError(code)) {
+                        userLog("FolderSync auth error: ", code);
+                        mExitStatus = EXIT_LOGIN_FAILURE;
+                        return;
+                    } else if (code == EAS_REDIRECT_CODE && canHandleAccountMailboxRedirect(resp)) {
+                        // This will cause a retry of the FolderSync
+                        continue;
+                    } else {
+                        userLog("FolderSync response error: ", code);
+                    }
+                } finally {
+                    resp.close();
+                }
+
+                // Change all push/hold boxes to push
+                cv.clear();
+                cv.put(Mailbox.SYNC_INTERVAL, Account.CHECK_INTERVAL_PUSH);
+                if (mContentResolver.update(Mailbox.CONTENT_URI, cv,
+                        WHERE_PUSH_HOLD_NOT_ACCOUNT_MAILBOX,
+                        new String[] {Long.toString(mAccount.mId)}) > 0) {
+                    userLog("Set push/hold boxes to push...");
+                }
+
+                try {
+                    ExchangeService.callback()
+                        .syncMailboxListStatus(mAccount.mId, exitStatusToServiceStatus(mExitStatus),
+                                0);
+                } catch (RemoteException e1) {
+                    // Don't care if this fails
+                }
+
+                // Before each run of the pingLoop, if this Account has a PolicySet, make sure it's
+                // active; otherwise, clear out the key/flag.  This should cause a provisioning
+                // error on the next POST, and start the security sequence over again
+                String key = mAccount.mSecuritySyncKey;
+                if (!TextUtils.isEmpty(key)) {
+                    Policy policy = Policy.restorePolicyWithId(mContext, mAccount.mPolicyKey);
+                    if ((policy != null) && !SecurityPolicyDelegate.isActive(mContext, policy)) {
+                        resetSecurityPolicies();
+                    }
+                }
+
+                // Wait for push notifications.
+                String threadName = Thread.currentThread().getName();
+                try {
+                    runPingLoop();
+                } catch (StaleFolderListException e) {
+                    // We break out if we get told about a stale folder list
+                    userLog("Ping interrupted; folder list requires sync...");
+                } catch (IllegalHeartbeatException e) {
+                    // If we're sending an illegal heartbeat, reset either the min or the max to
+                    // that heartbeat
+                    resetHeartbeats(e.mLegalHeartbeat);
+                } finally {
+                    Thread.currentThread().setName(threadName);
+                }
+            }
+        } catch (CommandStatusException e) {
+            // If the sync error is a provisioning failure (perhaps policies changed),
+            // let's try the provisioning procedure
+            // Provisioning must only be attempted for the account mailbox - trying to
+            // provision any other mailbox may result in race conditions and the
+            // creation of multiple policy keys.
+            int status = e.mStatus;
+            if (CommandStatus.isNeedsProvisioning(status)) {
+                if (!tryProvision()) {
+                    // Set the appropriate failure status
+                    mExitStatus = EXIT_SECURITY_FAILURE;
+                    return;
+                }
+            } else if (CommandStatus.isDeniedAccess(status)) {
+                mExitStatus = EXIT_ACCESS_DENIED;
+                try {
+                    ExchangeService.callback().syncMailboxListStatus(mAccount.mId,
+                            EmailServiceStatus.ACCESS_DENIED, 0);
+                } catch (RemoteException e1) {
+                    // Don't care if this fails
+                }
+                return;
+            } else {
+                userLog("Unexpected status: " + CommandStatus.toString(status));
+                mExitStatus = EXIT_EXCEPTION;
+            }
+        } catch (IOException e) {
+            // We catch this here to send the folder sync status callback
+            // A folder sync failed callback will get sent from run()
+            try {
+                if (!mStop) {
+                    // NOTE: The correct status is CONNECTION_ERROR, but the UI displays this, and
+                    // it's not really appropriate for EAS as this is not unexpected for a ping and
+                    // connection errors are retried in any case
+                    ExchangeService.callback()
+                        .syncMailboxListStatus(mAccount.mId, EmailServiceStatus.SUCCESS, 0);
+                }
+            } catch (RemoteException e1) {
+                // Don't care if this fails
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Reset either our minimum or maximum ping heartbeat to a heartbeat known to be legal
+     * @param legalHeartbeat a known legal heartbeat (from the EAS server)
+     */
+    /*package*/ void resetHeartbeats(int legalHeartbeat) {
+        userLog("Resetting min/max heartbeat, legal = " + legalHeartbeat);
+        // We are here because the current heartbeat (mPingHeartbeat) is invalid.  Depending on
+        // whether the argument is above or below the current heartbeat, we can infer the need to
+        // change either the minimum or maximum heartbeat
+        if (legalHeartbeat > mPingHeartbeat) {
+            // The legal heartbeat is higher than the ping heartbeat; therefore, our minimum was
+            // too low.  We respond by raising either or both of the minimum heartbeat or the
+            // force heartbeat to the argument value
+            if (mPingMinHeartbeat < legalHeartbeat) {
+                mPingMinHeartbeat = legalHeartbeat;
+            }
+            if (mPingForceHeartbeat < legalHeartbeat) {
+                mPingForceHeartbeat = legalHeartbeat;
+            }
+            // If our minimum is now greater than the max, bring them together
+            if (mPingMinHeartbeat > mPingMaxHeartbeat) {
+                mPingMaxHeartbeat = legalHeartbeat;
+            }
+        } else if (legalHeartbeat < mPingHeartbeat) {
+            // The legal heartbeat is lower than the ping heartbeat; therefore, our maximum was
+            // too high.  We respond by lowering the maximum to the argument value
+            mPingMaxHeartbeat = legalHeartbeat;
+            // If our maximum is now less than the minimum, bring them together
+            if (mPingMaxHeartbeat < mPingMinHeartbeat) {
+                mPingMinHeartbeat = legalHeartbeat;
+            }
+        }
+        // Set current heartbeat to the legal heartbeat
+        mPingHeartbeat = legalHeartbeat;
+        // Allow the heartbeat logic to run
+        mPingHeartbeatDropped = false;
+    }
+
+    private void pushFallback(long mailboxId) {
+        Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mailboxId);
+        if (mailbox == null) {
+            return;
+        }
+        ContentValues cv = new ContentValues();
+        int mins = PING_FALLBACK_PIM;
+        if (mailbox.mType == Mailbox.TYPE_INBOX) {
+            mins = PING_FALLBACK_INBOX;
+        }
+        cv.put(Mailbox.SYNC_INTERVAL, mins);
+        mContentResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId),
+                cv, null, null);
+        errorLog("*** PING ERROR LOOP: Set " + mailbox.mDisplayName + " to " + mins + " min sync");
+        ExchangeService.kick("push fallback");
+    }
+
+    /**
+     * Simplistic attempt to determine a NAT timeout, based on experience with various carriers
+     * and networks.  The string "reset by peer" is very common in these situations, so we look for
+     * that specifically.  We may add additional tests here as more is learned.
+     * @param message
+     * @return whether this message is likely associated with a NAT failure
+     */
+    private boolean isLikelyNatFailure(String message) {
+        if (message == null) return false;
+        if (message.contains("reset by peer")) {
+            return true;
+        }
+        return false;
+    }
+
+    private void runPingLoop() throws IOException, StaleFolderListException,
+            IllegalHeartbeatException, CommandStatusException {
+        int pingHeartbeat = mPingHeartbeat;
+        userLog("runPingLoop");
+        // Do push for all sync services here
+        long endTime = System.currentTimeMillis() + (30*MINUTES);
+        HashMap<String, Integer> pingErrorMap = new HashMap<String, Integer>();
+        ArrayList<String> readyMailboxes = new ArrayList<String>();
+        ArrayList<String> notReadyMailboxes = new ArrayList<String>();
+        int pingWaitCount = 0;
+        long inboxId = -1;
+
+        while ((System.currentTimeMillis() < endTime) && !mStop) {
+            // Count of pushable mailboxes
+            int pushCount = 0;
+            // Count of mailboxes that can be pushed right now
+            int canPushCount = 0;
+            // Count of uninitialized boxes
+            int uninitCount = 0;
+
+            Serializer s = new Serializer();
+            Cursor c = mContentResolver.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
+                    MailboxColumns.ACCOUNT_KEY + '=' + mAccount.mId +
+                    AND_FREQUENCY_PING_PUSH_AND_NOT_ACCOUNT_MAILBOX, null, null);
+            if (c == null) throw new ProviderUnavailableException();
+            notReadyMailboxes.clear();
+            readyMailboxes.clear();
+            // Look for an inbox, and remember its id
+            if (inboxId == -1) {
+                inboxId = Mailbox.findMailboxOfType(mContext, mAccount.mId, Mailbox.TYPE_INBOX);
+            }
+            try {
+                // Loop through our pushed boxes seeing what is available to push
+                while (c.moveToNext()) {
+                    pushCount++;
+                    // Two requirements for push:
+                    // 1) ExchangeService tells us the mailbox is syncable (not running/not stopped)
+                    // 2) The syncKey isn't "0" (i.e. it's synced at least once)
+                    long mailboxId = c.getLong(Mailbox.CONTENT_ID_COLUMN);
+                    int pingStatus = ExchangeService.pingStatus(mailboxId);
+                    String mailboxName = c.getString(Mailbox.CONTENT_DISPLAY_NAME_COLUMN);
+                    if (pingStatus == ExchangeService.PING_STATUS_OK) {
+                        String syncKey = c.getString(Mailbox.CONTENT_SYNC_KEY_COLUMN);
+                        if ((syncKey == null) || syncKey.equals("0")) {
+                            // We can't push until the initial sync is done
+                            pushCount--;
+                            uninitCount++;
+                            continue;
+                        }
+
+                        if (canPushCount++ == 0) {
+                            // Initialize the Ping command
+                            s.start(Tags.PING_PING)
+                                .data(Tags.PING_HEARTBEAT_INTERVAL,
+                                        Integer.toString(pingHeartbeat))
+                                .start(Tags.PING_FOLDERS);
+                        }
+
+                        String folderClass = getTargetCollectionClassFromCursor(c);
+                        s.start(Tags.PING_FOLDER)
+                            .data(Tags.PING_ID, c.getString(Mailbox.CONTENT_SERVER_ID_COLUMN))
+                            .data(Tags.PING_CLASS, folderClass)
+                            .end();
+                        readyMailboxes.add(mailboxName);
+                    } else if ((pingStatus == ExchangeService.PING_STATUS_RUNNING) ||
+                            (pingStatus == ExchangeService.PING_STATUS_WAITING)) {
+                        notReadyMailboxes.add(mailboxName);
+                    } else if (pingStatus == ExchangeService.PING_STATUS_UNABLE) {
+                        pushCount--;
+                        userLog(mailboxName, " in error state; ignore");
+                        continue;
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            if (Eas.USER_LOG) {
+                if (!notReadyMailboxes.isEmpty()) {
+                    userLog("Ping not ready for: " + notReadyMailboxes);
+                }
+                if (!readyMailboxes.isEmpty()) {
+                    userLog("Ping ready for: " + readyMailboxes);
+                }
+            }
+
+            // If we've waited 10 seconds or more, just ping with whatever boxes are ready
+            // But use a shorter than normal heartbeat
+            boolean forcePing = !notReadyMailboxes.isEmpty() && (pingWaitCount > 5);
+
+            if ((canPushCount > 0) && ((canPushCount == pushCount) || forcePing)) {
+                // If all pingable boxes are ready for push, send Ping to the server
+                s.end().end().done();
+                pingWaitCount = 0;
+                mPostReset = false;
+                mPostAborted = false;
+
+                // If we've been stopped, this is a good time to return
+                if (mStop) return;
+
+                long pingTime = SystemClock.elapsedRealtime();
+                try {
+                    // Send the ping, wrapped by appropriate timeout/alarm
+                    if (forcePing) {
+                        userLog("Forcing ping after waiting for all boxes to be ready");
+                    }
+                    EasResponse resp =
+                        sendPing(s.toByteArray(), forcePing ? mPingForceHeartbeat : pingHeartbeat);
+
+                    try {
+                        int code = resp.getStatus();
+                        userLog("Ping response: ", code);
+
+                        // If we're not allowed to sync (e.g. roaming policy), terminate gracefully
+                        // now; otherwise we might start a sync based on the response
+                        if (!ExchangeService.canAutoSync(mAccount)) {
+                            mStop = true;
+                        }
+
+                        // Return immediately if we've been asked to stop during the ping
+                        if (mStop) {
+                            userLog("Stopping pingLoop");
+                            return;
+                        }
+
+                        if (code == HttpStatus.SC_OK) {
+                            // Make sure to clear out any pending sync errors
+                            ExchangeService.removeFromSyncErrorMap(mMailboxId);
+                            if (!resp.isEmpty()) {
+                                InputStream is = resp.getInputStream();
+                                int pingResult = parsePingResult(is, mContentResolver,
+                                        pingErrorMap);
+                                // If our ping completed (status = 1), and wasn't forced and we're
+                                // not at the maximum, try increasing timeout by two minutes
+                                if (pingResult == PROTOCOL_PING_STATUS_COMPLETED && !forcePing) {
+                                    if (pingHeartbeat > mPingHighWaterMark) {
+                                        mPingHighWaterMark = pingHeartbeat;
+                                        userLog("Setting high water mark at: ", mPingHighWaterMark);
+                                    }
+                                    if ((pingHeartbeat < mPingMaxHeartbeat) &&
+                                            !mPingHeartbeatDropped) {
+                                        pingHeartbeat += PING_HEARTBEAT_INCREMENT;
+                                        if (pingHeartbeat > mPingMaxHeartbeat) {
+                                            pingHeartbeat = mPingMaxHeartbeat;
+                                        }
+                                        userLog("Increase ping heartbeat to ", pingHeartbeat, "s");
+                                    }
+                                }
+                            } else {
+                                userLog("Ping returned empty result; throwing IOException");
+                                throw new IOException();
+                            }
+                        } else if (EasResponse.isAuthError(code)) {
+                            mExitStatus = EXIT_LOGIN_FAILURE;
+                            userLog("Authorization error during Ping: ", code);
+                            throw new IOException();
+                        } else if (EasResponse.isProvisionError(code)) {
+                            userLog("Provisioning required during Ping: ", code);
+                            throw new CommandStatusException(CommandStatus.NEEDS_PROVISIONING);
+                        }
+                    } finally {
+                        resp.close();
+                    }
+                } catch (IOException e) {
+                    String message = e.getMessage();
+                    // If we get the exception that is indicative of a NAT timeout and if we
+                    // haven't yet "fixed" the timeout, back off by two minutes and "fix" it
+                    boolean hasMessage = message != null;
+                    userLog("IOException runPingLoop: " + (hasMessage ? message : "[no message]"));
+                    if (mPostReset) {
+                        // Nothing to do in this case; this is ExchangeService telling us to try
+                        // another ping.
+                    } else if (mPostAborted || isLikelyNatFailure(message)) {
+                        long pingLength = SystemClock.elapsedRealtime() - pingTime;
+                        if ((pingHeartbeat > mPingMinHeartbeat) &&
+                                (pingHeartbeat > mPingHighWaterMark)) {
+                            pingHeartbeat -= PING_HEARTBEAT_INCREMENT;
+                            mPingHeartbeatDropped = true;
+                            if (pingHeartbeat < mPingMinHeartbeat) {
+                                pingHeartbeat = mPingMinHeartbeat;
+                            }
+                            userLog("Decreased ping heartbeat to ", pingHeartbeat, "s");
+                        } else if (mPostAborted) {
+                            // There's no point in throwing here; this can happen in two cases
+                            // 1) An alarm, which indicates minutes without activity; no sense
+                            //    backing off
+                            // 2) ExchangeService abort, due to sync of mailbox.  Again, we want to
+                            //    keep on trying to ping
+                            userLog("Ping aborted; retry");
+                        } else if (pingLength < 2000) {
+                            userLog("Abort or NAT type return < 2 seconds; throwing IOException");
+                            throw e;
+                        } else {
+                            userLog("NAT type IOException");
+                        }
+                    } else if (hasMessage && message.contains("roken pipe")) {
+                        // The "broken pipe" error (uppercase or lowercase "b") seems to be an
+                        // internal error, so let's not throw an exception (which leads to delays)
+                        // but rather simply run through the loop again
+                    } else {
+                        throw e;
+                    }
+                }
+            } else if (forcePing) {
+                // In this case, there aren't any boxes that are pingable, but there are boxes
+                // waiting (for IOExceptions)
+                userLog("pingLoop waiting 60s for any pingable boxes");
+                sleep(60*SECONDS, true);
+            } else if (pushCount > 0) {
+                // If we want to Ping, but can't just yet, wait a little bit
+                // TODO Change sleep to wait and use notify from ExchangeService when a sync ends
+                sleep(2*SECONDS, false);
+                pingWaitCount++;
+                //userLog("pingLoop waited 2s for: ", (pushCount - canPushCount), " box(es)");
+            } else if (uninitCount > 0) {
+                // In this case, we're doing an initial sync of at least one mailbox.  Since this
+                // is typically a one-time case, I'm ok with trying again every 10 seconds until
+                // we're in one of the other possible states.
+                userLog("pingLoop waiting for initial sync of ", uninitCount, " box(es)");
+                sleep(10*SECONDS, true);
+            } else if (inboxId == -1) {
+                // In this case, we're still syncing mailboxes, so sleep for only a short time
+                sleep(45*SECONDS, true);
+            } else {
+                // We've got nothing to do, so we'll check again in 20 minutes at which time
+                // we'll update the folder list, check for policy changes and/or remote wipe, etc.
+                // Let the device sleep in the meantime...
+                userLog(ACCOUNT_MAILBOX_SLEEP_TEXT);
+                sleep(ACCOUNT_MAILBOX_SLEEP_TIME, true);
+            }
+        }
+
+        // Save away the current heartbeat
+        mPingHeartbeat = pingHeartbeat;
+    }
+
+    private void sleep(long ms, boolean runAsleep) {
+        if (runAsleep) {
+            ExchangeService.runAsleep(mMailboxId, ms+(5*SECONDS));
+        }
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+            // Doesn't matter whether we stop early; it's the thought that counts
+        } finally {
+            if (runAsleep) {
+                ExchangeService.runAwake(mMailboxId);
+            }
+        }
+    }
+
+    private int parsePingResult(InputStream is, ContentResolver cr,
+            HashMap<String, Integer> errorMap)
+            throws IOException, StaleFolderListException, IllegalHeartbeatException,
+                CommandStatusException {
+        PingParser pp = new PingParser(is, this);
+        if (pp.parse()) {
+            // True indicates some mailboxes need syncing...
+            // syncList has the serverId's of the mailboxes...
+            mBindArguments[0] = Long.toString(mAccount.mId);
+            mPingChangeList = pp.getSyncList();
+            for (String serverId: mPingChangeList) {
+                mBindArguments[1] = serverId;
+                Cursor c = cr.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
+                        WHERE_ACCOUNT_KEY_AND_SERVER_ID, mBindArguments, null);
+                if (c == null) throw new ProviderUnavailableException();
+                try {
+                    if (c.moveToFirst()) {
+
+                        /**
+                         * Check the boxes reporting changes to see if there really were any...
+                         * We do this because bugs in various Exchange servers can put us into a
+                         * looping behavior by continually reporting changes in a mailbox, even when
+                         * there aren't any.
+                         *
+                         * This behavior is seemingly random, and therefore we must code defensively
+                         * by backing off of push behavior when it is detected.
+                         *
+                         * One known cause, on certain Exchange 2003 servers, is acknowledged by
+                         * Microsoft, and the server hotfix for this case can be found at
+                         * http://support.microsoft.com/kb/923282
+                         */
+
+                        // Check the status of the last sync
+                        String status = c.getString(Mailbox.CONTENT_SYNC_STATUS_COLUMN);
+                        int type = ExchangeService.getStatusType(status);
+                        // This check should always be true...
+                        if (type == ExchangeService.SYNC_PING) {
+                            int changeCount = ExchangeService.getStatusChangeCount(status);
+                            if (changeCount > 0) {
+                                errorMap.remove(serverId);
+                            } else if (changeCount == 0) {
+                                // This means that a ping reported changes in error; we keep a count
+                                // of consecutive errors of this kind
+                                String name = c.getString(Mailbox.CONTENT_DISPLAY_NAME_COLUMN);
+                                Integer failures = errorMap.get(serverId);
+                                if (failures == null) {
+                                    userLog("Last ping reported changes in error for: ", name);
+                                    errorMap.put(serverId, 1);
+                                } else if (failures > MAX_PING_FAILURES) {
+                                    // We'll back off of push for this box
+                                    pushFallback(c.getLong(Mailbox.CONTENT_ID_COLUMN));
+                                    continue;
+                                } else {
+                                    userLog("Last ping reported changes in error for: ", name);
+                                    errorMap.put(serverId, failures + 1);
+                                }
+                            }
+                        }
+
+                        // If there were no problems with previous sync, we'll start another one
+                        ExchangeService.startManualSync(c.getLong(Mailbox.CONTENT_ID_COLUMN),
+                                ExchangeService.SYNC_PING, null);
+                    }
+                } finally {
+                    c.close();
+                }
+            }
+        }
+        return pp.getSyncStatus();
+    }
+
+    /**
      * Common code to sync E+PIM data
+     *
      * @param target an EasMailbox, EasContacts, or EasCalendar object
      */
     public void sync(AbstractSyncAdapter target) throws IOException {
@@ -1845,14 +2557,14 @@
      * Clears out the security policies associated with the account, forcing a provision error
      * and a re-sync of the policy information for the account.
      */
-    @SuppressWarnings("deprecation")
-    void resetSecurityPolicies() {
+    private void resetSecurityPolicies() {
         ContentValues cv = new ContentValues();
         cv.put(AccountColumns.SECURITY_FLAGS, 0);
         cv.putNull(AccountColumns.SECURITY_SYNC_KEY);
         long accountId = mAccount.mId;
         mContentResolver.update(ContentUris.withAppendedId(
                 Account.CONTENT_URI, accountId), cv, null, null);
+        SecurityPolicyDelegate.policiesRequired(mContext, accountId);
     }
 
     @Override
@@ -1869,6 +2581,9 @@
                 int trafficFlags = TrafficFlags.getSyncFlags(mContext, mAccount);
                 if ((mMailbox == null) || (mAccount == null)) {
                     return;
+                } else if (mMailbox.mType == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+                    TrafficStats.setThreadStatsTag(trafficFlags | TrafficFlags.DATA_EMAIL);
+                    runAccountMailbox();
                 } else {
                     AbstractSyncAdapter target;
                     if (mMailbox.mType == Mailbox.TYPE_CONTACTS) {
diff --git a/src/com/android/exchange/ExchangeService.java b/src/com/android/exchange/ExchangeService.java
index 0107d55..833e0c4 100644
--- a/src/com/android/exchange/ExchangeService.java
+++ b/src/com/android/exchange/ExchangeService.java
@@ -53,8 +53,6 @@
 import com.android.emailcommon.provider.Account;
 import com.android.emailcommon.provider.EmailContent;
 import com.android.emailcommon.provider.EmailContent.Attachment;
-import com.android.emailcommon.provider.EmailContent.Body;
-import com.android.emailcommon.provider.EmailContent.BodyColumns;
 import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
 import com.android.emailcommon.provider.EmailContent.MailboxColumns;
 import com.android.emailcommon.provider.EmailContent.Message;
@@ -177,8 +175,6 @@
     public static final int PING_STATUS_WAITING = 2;
     // Service had a fatal error; can't run
     public static final int PING_STATUS_UNABLE = 3;
-    // Service is disabled by user (checkbox)
-    public static final int PING_STATUS_DISABLED = 4;
 
     private static final int MAX_CLIENT_CONNECTION_MANAGER_SHUTDOWNS = 1;
 
@@ -287,7 +283,6 @@
             }
         }
 
-        @Override
         public void loadAttachmentStatus(final long messageId, final long attachmentId,
                 final int status, final int progress) {
             broadcastCallback(new ServiceCallbackWrapper() {
@@ -298,7 +293,6 @@
             });
         }
 
-        @Override
         public void sendMessageStatus(final long messageId, final String subject, final int status,
                 final int progress) {
             broadcastCallback(new ServiceCallbackWrapper() {
@@ -309,7 +303,6 @@
             });
         }
 
-        @Override
         public void syncMailboxListStatus(final long accountId, final int status,
                 final int progress) {
             broadcastCallback(new ServiceCallbackWrapper() {
@@ -320,7 +313,6 @@
             });
         }
 
-        @Override
         public void syncMailboxStatus(final long mailboxId, final int status,
                 final int progress) {
             broadcastCallback(new ServiceCallbackWrapper() {
@@ -330,11 +322,6 @@
                 }
             });
         }
-
-        @Override
-        public void loadMessageStatus(long messageId, int statusCode, int progress)
-                throws RemoteException {
-        }
     };
 
     /**
@@ -342,23 +329,19 @@
      */
     private final IEmailService.Stub mBinder = new IEmailService.Stub() {
 
-        @Override
         public int getApiLevel() {
             return Api.LEVEL;
         }
 
-        @Override
         public Bundle validate(HostAuth hostAuth) throws RemoteException {
             return AbstractSyncService.validate(EasSyncService.class,
                     hostAuth, ExchangeService.this);
         }
 
-        @Override
         public Bundle autoDiscover(String userName, String password) throws RemoteException {
             return new EasSyncService().tryAutodiscover(userName, password);
         }
 
-        @Override
         public void startSync(long mailboxId, boolean userRequest) throws RemoteException {
             ExchangeService exchangeService = INSTANCE;
             if (exchangeService == null) return;
@@ -417,24 +400,20 @@
                 ExchangeService.SYNC_SERVICE_START_SYNC, null);
         }
 
-        @Override
         public void stopSync(long mailboxId) throws RemoteException {
             stopManualSync(mailboxId);
         }
 
-        @Override
         public void loadAttachment(long attachmentId, boolean background) throws RemoteException {
             Attachment att = Attachment.restoreAttachmentWithId(ExchangeService.this, attachmentId);
             log("loadAttachment " + attachmentId + ": " + att.mFileName);
             sendMessageRequest(new PartRequest(att, null, null));
         }
 
-        @Override
         public void updateFolderList(long accountId) throws RemoteException {
             reloadFolderList(ExchangeService.this, accountId, false);
         }
 
-        @Override
         public void hostChanged(long accountId) throws RemoteException {
             ExchangeService exchangeService = INSTANCE;
             if (exchangeService == null) return;
@@ -459,38 +438,31 @@
             kick("host changed");
         }
 
-        @Override
         public void setLogging(int flags) throws RemoteException {
             Eas.setUserDebug(flags);
         }
 
-        @Override
         public void sendMeetingResponse(long messageId, int response) throws RemoteException {
             sendMessageRequest(new MeetingResponseRequest(messageId, response));
         }
 
-        @Override
         public void loadMore(long messageId) throws RemoteException {
         }
 
         // The following three methods are not implemented in this version
-        @Override
         public boolean createFolder(long accountId, String name) throws RemoteException {
             return false;
         }
 
-        @Override
         public boolean deleteFolder(long accountId, String name) throws RemoteException {
             return false;
         }
 
-        @Override
         public boolean renameFolder(long accountId, String oldName, String newName)
                 throws RemoteException {
             return false;
         }
 
-        @Override
         public void setCallback(IEmailServiceCallback cb) throws RemoteException {
             mCallbackList.register(cb);
         }
@@ -501,39 +473,19 @@
          * @param accountId the account whose data should be deleted
          * @throws RemoteException
          */
-        @Override
         public void deleteAccountPIMData(long accountId) throws RemoteException {
-            ExchangeService exchangeService = INSTANCE;
-            if (exchangeService == null) return;
             // Stop any running syncs
             ExchangeService.stopAccountSyncs(accountId);
             // Delete the data
             ExchangeService.deleteAccountPIMData(accountId);
-            long accountMailboxId = Mailbox.findMailboxOfType(exchangeService, accountId,
-                    Mailbox.TYPE_EAS_ACCOUNT_MAILBOX);
-            if (accountMailboxId != Mailbox.NO_MAILBOX) {
-                // Make sure the account mailbox is held due to security
-                synchronized(sSyncLock) {
-                    mSyncErrorMap.put(accountMailboxId, exchangeService.new SyncError(
-                            AbstractSyncService.EXIT_SECURITY_FAILURE, false));
-
-                }
-            }
-            // Make sure the reconciler runs
-            runAccountReconcilerSync(ExchangeService.this);
         }
 
-        @Override
         public int searchMessages(long accountId, SearchParams searchParams, long destMailboxId) {
             ExchangeService exchangeService = INSTANCE;
             if (exchangeService == null) return 0;
             return Search.searchMessages(exchangeService, accountId, searchParams,
                     destMailboxId);
         }
-
-        @Override
-        public void sendMail(long accountId) throws RemoteException {
-        }
     };
 
     /**
@@ -628,14 +580,14 @@
         Mailbox mailbox =
             Mailbox.restoreMailboxOfType(exchangeService, accountId, Mailbox.TYPE_CONTACTS);
         if (mailbox != null) {
-            EasSyncService service = EasSyncService.getServiceForMailbox(exchangeService, mailbox);
+            EasSyncService service = new EasSyncService(exchangeService, mailbox);
             ContactsSyncAdapter adapter = new ContactsSyncAdapter(service);
             adapter.wipe();
         }
         mailbox =
             Mailbox.restoreMailboxOfType(exchangeService, accountId, Mailbox.TYPE_CALENDAR);
         if (mailbox != null) {
-            EasSyncService service = EasSyncService.getServiceForMailbox(exchangeService, mailbox);
+            EasSyncService service = new EasSyncService(exchangeService, mailbox);
             CalendarSyncAdapter adapter = new CalendarSyncAdapter(service);
             adapter.wipe();
         }
@@ -682,13 +634,17 @@
                 public void run() {
                     synchronized (mAccountList) {
                         for (Account account : mAccountList) {
-                            if (onSecurityHold(account)) {
+                            if ((account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0) {
                                 // If we're in a security hold, and our policies are active, release
-                                // the hold
+                                // the hold; otherwise, ping PolicyService that this account's
+                                // policies are required
                                 if (PolicyServiceProxy.isActive(ExchangeService.this, null)) {
                                     PolicyServiceProxy.setAccountHoldFlag(ExchangeService.this,
                                             account, false);
                                     log("isActive true; release hold for " + account.mDisplayName);
+                                } else {
+                                    PolicyServiceProxy.policiesRequired(ExchangeService.this,
+                                            account.mId);
                                 }
                             }
                         }
@@ -848,8 +804,7 @@
         @Override
         public void onChange(boolean selfChange) {
             new Thread(new Runnable() {
-               @Override
-            public void run() {
+               public void run() {
                    onAccountChanged();
                 }}, "Account Observer").start();
         }
@@ -951,7 +906,6 @@
             // See if the user has changed syncing of our calendar
             if (!selfChange) {
                 new Thread(new Runnable() {
-                    @Override
                     public void run() {
                         try {
                             Cursor c = mResolver.query(Calendars.CONTENT_URI,
@@ -978,8 +932,7 @@
                                             stopManualSync(mailbox.mId);
                                             // Set the syncKey to 0 (reset)
                                             EasSyncService service =
-                                                EasSyncService.getServiceForMailbox(
-                                                        INSTANCE, mailbox);
+                                                new EasSyncService(INSTANCE, mailbox);
                                             CalendarSyncAdapter adapter =
                                                 new CalendarSyncAdapter(service);
                                             try {
@@ -1257,7 +1210,6 @@
     }
 
     static public ConnPerRoute sConnPerRoute = new ConnPerRoute() {
-        @Override
         public int getMaxForRoute(HttpRoute route) {
             return 8;
         }
@@ -1545,8 +1497,7 @@
                     threadName += service.mMailbox.mDisplayName;
                 }
                 new Thread(new Runnable() {
-                   @Override
-                public void run() {
+                   public void run() {
                        Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, id);
                        if (m != null) {
                            // We ignore drafts completely (doesn't sync).  Changes in Outbox are
@@ -1637,18 +1588,18 @@
      * @param service the service to start
      * @param m the Mailbox on which the service will operate
      */
-    private void startServiceThread(AbstractSyncService service) {
+    private void startServiceThread(AbstractSyncService service, Mailbox m) {
+        if (m == null) return;
         synchronized (sSyncLock) {
-            Mailbox mailbox = service.mMailbox;
-            String mailboxName = mailbox.mDisplayName;
+            String mailboxName = m.mDisplayName;
             String accountName = service.mAccount.mDisplayName;
             Thread thread = new Thread(service, mailboxName + "[" + accountName + "]");
             log("Starting thread for " + mailboxName + " in account " + accountName);
             thread.start();
-            mServiceMap.put(mailbox.mId, service);
-            runAwake(mailbox.mId);
-            if (mailbox.mServerId != null && mailbox.mType != Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
-                stopPing(mailbox.mAccountKey);
+            mServiceMap.put(m.mId, service);
+            runAwake(m.mId);
+            if ((m.mServerId != null) && !m.mServerId.startsWith(Eas.ACCOUNT_MAILBOX_PREFIX)) {
+                stopPing(m.mAccountKey);
             }
         }
     }
@@ -1665,7 +1616,7 @@
                 if (m != null) {
                     String serverId = m.mServerId;
                     if (m.mAccountKey == accountId && serverId != null &&
-                          m.mType == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+                            serverId.startsWith(Eas.ACCOUNT_MAILBOX_PREFIX)) {
                         // Here's our account mailbox; reset him (stopping pings)
                         AbstractSyncService svc = mServiceMap.get(mailboxId);
                         svc.reset();
@@ -1676,7 +1627,6 @@
     }
 
     private void requestSync(Mailbox m, int reason, Request req) {
-        int syncStatus = EmailContent.SYNC_STATUS_BACKGROUND;
         // Don't sync if there's no connectivity
         if (sConnectivityHold || (m == null) || sStop) {
             if (reason >= SYNC_CALLBACK_START) {
@@ -1694,34 +1644,18 @@
                 // Always make sure there's not a running instance of this service
                 AbstractSyncService service = mServiceMap.get(m.mId);
                 if (service == null) {
-                    service = EasSyncService.getServiceForMailbox(this, m);
+                    service = new EasSyncService(this, m);
                     if (!((EasSyncService)service).mIsValid) return;
                     service.mSyncReason = reason;
                     if (req != null) {
                         service.addRequest(req);
                     }
-                    startServiceThread(service);
-                    if (reason >= SYNC_CALLBACK_START) {
-                        syncStatus = EmailContent.SYNC_STATUS_USER;
-                    }
-                    setMailboxSyncStatus(m.mId, syncStatus);
+                    startServiceThread(service, m);
                 }
             }
         }
     }
 
-    private void setMailboxSyncStatus(long id, int status) {
-        ContentValues values = new ContentValues();
-        values.put(Mailbox.UI_SYNC_STATUS, status);
-        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, id), values, null, null);
-    }
-
-    private void setMailboxLastSyncResult(long id, int result) {
-        ContentValues values = new ContentValues();
-        values.put(Mailbox.UI_LAST_SYNC_RESULT, result);
-        mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, id), values, null, null);
-    }
-
     private void stopServiceThreads() {
         synchronized (sSyncLock) {
             ArrayList<Long> toStop = new ArrayList<Long>();
@@ -1937,7 +1871,6 @@
         }
     }
 
-    @Override
     public void run() {
         sStop = false;
         alwaysLog("ExchangeService thread running");
@@ -2156,7 +2089,6 @@
             if (policy == null) {
                 policy = Policy.restorePolicyWithId(INSTANCE, policyKey);
                 account.mPolicy = policy;
-                if (!PolicyServiceProxy.isActive(exchangeService, policy)) return false;
             }
             if (policy != null && policy.mRequireManualSyncWhenRoaming && networkInfo.isRoaming()) {
                 return false;
@@ -2187,12 +2119,9 @@
     private boolean isMailboxSyncable(Account account, int type) {
         // This 'if' statement performs checks to see whether or not a mailbox is a
         // candidate for syncing based on policies, user settings, & other restrictions
-        if (type == Mailbox.TYPE_OUTBOX) {
-            // Outbox is always syncable
+        if (type == Mailbox.TYPE_OUTBOX || type == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
+            // Outbox and account mailbox are always syncable
             return true;
-        } else if (type == Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) {
-            // Always sync EAS mailbox unless master sync is off
-            return ContentResolver.getMasterSyncAutomatically();
         } else if (type == Mailbox.TYPE_CONTACTS || type == Mailbox.TYPE_CALENDAR) {
             // Contacts/Calendar obey this setting from ContentResolver
             if (!ContentResolver.getMasterSyncAutomatically()) {
@@ -2317,7 +2246,7 @@
                     } else if (mailboxType == Mailbox.TYPE_OUTBOX) {
                         if (hasSendableMessages(c)) {
                             Mailbox m = EmailContent.getContent(c, Mailbox.class);
-                            startServiceThread(EasSyncService.getServiceForMailbox(this, m));
+                            startServiceThread(new EasOutboxService(this, m), m);
                         }
                     } else if (syncInterval > 0 && syncInterval <= ONE_DAY_MINUTES) {
                         long lastSync = c.getLong(Mailbox.CONTENT_SYNC_TIME_COLUMN);
@@ -2424,29 +2353,14 @@
 
     static public void sendMessageRequest(Request req) {
         ExchangeService exchangeService = INSTANCE;
+        if (exchangeService == null) return;
         Message msg = Message.restoreMessageWithId(exchangeService, req.mMessageId);
-        if (msg == null) return;
-        long mailboxId = msg.mMailboxKey;
-        Mailbox mailbox = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
-        if (mailbox == null) return;
-
-        // If we're loading an attachment for Outbox, we want to look at the source message
-        // to find the loading mailbox
-        if (mailbox.mType == Mailbox.TYPE_OUTBOX) {
-            long sourceId = Utility.getFirstRowLong(exchangeService, Body.CONTENT_URI,
-                    new String[] {BodyColumns.SOURCE_MESSAGE_KEY},
-                    BodyColumns.MESSAGE_KEY + "=?",
-                    new String[] {Long.toString(msg.mId)}, null, 0, -1L);
-            if (sourceId != -1L) {
-                EmailContent.Message sourceMsg =
-                        EmailContent.Message.restoreMessageWithId(exchangeService, sourceId);
-                if (sourceMsg != null) {
-                    mailboxId = sourceMsg.mMailboxKey;
-                }
-            }
+        if (msg == null) {
+            return;
         }
-
+        long mailboxId = msg.mMailboxKey;
         AbstractSyncService service = exchangeService.mServiceMap.get(mailboxId);
+
         if (service == null) {
             startManualSync(mailboxId, SYNC_SERVICE_PART_REQUEST, req);
             kick("part request");
@@ -2582,7 +2496,6 @@
                 return;
             }
             exchangeService.releaseMailbox(mailboxId);
-            exchangeService.setMailboxSyncStatus(mailboxId, EmailContent.SYNC_STATUS_NONE);
 
             ConcurrentHashMap<Long, SyncError> errorMap = exchangeService.mSyncErrorMap;
             SyncError syncError = errorMap.get(mailboxId);
@@ -2601,53 +2514,38 @@
                 }
             }
 
-            int lastResult = EmailContent.LAST_SYNC_RESULT_SUCCESS;
-            // For error states, whether the error is fatal (won't automatically be retried)
-            boolean errorIsFatal = true;
-            try {
-                switch (exitStatus) {
-                    case AbstractSyncService.EXIT_DONE:
-                        if (svc.hasPendingRequests()) {
-                            // TODO Handle this case
-                        }
-                        errorMap.remove(mailboxId);
-                        // If we've had a successful sync, clear the shutdown count
-                        synchronized (ExchangeService.class) {
-                            sClientConnectionManagerShutdownCount = 0;
-                        }
-                        // Leave now; other statuses are errors
-                        return;
-                    // I/O errors get retried at increasing intervals
-                    case AbstractSyncService.EXIT_IO_ERROR:
-                        if (syncError != null) {
-                            syncError.escalate();
-                            log(m.mDisplayName + " held for " + syncError.holdDelay + "ms");
-                        } else {
-                            log(m.mDisplayName + " added to syncErrorMap, hold for 15s");
-                        }
-                        lastResult = EmailContent.LAST_SYNC_RESULT_CONNECTION_ERROR;
-                        errorIsFatal = false;
-                        break;
-                    // These errors are not retried automatically
-                    case AbstractSyncService.EXIT_LOGIN_FAILURE:
-                        new AccountServiceProxy(exchangeService).notifyLoginFailed(m.mAccountKey);
-                        lastResult = EmailContent.LAST_SYNC_RESULT_AUTH_ERROR;
-                        break;
-                    case AbstractSyncService.EXIT_SECURITY_FAILURE:
-                    case AbstractSyncService.EXIT_ACCESS_DENIED:
-                        lastResult = EmailContent.LAST_SYNC_RESULT_SECURITY_ERROR;
-                        break;
-                    case AbstractSyncService.EXIT_EXCEPTION:
-                        lastResult = EmailContent.LAST_SYNC_RESULT_INTERNAL_ERROR;
-                        break;
-                }
-                // Add this box to the error map
-                errorMap.put(mailboxId, exchangeService.new SyncError(exitStatus, errorIsFatal));
-            } finally {
-                // Always set the last result
-                exchangeService.setMailboxLastSyncResult(mailboxId, lastResult);
-                kick("sync completed");
+            switch (exitStatus) {
+                case AbstractSyncService.EXIT_DONE:
+                    if (svc.hasPendingRequests()) {
+                        // TODO Handle this case
+                    }
+                    errorMap.remove(mailboxId);
+                    // If we've had a successful sync, clear the shutdown count
+                    synchronized (ExchangeService.class) {
+                        sClientConnectionManagerShutdownCount = 0;
+                    }
+                    break;
+                // I/O errors get retried at increasing intervals
+                case AbstractSyncService.EXIT_IO_ERROR:
+                    if (syncError != null) {
+                        syncError.escalate();
+                        log(m.mDisplayName + " held for " + syncError.holdDelay + "ms");
+                    } else {
+                        errorMap.put(mailboxId, exchangeService.new SyncError(exitStatus, false));
+                        log(m.mDisplayName + " added to syncErrorMap, hold for 15s");
+                    }
+                    break;
+                // These errors are not retried automatically
+                case AbstractSyncService.EXIT_LOGIN_FAILURE:
+                    new AccountServiceProxy(exchangeService).notifyLoginFailed(m.mAccountKey);
+                    // Fall through
+                case AbstractSyncService.EXIT_SECURITY_FAILURE:
+                case AbstractSyncService.EXIT_ACCESS_DENIED:
+                case AbstractSyncService.EXIT_EXCEPTION:
+                    errorMap.put(mailboxId, exchangeService.new SyncError(exitStatus, true));
+                    break;
             }
+            kick("sync completed");
         }
     }
 
diff --git a/src/com/android/exchange/SecurityPolicyDelegate.java b/src/com/android/exchange/SecurityPolicyDelegate.java
new file mode 100644
index 0000000..5025c8f
--- /dev/null
+++ b/src/com/android/exchange/SecurityPolicyDelegate.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.Policy;
+import com.android.emailcommon.service.PolicyServiceProxy;
+
+import android.content.Context;
+import android.os.RemoteException;
+
+public class SecurityPolicyDelegate {
+
+    public static boolean isActive(Context context, Policy policy) {
+        try {
+            return new PolicyServiceProxy(context).isActive(policy);
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    public static void policiesRequired(Context context, long accountId) {
+        try {
+            new PolicyServiceProxy(context).policiesRequired(accountId);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("PolicyService transaction failed");
+        }
+    }
+
+    public static void policiesUpdated(Context context, long accountId) {
+        try {
+            new PolicyServiceProxy(context).policiesUpdated(accountId);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("PolicyService transaction failed");
+        }
+    }
+
+    public static void setAccountHoldFlag(Context context, Account account, boolean newState) {
+        try {
+            new PolicyServiceProxy(context).setAccountHoldFlag(account.mId, newState);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("PolicyService transaction failed");
+        }
+    }
+
+    public static boolean isActiveAdmin(Context context) {
+        try {
+            return new PolicyServiceProxy(context).isActiveAdmin();
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    public static void remoteWipe(Context context) {
+        try {
+            new PolicyServiceProxy(context).remoteWipe();
+        } catch (RemoteException e) {
+            throw new IllegalStateException("PolicyService transaction failed");
+        }
+    }
+
+    public static boolean isSupported(Context context, Policy policy) {
+        try {
+            return new PolicyServiceProxy(context).isSupported(policy);
+        } catch (RemoteException e) {
+        }
+        return false;
+     }
+
+    public static Policy clearUnsupportedPolicies(Context context, Policy policy) {
+        try {
+            return new PolicyServiceProxy(context).clearUnsupportedPolicies(policy);
+        } catch (RemoteException e) {
+        }
+        throw new IllegalStateException("PolicyService transaction failed");
+    }
+}
diff --git a/src/com/android/exchange/adapter/AttachmentLoader.java b/src/com/android/exchange/adapter/AttachmentLoader.java
index 04cf555..4d14934 100644
--- a/src/com/android/exchange/adapter/AttachmentLoader.java
+++ b/src/com/android/exchange/adapter/AttachmentLoader.java
@@ -32,7 +32,6 @@
 import com.android.exchange.ExchangeService;
 import com.android.exchange.PartRequest;
 import com.android.exchange.utility.UriCodec;
-import com.android.mail.providers.UIProvider;
 import com.google.common.annotations.VisibleForTesting;
 
 import org.apache.http.HttpStatus;
@@ -95,7 +94,6 @@
     private void finishLoadAttachment() {
         ContentValues cv = new ContentValues();
         cv.put(AttachmentColumns.CONTENT_URI, mAttachmentUri.toString());
-        cv.put(AttachmentColumns.UI_STATE, UIProvider.AttachmentState.SAVED);
         mAttachment.update(mContext, cv);
         doStatusCallback(EmailServiceStatus.SUCCESS);
     }
diff --git a/src/com/android/exchange/adapter/CalendarSyncAdapter.java b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
index 4df45a9..c8ab766 100644
--- a/src/com/android/exchange/adapter/CalendarSyncAdapter.java
+++ b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
@@ -43,8 +43,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.calendarcommon.DateException;
-import com.android.calendarcommon.Duration;
 import com.android.emailcommon.AccountManagerTypes;
 import com.android.emailcommon.provider.EmailContent;
 import com.android.emailcommon.provider.EmailContent.Message;
@@ -55,9 +53,11 @@
 import com.android.exchange.EasSyncService;
 import com.android.exchange.ExchangeService;
 import com.android.exchange.utility.CalendarUtilities;
+import com.android.exchange.utility.Duration;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.GregorianCalendar;
 import java.util.Map.Entry;
@@ -1566,7 +1566,7 @@
                 try {
                     duration.parse(entityValues.getAsString(Events.DURATION));
                     durationMillis = duration.getMillis();
-                } catch (DateException e) {
+                } catch (ParseException e) {
                     // Can't do much about this; use the default (1 hour)
                 }
             }
diff --git a/src/com/android/exchange/adapter/ContactsSyncAdapter.java b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
index 1b21d11..ec0299b 100644
--- a/src/com/android/exchange/adapter/ContactsSyncAdapter.java
+++ b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
@@ -17,6 +17,10 @@
 
 package com.android.exchange.adapter;
 
+import com.android.exchange.CommandStatusException;
+import com.android.exchange.Eas;
+import com.android.exchange.EasSyncService;
+
 import android.content.ContentProviderClient;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderOperation.Builder;
@@ -58,10 +62,6 @@
 import android.util.Base64;
 import android.util.Log;
 
-import com.android.exchange.CommandStatusException;
-import com.android.exchange.Eas;
-import com.android.exchange.EasSyncService;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -1535,14 +1535,7 @@
         }
         // Compose address from name and addr
         if (addr != null) {
-            String value;
-            // Only send the raw email address for EAS 2.5 (Hotmail, in particular, chokes on
-            // an RFC822 address)
-            if (mService.mProtocolVersionDouble < Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
-                value = addr;
-            } else {
-                value = '\"' + name + "\" <" + addr + '>';
-            }
+            String value = '\"' + name + "\" <" + addr + '>';
             if (count < MAX_EMAIL_ROWS) {
                 s.data(EMAIL_TAGS[count], value);
             }
diff --git a/exchange1_src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
similarity index 99%
rename from exchange1_src/com/android/exchange/adapter/EmailSyncAdapter.java
rename to src/com/android/exchange/adapter/EmailSyncAdapter.java
index c498eb6..042ec32 100644
--- a/exchange1_src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -60,6 +60,7 @@
 import com.android.exchange.MessageMoveRequest;
 import com.android.exchange.R;
 import com.android.exchange.utility.CalendarUtilities;
+
 import com.google.common.annotations.VisibleForTesting;
 
 import org.apache.http.HttpStatus;
diff --git a/src/com/android/exchange/adapter/ProvisionParser.java b/src/com/android/exchange/adapter/ProvisionParser.java
index de30111..ca71cf9 100644
--- a/src/com/android/exchange/adapter/ProvisionParser.java
+++ b/src/com/android/exchange/adapter/ProvisionParser.java
@@ -23,7 +23,9 @@
 
 import com.android.emailcommon.provider.Policy;
 import com.android.exchange.EasSyncService;
+import com.android.exchange.ExchangeService;
 import com.android.exchange.R;
+import com.android.exchange.SecurityPolicyDelegate;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -36,20 +38,22 @@
 
 /**
  * Parse the result of the Provision command
+ *
+ * Assuming a successful parse, we store the PolicySet and the policy key
  */
 public class ProvisionParser extends Parser {
     private final EasSyncService mService;
-    private Policy mPolicy = null;
-    private String mSecuritySyncKey = null;
-    private boolean mRemoteWipe = false;
-    private boolean mIsSupportable = true;
-    private boolean smimeRequired = false;
-    private final Resources mResources;
+    Policy mPolicy = null;
+    String mSecuritySyncKey = null;
+    boolean mRemoteWipe = false;
+    boolean mIsSupportable = true;
+    // An array of string resource id's describing policies that are unsupported by the device/app
+    String[] mUnsupportedPolicies;
+    boolean smimeRequired = false;
 
     public ProvisionParser(InputStream in, EasSyncService service) throws IOException {
         super(in);
         mService = service;
-        mResources = service.mContext.getResources();
     }
 
     public Policy getPolicy() {
@@ -72,32 +76,18 @@
         return (mPolicy != null) && mIsSupportable;
     }
 
-    public void clearUnsupportablePolicies() {
+    public void clearUnsupportedPolicies() {
+        mPolicy = SecurityPolicyDelegate.clearUnsupportedPolicies(mService.mContext, mPolicy);
         mIsSupportable = true;
-        mPolicy.mProtocolPoliciesUnsupported = null;
+        mUnsupportedPolicies = null;
     }
 
-    private void addPolicyString(StringBuilder sb, int res) {
-        sb.append(mResources.getString(res));
-        sb.append(Policy.POLICY_STRING_DELIMITER);
+    public String[] getUnsupportedPolicies() {
+        return mUnsupportedPolicies;
     }
 
-    /**
-     * Complete setup of a Policy; we normalize it first (removing inconsistencies, etc.) and then
-     * generate the tokenized "protocol policies enforced" string.  Note that unsupported policies
-     * must have been added prior to calling this method (this is only a possibility with wbxml
-     * policy documents, as all versions of the OS support the policies in xml documents).
-     */
     private void setPolicy(Policy policy) {
         policy.normalize();
-        StringBuilder sb = new StringBuilder();
-        if (policy.mDontAllowAttachments) {
-            addPolicyString(sb, R.string.policy_dont_allow_attachments);
-        }
-        if (policy.mRequireManualSyncWhenRoaming) {
-            addPolicyString(sb, R.string.policy_require_manual_sync_roaming);
-        }
-        policy.mProtocolPoliciesEnforced = sb.toString();
         mPolicy = policy;
     }
 
@@ -361,16 +351,26 @@
         if (!passwordEnabled) {
             policy.mPasswordMode = Policy.PASSWORD_MODE_NONE;
         }
+        setPolicy(policy);
 
-        if (!unsupportedList.isEmpty()) {
-            StringBuilder sb = new StringBuilder();
-            for (int res: unsupportedList) {
-                addPolicyString(sb, res);
-            }
-            policy.mProtocolPoliciesUnsupported = sb.toString();
+        // We can only determine whether encryption is supported on device by using isSupported here
+        if (!SecurityPolicyDelegate.isSupported(mService.mContext, policy)) {
+            log("SecurityPolicy reports PolicySet not supported.");
+            mIsSupportable = false;
+            unsupportedList.add(R.string.policy_require_encryption);
         }
 
-        setPolicy(policy);
+        if (!unsupportedList.isEmpty()) {
+            mUnsupportedPolicies = new String[unsupportedList.size()];
+            int i = 0;
+            Context context = ExchangeService.getContext();
+            if (context != null) {
+                Resources resources = context.getResources();
+                for (int res: unsupportedList) {
+                    mUnsupportedPolicies[i++] = resources.getString(res);
+                }
+            }
+        }
     }
 
     /**
diff --git a/src/com/android/exchange/adapter/Search.java b/src/com/android/exchange/adapter/Search.java
index 62cda19..309ff79 100644
--- a/src/com/android/exchange/adapter/Search.java
+++ b/src/com/android/exchange/adapter/Search.java
@@ -17,7 +17,6 @@
 package com.android.exchange.adapter;
 
 import android.content.ContentProviderOperation;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.OperationApplicationException;
 import android.os.RemoteException;
@@ -36,7 +35,6 @@
 import com.android.exchange.EasSyncService;
 import com.android.exchange.ExchangeService;
 import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
-import com.android.mail.providers.UIProvider;
 
 import org.apache.http.HttpStatus;
 
@@ -69,15 +67,10 @@
         if (account == null) return res;
         EasSyncService svc = EasSyncService.setupServiceForAccount(context, account);
         if (svc == null) return res;
-        Mailbox searchMailbox = Mailbox.restoreMailboxWithId(context, destMailboxId);
-        // Sanity check; account might have been deleted?
-        if (searchMailbox == null) return res;
-        ContentValues statusValues = new ContentValues();
         try {
-            // Set the status of this mailbox to indicate query
-            statusValues.put(Mailbox.UI_SYNC_STATUS, UIProvider.SyncStatus.USER_QUERY);
-            searchMailbox.update(context, statusValues);
-
+            Mailbox searchMailbox = Mailbox.restoreMailboxWithId(context, destMailboxId);
+            // Sanity check; account might have been deleted?
+            if (searchMailbox == null) return res;
             svc.mMailbox = searchMailbox;
             svc.mAccount = account;
             Serializer s = new Serializer();
@@ -131,10 +124,6 @@
             svc.userLog("Search exception " + e);
         } finally {
             try {
-                // TODO: Handle error states
-                // Set the status of this mailbox to indicate query over
-                statusValues.put(Mailbox.UI_SYNC_STATUS, UIProvider.SyncStatus.NO_SYNC);
-                searchMailbox.update(context, statusValues);
                 ExchangeService.callback().syncMailboxStatus(destMailboxId,
                         EmailServiceStatus.SUCCESS, 100);
             } catch (RemoteException e) {
diff --git a/exchange1_src/com/android/exchange/provider/MailboxUtilities.java b/src/com/android/exchange/provider/MailboxUtilities.java
similarity index 93%
rename from exchange1_src/com/android/exchange/provider/MailboxUtilities.java
rename to src/com/android/exchange/provider/MailboxUtilities.java
index 6be7920..6089257 100644
--- a/exchange1_src/com/android/exchange/provider/MailboxUtilities.java
+++ b/src/com/android/exchange/provider/MailboxUtilities.java
@@ -130,22 +130,21 @@
 
         // We'll loop through mailboxes with an uninitialized parent key
         ContentResolver resolver = context.getContentResolver();
-        Cursor noParentKeyMailboxCursor =
-                resolver.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
-                        noParentKeySelection, null, null);
-        if (noParentKeyMailboxCursor == null) return;
+        Cursor parentCursor = resolver.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
+                noParentKeySelection, null, null);
+        if (parentCursor == null) return;
         try {
-            while (noParentKeyMailboxCursor.moveToNext()) {
-                setFlagsAndChildrensParentKey(context, noParentKeyMailboxCursor, accountSelector);
+            while (parentCursor.moveToNext()) {
+                setFlagsAndChildrensParentKey(context, parentCursor, accountSelector);
+                // Fix up the parent as well
                 String parentServerId =
-                        noParentKeyMailboxCursor.getString(Mailbox.CONTENT_PARENT_SERVER_ID_COLUMN);
-                // Fixup the parent so that the children's parentKey is updated
+                        parentCursor.getString(Mailbox.CONTENT_PARENT_SERVER_ID_COLUMN);
                 if (parentServerId != null) {
                     setFlagsAndChildrensParentKey(context, accountSelector, parentServerId);
                 }
             }
         } finally {
-            noParentKeyMailboxCursor.close();
+            parentCursor.close();
         }
 
         // Any mailboxes without a parent key should have parentKey set to -1 (no parent)
diff --git a/src/com/android/exchange/utility/CalendarUtilities.java b/src/com/android/exchange/utility/CalendarUtilities.java
index 2302b7a..2f466b8 100644
--- a/src/com/android/exchange/utility/CalendarUtilities.java
+++ b/src/com/android/exchange/utility/CalendarUtilities.java
@@ -35,8 +35,6 @@
 import android.util.Base64;
 import android.util.Log;
 
-import com.android.calendarcommon.DateException;
-import com.android.calendarcommon.Duration;
 import com.android.emailcommon.Logging;
 import com.android.emailcommon.mail.Address;
 import com.android.emailcommon.provider.Account;
@@ -57,6 +55,7 @@
 
 import java.io.IOException;
 import java.text.DateFormat;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
@@ -1497,6 +1496,7 @@
             sb = new StringBuilder();
         }
         Resources resources = context.getResources();
+        Date date = new Date(entityValues.getAsLong(Events.DTSTART));
         // TODO: Add more detail to message text
         // Right now, we're using.. When: Tuesday, March 5th at 2:00pm
         // What we're missing is the duration and any recurrence information.  So this should be
@@ -1514,13 +1514,11 @@
 
         String dateTimeString;
         int res;
-        long startTime = entityValues.getAsLong(Events.DTSTART);
         if (allDayEvent) {
-            Date date = new Date(getLocalAllDayCalendarTime(startTime, TimeZone.getDefault()));
             dateTimeString = DateFormat.getDateInstance().format(date);
             res = recurringEvent ? R.string.meeting_allday_recurring : R.string.meeting_allday;
         } else {
-            dateTimeString = DateFormat.getDateTimeInstance().format(new Date(startTime));
+            dateTimeString = DateFormat.getDateTimeInstance().format(date);
             res = recurringEvent ? R.string.meeting_recurring : R.string.meeting_when;
         }
         sb.append(resources.getString(res, dateTimeString));
@@ -1703,7 +1701,7 @@
                 try {
                     duration.parse(entityValues.getAsString(Events.DURATION));
                     durationMillis = duration.getMillis();
-                } catch (DateException e) {
+                } catch (ParseException e) {
                     // We'll use the default in this case
                 }
                 ics.writeTag("DTEND" + vCalendarDateSuffix,
diff --git a/src/com/android/exchange/utility/Duration.java b/src/com/android/exchange/utility/Duration.java
new file mode 100644
index 0000000..f6e6525
--- /dev/null
+++ b/src/com/android/exchange/utility/Duration.java
@@ -0,0 +1,127 @@
+/* Copyright 2010, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.exchange.utility;
+
+import java.text.ParseException;
+import java.util.Calendar;
+
+/**
+ * Note: This class was simply copied from the class in CalendarProvider, since we don't have access
+ * to it from the Email app.  I reformated some lines, but otherwise haven't altered the code.
+ */
+public class Duration {
+    public int sign; // 1 or -1
+    public int weeks;
+    public int days;
+    public int hours;
+    public int minutes;
+    public int seconds;
+
+    public Duration() {
+        sign = 1;
+    }
+
+    /**
+     * Parse according to RFC2445 ss4.3.6.  (It's actually a little loose with
+     * its parsing, for better or for worse)
+     */
+    public void parse(String str) throws ParseException {
+        sign = 1;
+        weeks = 0;
+        days = 0;
+        hours = 0;
+        minutes = 0;
+        seconds = 0;
+
+        int len = str.length();
+        int index = 0;
+        char c;
+
+        if (len < 1) {
+            return;
+        }
+
+        c = str.charAt(0);
+        if (c == '-') {
+            sign = -1;
+            index++;
+        } else if (c == '+') {
+            index++;
+        }
+
+        if (len < index) {
+            return;
+        }
+
+        c = str.charAt(index);
+        if (c != 'P') {
+            throw new ParseException (
+                    "Duration.parse(str='" + str + "') expected 'P' at index="
+                    + index, index);
+        }
+        index++;
+
+        int n = 0;
+        for (; index < len; index++) {
+            c = str.charAt(index);
+            if (c >= '0' && c <= '9') {
+                n *= 10;
+                n += (c - '0');
+            } else if (c == 'W') {
+                weeks = n;
+                n = 0;
+            } else if (c == 'H') {
+                hours = n;
+                n = 0;
+            } else if (c == 'M') {
+                minutes = n;
+                n = 0;
+            } else if (c == 'S') {
+                seconds = n;
+                n = 0;
+            } else if (c == 'D') {
+                days = n;
+                n = 0;
+            } else if (c == 'T') {
+            } else {
+                throw new ParseException (
+                        "Duration.parse(str='" + str + "') unexpected char '"
+                        + c + "' at index=" + index, index);
+            }
+        }
+    }
+
+    /**
+     * Add this to the calendar provided, in place, in the calendar.
+     */
+    public void addTo(Calendar cal) {
+        cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7);
+        cal.add(Calendar.DAY_OF_MONTH, sign*days);
+        cal.add(Calendar.HOUR, sign*hours);
+        cal.add(Calendar.MINUTE, sign*minutes);
+        cal.add(Calendar.SECOND, sign*seconds);
+    }
+
+    public long addTo(long dt) {
+        return dt + getMillis();
+    }
+
+    public long getMillis() {
+        long factor = 1000 * sign;
+        return factor * ((7*24*60*60*weeks) + (24*60*60*days) + (60*60*hours) + (60*minutes) +
+                seconds);
+    }
+}
diff --git a/tests/src/com/android/exchange/EasSyncServiceTests.java b/tests/src/com/android/exchange/EasSyncServiceTests.java
index 150b1f1..54d76b3 100644
--- a/tests/src/com/android/exchange/EasSyncServiceTests.java
+++ b/tests/src/com/android/exchange/EasSyncServiceTests.java
@@ -128,4 +128,46 @@
         assertEquals("https://" + HOST + "/Microsoft-Server-ActiveSync?Cmd=Sync" +
                 svc.mUserString, uriString);
     }
+
+    public void testResetHeartbeats() {
+        EasSyncService svc = new EasSyncService();
+        // Test case in which the minimum and force heartbeats need to come up
+        svc.mPingMaxHeartbeat = 1000;
+        svc.mPingMinHeartbeat = 200;
+        svc.mPingHeartbeat = 300;
+        svc.mPingForceHeartbeat = 100;
+        svc.mPingHeartbeatDropped = true;
+        svc.resetHeartbeats(400);
+        assertEquals(400, svc.mPingMinHeartbeat);
+        assertEquals(1000, svc.mPingMaxHeartbeat);
+        assertEquals(400, svc.mPingHeartbeat);
+        assertEquals(400, svc.mPingForceHeartbeat);
+        assertFalse(svc.mPingHeartbeatDropped);
+
+        // Test case in which the force heartbeat needs to come up
+        svc.mPingMaxHeartbeat = 1000;
+        svc.mPingMinHeartbeat = 200;
+        svc.mPingHeartbeat = 100;
+        svc.mPingForceHeartbeat = 100;
+        svc.mPingHeartbeatDropped = true;
+        svc.resetHeartbeats(150);
+        assertEquals(200, svc.mPingMinHeartbeat);
+        assertEquals(1000, svc.mPingMaxHeartbeat);
+        assertEquals(150, svc.mPingHeartbeat);
+        assertEquals(150, svc.mPingForceHeartbeat);
+        assertFalse(svc.mPingHeartbeatDropped);
+
+        // Test case in which the maximum needs to come down
+        svc.mPingMaxHeartbeat = 1000;
+        svc.mPingMinHeartbeat = 200;
+        svc.mPingHeartbeat = 800;
+        svc.mPingForceHeartbeat = 100;
+        svc.mPingHeartbeatDropped = true;
+        svc.resetHeartbeats(600);
+        assertEquals(200, svc.mPingMinHeartbeat);
+        assertEquals(600, svc.mPingMaxHeartbeat);
+        assertEquals(600, svc.mPingHeartbeat);
+        assertEquals(100, svc.mPingForceHeartbeat);
+        assertFalse(svc.mPingHeartbeatDropped);
+    }
 }
diff --git a/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java b/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java
index a7425d7..57b5fb9 100644
--- a/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java
+++ b/tests/src/com/android/exchange/provider/MailboxUtilitiesTests.java
@@ -201,7 +201,7 @@
                 "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box2);
         box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED;
         box3.save(mProviderContext);
-        simulateFolderSyncChangeHandling(accountSelector, box3 /*box3's parent*/);
+        simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's parent*/);
 
         box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId);
         box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId);
