diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index f59017c..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-contacts_provider_files := ../ContactsProvider/src/com/android/providers/contacts/ContactsProvider.java
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src) $(contacts_provider_files)
-
-LOCAL_JAVA_LIBRARIES := ext
-
-# We depend on googlelogin-client also, but that is already being included by google-framework
-LOCAL_STATIC_JAVA_LIBRARIES := google-framework
-
-LOCAL_PACKAGE_NAME := GoogleContactsProvider
-LOCAL_CERTIFICATE := shared
-
-LOCAL_OVERRIDES_PACKAGES := ContactsProvider
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
deleted file mode 100644
index a66809f..0000000
--- a/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.providers.contacts"
-        android:sharedUserId="android.uid.shared">
-
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
-    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
-    <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
-    <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.cp" />
-    <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
-    <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" />
-
-    <application android:process="android.process.acore"
-                 android:label="@string/app_label"
-                 android:icon="@drawable/app_icon">
-        <provider android:name="GoogleContactsProvider" android:authorities="contacts;call_log"
-                android:syncable="true" android:multiprocess="false"
-                android:readPermission="android.permission.READ_CONTACTS"
-                android:writePermission="android.permission.WRITE_CONTACTS" />
-        <service android:name="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" />
-        </service>
-    </application>
-</manifest>
diff --git a/res/drawable-hdpi/app_icon.png b/res/drawable-hdpi/app_icon.png
deleted file mode 100755
index 0bcbca4..0000000
--- a/res/drawable-hdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/app_icon.png b/res/drawable-mdpi/app_icon.png
deleted file mode 100644
index 826656f..0000000
--- a/res/drawable-mdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
deleted file mode 100644
index a76af52..0000000
--- a/res/values-cs/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Úložiště kontaktů"</string>
-</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
deleted file mode 100644
index c65fed4..0000000
--- a/res/values-da/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Lagring af kontakter"</string>
-</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
deleted file mode 100644
index 4a21e6e..0000000
--- a/res/values-de/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Kontakte-Speicher"</string>
-</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
deleted file mode 100644
index 31b89b4..0000000
--- a/res/values-el/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Χώρος αποθήκευσης επαφών"</string>
-</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
deleted file mode 100644
index 0170e69..0000000
--- a/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Espacio de almacenamiento para Contactos"</string>
-</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
deleted file mode 100644
index 3a0ebc7..0000000
--- a/res/values-es/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Información de los contactos"</string>
-</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
deleted file mode 100644
index d36d9ff..0000000
--- a/res/values-fr/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Liste des contacts"</string>
-</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
deleted file mode 100644
index fe2b515..0000000
--- a/res/values-it/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Archiviazione contatti"</string>
-</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
deleted file mode 100644
index ae23f6a..0000000
--- a/res/values-ja/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"アドレス帳"</string>
-</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
deleted file mode 100644
index ce2dc72..0000000
--- a/res/values-ko/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"주소록 저장소"</string>
-</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
deleted file mode 100644
index 14733fb..0000000
--- a/res/values-nb/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Kontaktlager"</string>
-</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
deleted file mode 100644
index 8117b29..0000000
--- a/res/values-nl/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Opslag contacten"</string>
-</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
deleted file mode 100644
index 969cfb1..0000000
--- a/res/values-pl/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Spis kontaktów"</string>
-</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 7e34855..0000000
--- a/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Armazenamento de contactos"</string>
-</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
deleted file mode 100644
index 81cd411..0000000
--- a/res/values-pt/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Armazenamento de contatos"</string>
-</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
deleted file mode 100644
index 9b296d9..0000000
--- a/res/values-ru/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Хранилище контактов"</string>
-</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
deleted file mode 100644
index 7cfd0e0..0000000
--- a/res/values-sv/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Kontakter"</string>
-</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
deleted file mode 100644
index f8db006..0000000
--- a/res/values-tr/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"Kişi Deposu"</string>
-</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 64b5bc8..0000000
--- a/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"联系人存储"</string>
-</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 14da964..0000000
--- a/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8174768630168497947">"聯絡人儲存空間"</string>
-</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
deleted file mode 100644
index 2ef1c9a..0000000
--- a/res/values/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- This is the label for the application that stores contacts data -->
-    <string name="app_label">Contacts Storage</string>
-</resources>
diff --git a/res/xml/syncadapter.xml b/res/xml/syncadapter.xml
deleted file mode 100644
index d46be9a..0000000
--- a/res/xml/syncadapter.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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="contacts"
-    android:accountType="com.google"
-/>
diff --git a/src/com/android/providers/contacts/ContactsSyncAdapter.java b/src/com/android/providers/contacts/ContactsSyncAdapter.java
deleted file mode 100644
index c15f2da..0000000
--- a/src/com/android/providers/contacts/ContactsSyncAdapter.java
+++ /dev/null
@@ -1,1295 +0,0 @@
-/*
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** See the License for the specific language governing permissions and
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** limitations under the License.
-*/
-
-package com.android.providers.contacts;
-
-import com.google.android.collect.Sets;
-import com.google.android.gdata.client.AndroidGDataClient;
-import com.google.android.gdata.client.AndroidXmlParserFactory;
-import com.google.android.providers.AbstractGDataSyncAdapter;
-import com.google.wireless.gdata.client.GDataServiceClient;
-import com.google.wireless.gdata.client.QueryParams;
-import com.google.wireless.gdata.client.HttpException;
-import com.google.wireless.gdata.contacts.client.ContactsClient;
-import com.google.wireless.gdata.contacts.data.ContactEntry;
-import com.google.wireless.gdata.contacts.data.ContactsElement;
-import com.google.wireless.gdata.contacts.data.EmailAddress;
-import com.google.wireless.gdata.contacts.data.GroupEntry;
-import com.google.wireless.gdata.contacts.data.GroupMembershipInfo;
-import com.google.wireless.gdata.contacts.data.ImAddress;
-import com.google.wireless.gdata.contacts.data.Organization;
-import com.google.wireless.gdata.contacts.data.PhoneNumber;
-import com.google.wireless.gdata.contacts.data.PostalAddress;
-import com.google.wireless.gdata.contacts.parser.xml.XmlContactsGDataParserFactory;
-import com.google.wireless.gdata.data.Entry;
-import com.google.wireless.gdata.data.ExtendedProperty;
-import com.google.wireless.gdata.data.Feed;
-import com.google.wireless.gdata.data.MediaEntry;
-import com.google.wireless.gdata.parser.ParseException;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.content.ContentProvider;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SyncContext;
-import android.content.SyncResult;
-import android.content.SyncableContentProvider;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.provider.Contacts;
-import android.provider.Contacts.ContactMethods;
-import android.provider.Contacts.Extensions;
-import android.provider.Contacts.GroupMembership;
-import android.provider.Contacts.Groups;
-import android.provider.Contacts.Organizations;
-import android.provider.Contacts.People;
-import android.provider.Contacts.Phones;
-import android.provider.Contacts.Photos;
-import android.provider.SubscribedFeeds;
-import android.provider.SyncConstValue;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-import android.accounts.AccountManager;
-import android.accounts.Account;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implements a SyncAdapter for Contacts
- */
-public class ContactsSyncAdapter extends AbstractGDataSyncAdapter {
-
-    private static final String USER_AGENT_APP_VERSION = "Android-GData-Contacts/1.1"; 
-
-    private static final String CONTACTS_FEED_URL = "http://www.google.com/m8/feeds/contacts/";
-    private static final String GROUPS_FEED_URL = "http://www.google.com/m8/feeds/groups/";
-    private static final String PHOTO_FEED_URL = "http://www.google.com/m8/feeds/photos/media/";
-
-    private final ContactsClient mContactsClient;
-
-    private static final String[] sSubscriptionProjection =
-            new String[] {
-                    SubscribedFeeds.Feeds._SYNC_ACCOUNT,
-                    SubscribedFeeds.Feeds.FEED,
-                    SubscribedFeeds.Feeds._ID};
-
-    private static final HashMap<Byte, Integer> ENTRY_TYPE_TO_PROVIDER_PHONE;
-    private static final HashMap<Byte, Integer> ENTRY_TYPE_TO_PROVIDER_EMAIL;
-    private static final HashMap<Byte, Integer> ENTRY_TYPE_TO_PROVIDER_IM;
-    private static final HashMap<Byte, Integer> ENTRY_TYPE_TO_PROVIDER_POSTAL;
-    private static final HashMap<Byte, Integer> ENTRY_TYPE_TO_PROVIDER_ORGANIZATION;
-    private static final HashMap<Integer, Byte> PROVIDER_TYPE_TO_ENTRY_PHONE;
-    private static final HashMap<Integer, Byte> PROVIDER_TYPE_TO_ENTRY_EMAIL;
-    private static final HashMap<Integer, Byte> PROVIDER_TYPE_TO_ENTRY_IM;
-    private static final HashMap<Integer, Byte> PROVIDER_TYPE_TO_ENTRY_POSTAL;
-    private static final HashMap<Integer, Byte> PROVIDER_TYPE_TO_ENTRY_ORGANIZATION;
-
-    private static final HashMap<Byte, Integer> ENTRY_IM_PROTOCOL_TO_PROVIDER_PROTOCOL;
-    private static final HashMap<Integer, Byte> PROVIDER_IM_PROTOCOL_TO_ENTRY_PROTOCOL;
-
-    private static final int MAX_MEDIA_ENTRIES_PER_SYNC = 10;
-
-    // Only valid during a sync operation.
-    // If set then a getServerDiffs() was performed during this sync.
-    private boolean mPerformedGetServerDiffs;
-
-    // Only valid during a sync. If set then this sync was a forced sync request
-    private boolean mIsManualSync;
-
-    private int mPhotoDownloads;
-    private int mPhotoUploads;
-
-    private static final String IMAGE_MIME_TYPE = "image/*";
-
-    static {
-        HashMap<Byte, Integer> map;
-
-        map = new HashMap<Byte, Integer>();
-        map.put(ImAddress.PROTOCOL_AIM, ContactMethods.PROTOCOL_AIM);
-        map.put(ImAddress.PROTOCOL_GOOGLE_TALK, ContactMethods.PROTOCOL_GOOGLE_TALK);
-        map.put(ImAddress.PROTOCOL_ICQ, ContactMethods.PROTOCOL_ICQ);
-        map.put(ImAddress.PROTOCOL_JABBER, ContactMethods.PROTOCOL_JABBER);
-        map.put(ImAddress.PROTOCOL_MSN, ContactMethods.PROTOCOL_MSN);
-        map.put(ImAddress.PROTOCOL_QQ, ContactMethods.PROTOCOL_QQ);
-        map.put(ImAddress.PROTOCOL_SKYPE, ContactMethods.PROTOCOL_SKYPE);
-        map.put(ImAddress.PROTOCOL_YAHOO, ContactMethods.PROTOCOL_YAHOO);
-        ENTRY_IM_PROTOCOL_TO_PROVIDER_PROTOCOL = map;
-        PROVIDER_IM_PROTOCOL_TO_ENTRY_PROTOCOL = swapMap(map);
-
-        map = new HashMap<Byte, Integer>();
-        map.put(EmailAddress.TYPE_HOME, ContactMethods.TYPE_HOME);
-        map.put(EmailAddress.TYPE_WORK, ContactMethods.TYPE_WORK);
-        map.put(EmailAddress.TYPE_OTHER, ContactMethods.TYPE_OTHER);
-        map.put(EmailAddress.TYPE_NONE, ContactMethods.TYPE_CUSTOM);
-        ENTRY_TYPE_TO_PROVIDER_EMAIL = map;
-        PROVIDER_TYPE_TO_ENTRY_EMAIL = swapMap(map);
-
-        map = new HashMap<Byte, Integer>();
-        map.put(PhoneNumber.TYPE_HOME, Phones.TYPE_HOME);
-        map.put(PhoneNumber.TYPE_MOBILE, Phones.TYPE_MOBILE);
-        map.put(PhoneNumber.TYPE_PAGER, Phones.TYPE_PAGER);
-        map.put(PhoneNumber.TYPE_WORK, Phones.TYPE_WORK);
-        map.put(PhoneNumber.TYPE_HOME_FAX, Phones.TYPE_FAX_HOME);
-        map.put(PhoneNumber.TYPE_WORK_FAX, Phones.TYPE_FAX_WORK);
-        map.put(PhoneNumber.TYPE_OTHER, Phones.TYPE_OTHER);
-        map.put(PhoneNumber.TYPE_NONE, Phones.TYPE_CUSTOM);
-        ENTRY_TYPE_TO_PROVIDER_PHONE = map;
-        PROVIDER_TYPE_TO_ENTRY_PHONE = swapMap(map);
-
-        map = new HashMap<Byte, Integer>();
-        map.put(PostalAddress.TYPE_HOME, ContactMethods.TYPE_HOME);
-        map.put(PostalAddress.TYPE_WORK, ContactMethods.TYPE_WORK);
-        map.put(PostalAddress.TYPE_OTHER, ContactMethods.TYPE_OTHER);
-        map.put(PostalAddress.TYPE_NONE, ContactMethods.TYPE_CUSTOM);
-        ENTRY_TYPE_TO_PROVIDER_POSTAL = map;
-        PROVIDER_TYPE_TO_ENTRY_POSTAL = swapMap(map);
-
-        map = new HashMap<Byte, Integer>();
-        map.put(ImAddress.TYPE_HOME, ContactMethods.TYPE_HOME);
-        map.put(ImAddress.TYPE_WORK, ContactMethods.TYPE_WORK);
-        map.put(ImAddress.TYPE_OTHER, ContactMethods.TYPE_OTHER);
-        map.put(ImAddress.TYPE_NONE, ContactMethods.TYPE_CUSTOM);
-        ENTRY_TYPE_TO_PROVIDER_IM = map;
-        PROVIDER_TYPE_TO_ENTRY_IM = swapMap(map);
-
-        map = new HashMap<Byte, Integer>();
-        map.put(Organization.TYPE_WORK, Organizations.TYPE_WORK);
-        map.put(Organization.TYPE_OTHER, Organizations.TYPE_OTHER);
-        map.put(Organization.TYPE_NONE, Organizations.TYPE_CUSTOM);
-        ENTRY_TYPE_TO_PROVIDER_ORGANIZATION = map;
-        PROVIDER_TYPE_TO_ENTRY_ORGANIZATION = swapMap(map);
-    }
-
-    private static <A, B> HashMap<B, A> swapMap(HashMap<A, B> originalMap) {
-        HashMap<B, A> newMap = new HashMap<B,A>();
-        for (Map.Entry<A, B> entry : originalMap.entrySet()) {
-            final B originalValue = entry.getValue();
-            if (newMap.containsKey(originalValue)) {
-                throw new IllegalArgumentException("value " + originalValue
-                        + " was already encountered");
-            }
-            newMap.put(originalValue, entry.getKey());
-        }
-        return newMap;
-    }
-
-    protected ContactsSyncAdapter(Context context, SyncableContentProvider provider) {
-        super(context, provider);
-        mContactsClient = new ContactsClient(
-                new AndroidGDataClient(context, USER_AGENT_APP_VERSION),
-                new XmlContactsGDataParserFactory(new AndroidXmlParserFactory()));
-    }
-
-    protected GDataServiceClient getGDataServiceClient() {
-        return mContactsClient;
-    }
-
-    @Override
-    protected Entry newEntry() {
-        throw new UnsupportedOperationException("this should never be used");
-    }
-
-    protected String getFeedUrl(Account account) {
-        throw new UnsupportedOperationException("this should never be used");
-    }
-
-    protected Class getFeedEntryClass() {
-        throw new UnsupportedOperationException("this should never be used");
-    }
-
-    protected Class getFeedEntryClass(String feed) {
-        if (feed.startsWith(rewriteUrlforAccount(getAccount(), GROUPS_FEED_URL))) {
-            return GroupEntry.class;
-        }
-        if (feed.startsWith(rewriteUrlforAccount(getAccount(), CONTACTS_FEED_URL))) {
-            return ContactEntry.class;
-        }
-        return null;
-    }
-
-    @Override
-    public void getServerDiffs(SyncContext context, SyncData baseSyncData,
-            SyncableContentProvider tempProvider,
-            Bundle extras, Object syncInfo, SyncResult syncResult) {
-        mPerformedGetServerDiffs = true;
-        GDataSyncData syncData = (GDataSyncData)baseSyncData;
-
-        ArrayList<String> feedsToSync = new ArrayList<String>();
-
-        if (extras != null && extras.containsKey("feed")) {
-            feedsToSync.add((String) extras.get("feed"));
-        } else {
-            feedsToSync.add(getGroupsFeedForAccount(getAccount()));
-            addContactsFeedsToSync(getContext().getContentResolver(), getAccount(), feedsToSync);
-            feedsToSync.add(getPhotosFeedForAccount(getAccount()));
-        }
-
-        for (String feed : feedsToSync) {
-            context.setStatusText("Downloading\u2026");
-            if (getPhotosFeedForAccount(getAccount()).equals(feed)) {
-                getServerPhotos(context, feed, MAX_MEDIA_ENTRIES_PER_SYNC, syncData, syncResult);
-            } else {
-                final Class feedEntryClass = getFeedEntryClass(feed);
-                if (feedEntryClass != null) {
-                    getServerDiffsImpl(context, tempProvider, feedEntryClass,
-                            feed, null, getMaxEntriesPerSync(), syncData, syncResult);
-                } else {
-                    if (Config.LOGD) {
-                        Log.d(TAG, "ignoring sync request for unknown feed " + feed);
-                    }
-                }
-            }
-            if (syncResult.hasError()) {
-                break;
-            }
-        }
-    }
-
-    /**
-     * Look at the groups sync settings and the overall sync preference to determine which
-     * feeds to sync and add them to the feedsToSync list.
-     */
-    public static void addContactsFeedsToSync(ContentResolver cr, Account account,
-            Collection<String> feedsToSync) {
-        boolean shouldSyncEverything = getShouldSyncEverything(cr, account);
-        if (shouldSyncEverything) {
-            feedsToSync.add(getContactsFeedForAccount(account));
-            return;
-        }
-
-        Cursor cursor = cr.query(Contacts.Groups.CONTENT_URI, new String[]{Groups._SYNC_ID},
-                "_sync_account=? AND _sync_account_type=? AND should_sync>0",
-                new String[]{account.name, account.type}, null);
-        try {
-            while (cursor.moveToNext()) {
-                feedsToSync.add(getContactsFeedForGroup(account, cursor.getString(0)));
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    private static boolean getShouldSyncEverything(ContentResolver cr, Account account) {
-        // TODO(fredq) should be using account instead of null
-        String value = Contacts.Settings.getSetting(cr, null, Contacts.Settings.SYNC_EVERYTHING);
-        return !TextUtils.isEmpty(value) && !"0".equals(value);
-    }
-
-    private void getServerPhotos(SyncContext context, String feedUrl, int maxDownloads,
-            GDataSyncData syncData, SyncResult syncResult) {
-        final ContentResolver cr = getContext().getContentResolver();
-        final Account account = getAccount();
-        Cursor cursor = cr.query(
-                Photos.CONTENT_URI,
-                new String[]{Photos._SYNC_ID, Photos._SYNC_VERSION, Photos.PERSON_ID,
-                        Photos.DOWNLOAD_REQUIRED, Photos._ID}, ""
-                + "_sync_account=? AND _sync_account_type=? AND download_required != 0",
-                new String[]{account.name, account.type}, null);
-        try {
-            int numFetched = 0;
-            while (cursor.moveToNext()) {
-                if (numFetched >= maxDownloads) {
-                    break;
-                }
-                String photoSyncId = cursor.getString(0);
-                String photoVersion = cursor.getString(1);
-                long person = cursor.getLong(2);
-                String photoUrl = feedUrl + "/" + photoSyncId;
-                long photoId = cursor.getLong(4);
-
-                try {
-                    context.setStatusText("Downloading photo " + photoSyncId);
-                    ++numFetched;
-                    ++mPhotoDownloads;
-                    InputStream inputStream = mContactsClient.getMediaEntryAsStream(
-                            photoUrl, getAuthToken());
-                    savePhoto(person, inputStream, photoVersion);
-                    syncResult.stats.numUpdates++;
-                } catch (IOException e) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.d(TAG, "error downloading " + photoUrl, e);
-                    }
-                    syncResult.stats.numIoExceptions++;
-                    return;
-                } catch (HttpException e) {
-                    switch (e.getStatusCode()) {
-                        case HttpException.SC_UNAUTHORIZED:
-                            if (Config.LOGD) {
-                                Log.d(TAG, "not authorized to download " + photoUrl, e);
-                            }
-                            syncResult.stats.numAuthExceptions++;
-                            return;
-                        case HttpException.SC_FORBIDDEN:
-                        case HttpException.SC_NOT_FOUND:
-                            final String exceptionMessage = e.getMessage();
-                            if (Config.LOGD) {
-                                Log.d(TAG, "unable to download photo " + photoUrl + ", "
-                                        + exceptionMessage + ", ignoring");
-                            }
-                            ContentValues values = new ContentValues();
-                            values.put(Photos.SYNC_ERROR, exceptionMessage);
-                            Uri photoUri = Uri.withAppendedPath(
-                                    ContentUris.withAppendedId(People.CONTENT_URI, photoId),
-                                    Photos.CONTENT_DIRECTORY);
-                            cr.update(photoUri, values, null /* where */, null /* where args */);
-                            break;
-                        default:
-                            if (Config.LOGD) {
-                                Log.d(TAG, "error downloading " + photoUrl, e);
-                            }
-                            syncResult.stats.numIoExceptions++;
-                            return;
-                    }
-                }
-            }
-            final boolean hasMoreToSync = numFetched < cursor.getCount();
-            GDataSyncData.FeedData feedData =
-                    new GDataSyncData.FeedData(0  /* no update time */,
-                            numFetched, hasMoreToSync, null /* no lastId */,
-                            0 /* no feed index */);
-            syncData.feedData.put(feedUrl, feedData);
-        } finally {
-            cursor.close();
-        }
-    }
-
-    @Override
-    protected void getStatsString(StringBuffer sb, SyncResult result) {
-        super.getStatsString(sb, result);
-        if (mPhotoUploads > 0) {
-            sb.append("p").append(mPhotoUploads);
-        }
-        if (mPhotoDownloads > 0) {
-            sb.append("P").append(mPhotoDownloads);
-        }
-    }
-
-    @Override
-    public void sendClientDiffs(SyncContext context, SyncableContentProvider clientDiffs,
-            SyncableContentProvider serverDiffs, SyncResult syncResult,
-            boolean dontSendDeletes) {
-        initTempProvider(clientDiffs);
-
-        sendClientDiffsImpl(context, clientDiffs, new GroupEntry(), null /* no syncInfo */,
-                serverDiffs, syncResult, dontSendDeletes);
-
-        // lets go ahead and commit what we have if we successfully made a change
-        if (syncResult.madeSomeProgress()) {
-            return;
-        }
-
-        sendClientPhotos(context, clientDiffs, null /* no syncInfo */, syncResult);
-
-        // lets go ahead and commit what we have if we successfully made a change
-        if (syncResult.madeSomeProgress()) {
-            return;
-        }
-
-        sendClientDiffsImpl(context, clientDiffs, new ContactEntry(), null /* no syncInfo */,
-                serverDiffs, syncResult, dontSendDeletes);
-    }
-
-    protected void sendClientPhotos(SyncContext context, ContentProvider clientDiffs,
-            Object syncInfo, SyncResult syncResult) {
-        Entry entry = new MediaEntry();
-
-        GDataServiceClient client = getGDataServiceClient();
-        String authToken = getAuthToken();
-        ContentResolver cr = getContext().getContentResolver();
-        final Account account = getAccount();
-
-        Cursor c = clientDiffs.query(Photos.CONTENT_URI, null /* all columns */,
-                null /* no where */, null /* no where args */, null /* default sort order */);
-        try {
-            int personColumn = c.getColumnIndexOrThrow(Photos.PERSON_ID);
-            int dataColumn = c.getColumnIndexOrThrow(Photos.DATA);
-            int numRows = c.getCount();
-            while (c.moveToNext()) {
-                if (mSyncCanceled) {
-                    if (Config.LOGD) Log.d(TAG, "stopping since the sync was canceled");
-                    break;
-                }
-
-                entry.clear();
-                context.setStatusText("Updating, " + (numRows - 1) + " to go");
-
-                cursorToBaseEntry(entry, account, c);
-                String editUrl = entry.getEditUri();
-
-                if (TextUtils.isEmpty(editUrl)) {
-                    if (Config.LOGD) {
-                        Log.d(TAG, "skipping photo edit for unsynced contact");
-                    }
-                    continue;
-                }
-
-                // Send the request and receive the response
-                InputStream inputStream = null;
-                byte[] imageData = c.getBlob(dataColumn);
-                if (imageData != null) {
-                    inputStream = new ByteArrayInputStream(imageData);
-                }
-                Uri photoUri = Uri.withAppendedPath(People.CONTENT_URI,
-                        c.getString(personColumn) + "/" + Photos.CONTENT_DIRECTORY);
-                try {
-                    if (inputStream != null) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "Updating photo " + entry.toString());
-                        }
-                        ++mPhotoUploads;
-                        client.updateMediaEntry(editUrl, inputStream, IMAGE_MIME_TYPE, authToken);
-                    } else {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "Deleting photo " + entry.toString());
-                        }
-                        client.deleteEntry(editUrl, authToken);
-                    }
-
-                    // Mark that this photo is no longer dirty. The next time we sync (which
-                    // should be soon), we will get the new version of the photo and whether
-                    // or not there is a new one to download (e.g. if we deleted our version
-                    // yet there is an evergreen version present).
-                    ContentValues values = new ContentValues();
-                    values.put(Photos.EXISTS_ON_SERVER, inputStream == null ? 0 : 1);
-                    values.put(Photos._SYNC_DIRTY, 0);
-                    if (cr.update(photoUri, values,
-                            null /* no where */, null /* no where args */) != 1) {
-                        Log.e(TAG, "error updating photo " + photoUri + " with values " + values);
-                        syncResult.stats.numParseExceptions++;
-                    } else {
-                        syncResult.stats.numUpdates++;
-                    }
-                    continue;
-                } catch (ParseException e) {
-                    Log.e(TAG, "parse error during update of " + ", skipping");
-                    syncResult.stats.numParseExceptions++;
-                } catch (IOException e) {
-                    if (Config.LOGD) {
-                        Log.d(TAG, "io error during update of " + entry.toString()
-                                + ", skipping");
-                    }
-                    syncResult.stats.numIoExceptions++;
-                } catch (HttpException e) {
-                    switch (e.getStatusCode()) {
-                        case HttpException.SC_UNAUTHORIZED:
-                            if (syncResult.stats.numAuthExceptions == 0) {
-                                if (Config.LOGD) {
-                                   Log.d(TAG, "auth error during update of " + entry
-                                           + ", skipping");
-                                }
-                            }
-                            syncResult.stats.numAuthExceptions++;
-                            AccountManager.get(getContext()).invalidateAuthToken(
-                                    "com.google", authToken);
-                            return;
-
-                        case HttpException.SC_CONFLICT:
-                            if (Config.LOGD) {
-                                Log.d(TAG, "conflict detected during update of " + entry
-                                        + ", skipping");
-                            }
-                            syncResult.stats.numConflictDetectedExceptions++;
-                            break;
-                        case HttpException.SC_BAD_REQUEST:
-                        case HttpException.SC_FORBIDDEN:
-                        case HttpException.SC_NOT_FOUND:
-                        case HttpException.SC_INTERNAL_SERVER_ERROR:
-                        default:
-                            if (Config.LOGD) {
-                                Log.d(TAG, "error " + e.getMessage() + " during update of "
-                                        + entry.toString() + ", skipping");
-                            }
-                            syncResult.stats.numIoExceptions++;
-                    }
-                }
-            }
-        } finally {
-            c.close();
-        }
-    }
-
-    @Override
-    protected Cursor getCursorForTable(ContentProvider cp, Class entryClass) {
-        return getCursorForTableImpl(cp, entryClass);
-    }
-
-    protected static Cursor getCursorForTableImpl(ContentProvider cp, Class entryClass) {
-        if (entryClass == ContactEntry.class) {
-            return cp.query(People.CONTENT_URI, null, null, null, null);
-        }
-        if (entryClass == GroupEntry.class) {
-            return cp.query(Groups.CONTENT_URI, null, null, null, null);
-        }
-        throw new IllegalArgumentException("unexpected entry class, " + entryClass.getName());
-    }
-
-    @Override
-    protected Cursor getCursorForDeletedTable(ContentProvider cp, Class entryClass) {
-        return getCursorForDeletedTableImpl(cp, entryClass);
-    }
-
-    protected static Cursor getCursorForDeletedTableImpl(ContentProvider cp, Class entryClass) {
-        if (entryClass == ContactEntry.class) {
-            return cp.query(People.DELETED_CONTENT_URI, null, null, null, null);
-        }
-        if (entryClass == GroupEntry.class) {
-            return cp.query(Groups.DELETED_CONTENT_URI, null, null, null, null);
-        }
-        throw new IllegalArgumentException("unexpected entry class, " + entryClass.getName());
-    }
-
-    @Override
-    protected String cursorToEntry(SyncContext context, Cursor c, Entry baseEntry,
-            Object syncInfo) throws ParseException {
-        return cursorToEntryImpl(getContext().getContentResolver(), c, baseEntry, getAccount());
-    }
-
-    static protected String cursorToEntryImpl(ContentResolver cr, Cursor c, Entry entry,
-            Account account) throws ParseException {
-        cursorToBaseEntry(entry, account, c);
-        String createUrl = null;
-        if (entry instanceof ContactEntry) {
-            cursorToContactEntry(account, cr, c, (ContactEntry) entry);
-            if (entry.getEditUri() == null) {
-                createUrl = getContactsFeedForAccount(account);
-            }
-        } else if (entry instanceof MediaEntry) {
-            if (entry.getEditUri() == null) {
-                createUrl = getPhotosFeedForAccount(account);
-            }
-        } else {
-            cursorToGroupEntry(c, (GroupEntry) entry);
-            if (entry.getEditUri() == null) {
-                createUrl = getGroupsFeedForAccount(account);
-            }
-        }
-
-        return createUrl;
-    }
-
-    private static void cursorToGroupEntry(Cursor c, GroupEntry entry) throws ParseException {
-        if (!TextUtils.isEmpty(c.getString(c.getColumnIndexOrThrow(Groups.SYSTEM_ID)))) {
-            throw new ParseException("unable to modify system groups");
-        }
-        entry.setTitle(c.getString(c.getColumnIndexOrThrow(Groups.NAME)));
-        entry.setContent(c.getString(c.getColumnIndexOrThrow(Groups.NOTES)));
-        entry.setSystemGroup(null);
-    }
-
-    private static void cursorToContactEntry(Account account, ContentResolver cr, Cursor c,
-            ContactEntry entry)
-            throws ParseException {
-        entry.setTitle(c.getString(c.getColumnIndexOrThrow(People.NAME)));
-        entry.setContent(c.getString(c.getColumnIndexOrThrow(People.NOTES)));
-        entry.setYomiName(c.getString(c.getColumnIndexOrThrow(People.PHONETIC_NAME)));
-
-        long syncLocalId = c.getLong(c.getColumnIndexOrThrow(SyncConstValue._SYNC_LOCAL_ID));
-        addContactMethodsToContactEntry(cr, syncLocalId, entry);
-        addPhonesToContactEntry(cr, syncLocalId, entry);
-        addOrganizationsToContactEntry(cr, syncLocalId, entry);
-        addGroupMembershipToContactEntry(account, cr, syncLocalId, entry);
-        addExtensionsToContactEntry(cr, syncLocalId, entry);
-    }
-
-    @Override
-    protected void deletedCursorToEntry(SyncContext context, Cursor c, Entry entry) {
-        deletedCursorToEntryImpl(c, entry, getAccount());
-    }
-
-    protected boolean handleAllDeletedUnavailable(GDataSyncData syncData, String feed) {
-        // Contacts has no way to clear the contacts for just a given feed so it is unable
-        // to handle this condition itself. Instead it returns false, which tell the
-        // sync framework that it must handle it.
-        return false;
-    }
-
-    protected static void deletedCursorToEntryImpl(Cursor c, Entry entry, Account account) {
-        cursorToBaseEntry(entry, account, c);
-    }
-
-    private static void cursorToBaseEntry(Entry entry, Account account, Cursor c) {
-        String feedUrl;
-        if (entry instanceof ContactEntry) {
-            feedUrl = getContactsFeedForAccount(account);
-        } else if (entry instanceof GroupEntry) {
-            feedUrl = getGroupsFeedForAccount(account);
-        } else if (entry instanceof MediaEntry) {
-            feedUrl = getPhotosFeedForAccount(account);
-        } else {
-            throw new IllegalArgumentException("bad entry type: " + entry.getClass().getName());
-        }
-
-        String syncId = c.getString(c.getColumnIndexOrThrow(SyncConstValue._SYNC_ID));
-        if (syncId != null) {
-            String syncVersion = c.getString(c.getColumnIndexOrThrow(SyncConstValue._SYNC_VERSION));
-            entry.setId(feedUrl + "/" + syncId);
-            entry.setEditUri(entry.getId() + "/" + syncVersion);
-        }
-    }
-
-    private static void addPhonesToContactEntry(ContentResolver cr, long personId,
-                                                ContactEntry entry)
-            throws ParseException {
-        Cursor c = cr.query(Phones.CONTENT_URI, null, "person=" + personId, null, null);
-        int numberIndex = c.getColumnIndexOrThrow(People.Phones.NUMBER);
-        try {
-            while (c.moveToNext()) {
-                PhoneNumber phoneNumber = new PhoneNumber();
-                cursorToContactsElement(phoneNumber, c, PROVIDER_TYPE_TO_ENTRY_PHONE);
-                phoneNumber.setPhoneNumber(c.getString(numberIndex));
-                entry.addPhoneNumber(phoneNumber);
-            }
-        } finally {
-            if (c != null) c.close();
-        }
-    }
-
-
-    static private void addContactMethodsToContactEntry(ContentResolver cr, long personId,
-            ContactEntry entry) throws ParseException {
-        Cursor c = cr.query(ContactMethods.CONTENT_URI, null,
-                "person=" + personId, null, null);
-        int kindIndex = c.getColumnIndexOrThrow(ContactMethods.KIND);
-        int dataIndex = c.getColumnIndexOrThrow(ContactMethods.DATA);
-        int auxDataIndex = c.getColumnIndexOrThrow(ContactMethods.AUX_DATA);
-        try {
-            while (c.moveToNext()) {
-                int kind = c.getInt(kindIndex);
-                switch (kind) {
-                    case Contacts.KIND_IM: {
-                        ImAddress address = new ImAddress();
-                        cursorToContactsElement(address, c, PROVIDER_TYPE_TO_ENTRY_IM);
-                        address.setAddress(c.getString(dataIndex));
-                        Object object = ContactMethods.decodeImProtocol(c.getString(auxDataIndex));
-                        if (object == null) {
-                            address.setProtocolPredefined(ImAddress.PROTOCOL_NONE);
-                        } else if (object instanceof Integer) {
-                            address.setProtocolPredefined(
-                                    PROVIDER_IM_PROTOCOL_TO_ENTRY_PROTOCOL.get((Integer)object));
-                        } else {
-                            if (!(object instanceof String)) {
-                                throw new IllegalArgumentException("expected an String, " + object);
-                            }
-                            address.setProtocolPredefined(ImAddress.PROTOCOL_CUSTOM);
-                            address.setProtocolCustom((String)object);
-                        }
-                        entry.addImAddress(address);
-                        break;
-                    }
-                    case Contacts.KIND_POSTAL: {
-                        PostalAddress address = new PostalAddress();
-                        cursorToContactsElement(address, c, PROVIDER_TYPE_TO_ENTRY_POSTAL);
-                        address.setValue(c.getString(dataIndex));
-                        entry.addPostalAddress(address);
-                        break;
-                    }
-                    case Contacts.KIND_EMAIL: {
-                        EmailAddress address = new EmailAddress();
-                        cursorToContactsElement(address, c, PROVIDER_TYPE_TO_ENTRY_EMAIL);
-                        address.setAddress(c.getString(dataIndex));
-                        entry.addEmailAddress(address);
-                        break;
-                    }
-                }
-            }
-        } finally {
-            if (c != null) c.close();
-        }
-    }
-
-    private static void addOrganizationsToContactEntry(ContentResolver cr, long personId,
-            ContactEntry entry) throws ParseException {
-        Cursor c = cr.query(Organizations.CONTENT_URI, null,
-                "person=" + personId, null, null);
-        try {
-            int companyIndex = c.getColumnIndexOrThrow(Organizations.COMPANY);
-            int titleIndex = c.getColumnIndexOrThrow(Organizations.TITLE);
-            while (c.moveToNext()) {
-                Organization organization = new Organization();
-                cursorToContactsElement(organization, c, PROVIDER_TYPE_TO_ENTRY_ORGANIZATION);
-                organization.setName(c.getString(companyIndex));
-                organization.setTitle(c.getString(titleIndex));
-                entry.addOrganization(organization);
-            }
-        } finally {
-            if (c != null) c.close();
-        }
-    }
-
-    private static void addGroupMembershipToContactEntry(Account account, ContentResolver cr,
-            long personId, ContactEntry entry) throws ParseException {
-        Cursor c = cr.query(GroupMembership.RAW_CONTENT_URI, null,
-                "person=" + personId, null, null);
-        try {
-            int serverIdIndex = c.getColumnIndexOrThrow(GroupMembership.GROUP_SYNC_ID);
-            int localIdIndex = c.getColumnIndexOrThrow(GroupMembership.GROUP_ID);
-            while (c.moveToNext()) {
-                String serverId = c.getString(serverIdIndex);
-                if (serverId == null) {
-                    final Uri groupUri = ContentUris
-                            .withAppendedId(Groups.CONTENT_URI, c.getLong(localIdIndex));
-                    Cursor groupCursor = cr.query(groupUri, new String[]{Groups._SYNC_ID},
-                            null, null, null);
-                    try {
-                        if (groupCursor.moveToNext()) {
-                            serverId = groupCursor.getString(0);
-                        }
-                    } finally {
-                        groupCursor.close();
-                    }
-                }
-                if (serverId == null) {
-                    // the group hasn't been synced yet, we can't complete this operation since
-                    // we don't know what server id to use for the group
-                    throw new ParseException("unable to construct GroupMembershipInfo since the "
-                            + "group _sync_id isn't known yet, will retry later");
-                }
-                GroupMembershipInfo groupMembershipInfo = new GroupMembershipInfo();
-                String groupId = getCanonicalGroupsFeedForAccount(account) + "/" + serverId;
-                groupMembershipInfo.setGroup(groupId);
-                groupMembershipInfo.setDeleted(false);
-                entry.addGroup(groupMembershipInfo);
-            }
-        } finally {
-            if (c != null) c.close();
-        }
-    }
-
-    private static void addExtensionsToContactEntry(ContentResolver cr, long personId,
-            ContactEntry entry) throws ParseException {
-        Cursor c = cr.query(Extensions.CONTENT_URI, null, "person=" + personId, null, null);
-        try {
-            JSONObject jsonObject = new JSONObject();
-            int nameIndex = c.getColumnIndexOrThrow(Extensions.NAME);
-            int valueIndex = c.getColumnIndexOrThrow(Extensions.VALUE);
-            if (c.getCount() == 0) return;
-            while (c.moveToNext()) {
-                try {
-                    jsonObject.put(c.getString(nameIndex), c.getString(valueIndex));
-                } catch (JSONException e) {
-                    throw new ParseException("bad key or value", e);
-                }
-            }
-            ExtendedProperty extendedProperty = new ExtendedProperty();
-            extendedProperty.setName("android");
-            final String jsonString = jsonObject.toString();
-            if (jsonString == null) {
-                throw new ParseException("unable to convert cursor into a JSON string, "
-                        + DatabaseUtils.dumpCursorToString(c));
-            }
-            extendedProperty.setXmlBlob(jsonString);
-            entry.addExtendedProperty(extendedProperty);
-        } finally {
-            if (c != null) c.close();
-        }
-    }
-
-    private static void cursorToContactsElement(ContactsElement element,
-            Cursor c, HashMap<Integer, Byte> map) {
-        final int typeIndex = c.getColumnIndexOrThrow("type");
-        final int labelIndex = c.getColumnIndexOrThrow("label");
-        final int isPrimaryIndex = c.getColumnIndexOrThrow("isprimary");
-
-        element.setLabel(c.getString(labelIndex));
-        element.setType(map.get(c.getInt(typeIndex)));
-        element.setIsPrimary(c.getInt(isPrimaryIndex) != 0);
-    }
-
-    private static void contactsElementToValues(ContentValues values, ContactsElement element,
-            HashMap<Byte, Integer> map) {
-        values.put("type", map.get(element.getType()));
-        values.put("label", element.getLabel());
-        values.put("isprimary", element.isPrimary() ? 1 : 0);
-    }
-
-    /*
-     * Takes the entry, casts it to a ContactEntry and executes the appropriate
-     * actions on the ContentProvider to represent the entry.
-     */
-    protected void updateProvider(Feed feed, Long syncLocalId,
-            Entry baseEntry, ContentProvider provider, Object syncInfo,
-            GDataSyncData.FeedData feedSyncData) throws ParseException {
-
-        // This is a hack to delete these incorrectly created contacts named "Starred in Android"
-        if (baseEntry instanceof ContactEntry
-                && "Starred in Android".equals(baseEntry.getTitle())) {
-            Log.i(TAG, "Deleting incorrectly created contact from the server: " + baseEntry);
-            GDataServiceClient client = getGDataServiceClient();
-            try {
-                client.deleteEntry(baseEntry.getEditUri(), getAuthToken());
-            } catch (IOException e) {
-                Log.i(TAG, "  exception while deleting contact: " + baseEntry, e);
-            } catch (com.google.wireless.gdata.client.HttpException e) {
-                Log.i(TAG, "  exception while deleting contact: " + baseEntry, e);
-            }
-        }
-
-        updateProviderImpl(getAccount(), syncLocalId, baseEntry, provider);
-    }
-
-    protected static void updateProviderImpl(Account account, Long syncLocalId,
-            Entry entry, ContentProvider provider) throws ParseException {
-        // If this is a deleted entry then add it to the DELETED_CONTENT_URI
-        ContentValues deletedValues = null;
-        if (entry.isDeleted()) {
-            deletedValues = new ContentValues();
-            deletedValues.put(SyncConstValue._SYNC_LOCAL_ID, syncLocalId);
-            final String id = entry.getId();
-            final String editUri = entry.getEditUri();
-            if (!TextUtils.isEmpty(id)) {
-                deletedValues.put(SyncConstValue._SYNC_ID, lastItemFromUri(id));
-            }
-            if (!TextUtils.isEmpty(editUri)) {
-                deletedValues.put(SyncConstValue._SYNC_VERSION, lastItemFromUri(editUri));
-            }
-            deletedValues.put(SyncConstValue._SYNC_ACCOUNT, account.name);
-            deletedValues.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
-        }
-
-        if (entry instanceof ContactEntry) {
-            if (deletedValues != null) {
-                provider.insert(People.DELETED_CONTENT_URI, deletedValues);
-                return;
-            }
-            updateProviderWithContactEntry(account, syncLocalId, (ContactEntry) entry, provider);
-            return;
-        }
-        if (entry instanceof GroupEntry) {
-            if (deletedValues != null) {
-                provider.insert(Groups.DELETED_CONTENT_URI, deletedValues);
-                return;
-            }
-            updateProviderWithGroupEntry(account, syncLocalId, (GroupEntry) entry, provider);
-            return;
-        }
-        throw new IllegalArgumentException("unknown entry type, " + entry.getClass().getName());
-    }
-
-    protected static void updateProviderWithContactEntry(Account account, Long syncLocalId,
-            ContactEntry entry, ContentProvider provider) throws ParseException {
-        final String name = entry.getTitle();
-        final String notes = entry.getContent();
-        final String yomiName = entry.getYomiName();
-        final String personSyncId = lastItemFromUri(entry.getId());
-        final String personSyncVersion = lastItemFromUri(entry.getEditUri());
-
-        // Store the info about the person
-        ContentValues values = new ContentValues();
-        values.put(People.NAME, name);
-        values.put(People.NOTES, notes);
-        values.put(People.PHONETIC_NAME, yomiName);
-        values.put(SyncConstValue._SYNC_ACCOUNT, account.name);
-        values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
-        values.put(SyncConstValue._SYNC_ID, personSyncId);
-        values.put(SyncConstValue._SYNC_DIRTY, "0");
-        values.put(SyncConstValue._SYNC_LOCAL_ID, syncLocalId);
-        values.put(SyncConstValue._SYNC_TIME, personSyncVersion);
-        values.put(SyncConstValue._SYNC_VERSION, personSyncVersion);
-        Uri personUri = provider.insert(People.CONTENT_URI, values);
-
-        // Store the photo information
-        final boolean photoExistsOnServer = !TextUtils.isEmpty(entry.getLinkPhotoHref());
-        final String photoVersion = lastItemFromUri(entry.getLinkEditPhotoHref());
-        values.clear();
-        values.put(Photos.PERSON_ID, ContentUris.parseId(personUri));
-        values.put(Photos.EXISTS_ON_SERVER, photoExistsOnServer ? 1 : 0);
-        values.put(SyncConstValue._SYNC_ACCOUNT, account.name);
-        values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
-        values.put(SyncConstValue._SYNC_ID, personSyncId);
-        values.put(SyncConstValue._SYNC_DIRTY, 0);
-        values.put(SyncConstValue._SYNC_LOCAL_ID, syncLocalId);
-        values.put(SyncConstValue._SYNC_TIME, photoVersion);
-        values.put(SyncConstValue._SYNC_VERSION, photoVersion);
-        if (provider.insert(Photos.CONTENT_URI, values) == null) {
-            Log.e(TAG, "error inserting photo row, " + values);
-        }
-
-        // Store each email address
-        for (Object object : entry.getEmailAddresses()) {
-            EmailAddress email = (EmailAddress) object;
-            values.clear();
-            contactsElementToValues(values, email, ENTRY_TYPE_TO_PROVIDER_EMAIL);
-            values.put(ContactMethods.DATA, email.getAddress());
-            values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
-            Uri uri = Uri.withAppendedPath(personUri, People.ContactMethods.CONTENT_DIRECTORY);
-            provider.insert(uri, values);
-        }
-
-        // Store each postal address
-        for (Object object : entry.getPostalAddresses()) {
-            PostalAddress address = (PostalAddress) object;
-            values.clear();
-            contactsElementToValues(values, address, ENTRY_TYPE_TO_PROVIDER_POSTAL);
-            values.put(ContactMethods.DATA, address.getValue());
-            values.put(ContactMethods.KIND, Contacts.KIND_POSTAL);
-            Uri uri = Uri.withAppendedPath(personUri, People.ContactMethods.CONTENT_DIRECTORY);
-            provider.insert(uri, values);
-        }
-
-        // Store each im address
-        for (Object object : entry.getImAddresses()) {
-            ImAddress address = (ImAddress) object;
-            values.clear();
-            contactsElementToValues(values, address, ENTRY_TYPE_TO_PROVIDER_IM);
-            values.put(ContactMethods.DATA, address.getAddress());
-            values.put(ContactMethods.KIND, Contacts.KIND_IM);
-            final byte protocolType = address.getProtocolPredefined();
-            if (protocolType == ImAddress.PROTOCOL_NONE) {
-                // don't add anything
-            } else if (protocolType == ImAddress.PROTOCOL_CUSTOM) {
-                values.put(ContactMethods.AUX_DATA,
-                        ContactMethods.encodeCustomImProtocol(address.getProtocolCustom()));
-            } else {
-                Integer providerProtocolType =
-                        ENTRY_IM_PROTOCOL_TO_PROVIDER_PROTOCOL .get(protocolType);
-                if (providerProtocolType == null) {
-                    throw new IllegalArgumentException("unknown protocol type, " + protocolType);
-                }
-                values.put(ContactMethods.AUX_DATA,
-                        ContactMethods.encodePredefinedImProtocol(providerProtocolType));
-            }
-            Uri uri = Uri.withAppendedPath(personUri, People.ContactMethods.CONTENT_DIRECTORY);
-            provider.insert(uri, values);
-        }
-
-        // Store each organization
-        for (Object object : entry.getOrganizations()) {
-            Organization organization = (Organization) object;
-            values.clear();
-            contactsElementToValues(values, organization, ENTRY_TYPE_TO_PROVIDER_ORGANIZATION);
-            values.put(Organizations.COMPANY, organization.getName());
-            values.put(Organizations.TITLE, organization.getTitle());
-            values.put(Organizations.COMPANY, organization.getName());
-            Uri uri = Uri.withAppendedPath(personUri, Organizations.CONTENT_DIRECTORY);
-            provider.insert(uri, values);
-        }
-
-        // Store each group
-        for (Object object : entry.getGroups()) {
-            GroupMembershipInfo groupMembershipInfo = (GroupMembershipInfo) object;
-            if (groupMembershipInfo.isDeleted()) {
-                continue;
-            }
-            values.clear();
-            values.put(GroupMembership.GROUP_SYNC_ACCOUNT, account.name);
-            values.put(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE, account.type);
-            values.put(GroupMembership.GROUP_SYNC_ID,
-                    lastItemFromUri(groupMembershipInfo.getGroup()));
-            Uri uri = Uri.withAppendedPath(personUri, GroupMembership.CONTENT_DIRECTORY);
-            provider.insert(uri, values);
-        }
-
-        // Store each phone number
-        for (Object object : entry.getPhoneNumbers()) {
-            PhoneNumber phone = (PhoneNumber) object;
-            values.clear();
-            contactsElementToValues(values, phone, ENTRY_TYPE_TO_PROVIDER_PHONE);
-            values.put(People.Phones.NUMBER, phone.getPhoneNumber());
-            values.put(People.Phones.LABEL, phone.getLabel());
-            Uri uri = Uri.withAppendedPath(personUri, People.Phones.CONTENT_DIRECTORY);
-            provider.insert(uri, values);
-        }
-
-        // Store the extended properties
-        for (Object object : entry.getExtendedProperties()) {
-            ExtendedProperty extendedProperty = (ExtendedProperty) object;
-            if (!"android".equals(extendedProperty.getName())) {
-                continue;
-            }
-            JSONObject jsonObject = null;
-            try {
-                jsonObject = new JSONObject(extendedProperty.getXmlBlob());
-            } catch (JSONException e) {
-                Log.w(TAG, "error parsing the android extended property, dropping, entry is "
-                        + entry.toString());
-                continue;
-            }
-            Iterator jsonIterator = jsonObject.keys();
-            while (jsonIterator.hasNext()) {
-                String key = (String)jsonIterator.next();
-                values.clear();
-                values.put(Extensions.NAME, key);
-                try {
-                    values.put(Extensions.VALUE, jsonObject.getString(key));
-                } catch (JSONException e) {
-                    // this should never happen, since we just got the key from the iterator
-                }
-                Uri uri = Uri.withAppendedPath(personUri, People.Extensions.CONTENT_DIRECTORY);
-                if (null == provider.insert(uri, values)) {
-                    Log.e(TAG, "Error inserting extension into provider, uri "
-                            + uri + ", values " + values);
-                }
-            }
-            break;
-        }
-    }
-
-    protected static void updateProviderWithGroupEntry(Account account, Long syncLocalId,
-            GroupEntry entry, ContentProvider provider) throws ParseException {
-        ContentValues values = new ContentValues();
-        values.put(Groups.NAME, entry.getTitle());
-        values.put(Groups.NOTES, entry.getContent());
-        values.put(Groups.SYSTEM_ID, entry.getSystemGroup());
-        values.put(Groups._SYNC_ACCOUNT, account.name);
-        values.put(Groups._SYNC_ACCOUNT_TYPE, account.type);
-        values.put(Groups._SYNC_ID, lastItemFromUri(entry.getId()));
-        values.put(Groups._SYNC_DIRTY, 0);
-        values.put(Groups._SYNC_LOCAL_ID, syncLocalId);
-        final String editUri = entry.getEditUri();
-        final String syncVersion = editUri == null ? null : lastItemFromUri(editUri);
-        values.put(Groups._SYNC_TIME, syncVersion);
-        values.put(Groups._SYNC_VERSION, syncVersion);
-        provider.insert(Groups.CONTENT_URI, values);
-    }
-
-    private static String lastItemFromUri(String url) {
-        return url.substring(url.lastIndexOf('/') + 1);
-    }
-
-    protected void savePhoto(long person, InputStream photoInput, String photoVersion)
-            throws IOException {
-        try {
-            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
-            byte[] data = new byte[1024];
-            while(true) {
-                int bytesRead = photoInput.read(data);
-                if (bytesRead < 0) break;
-                byteStream.write(data, 0, bytesRead);
-            }
-
-            ContentValues values = new ContentValues();
-            // we have to include this here otherwise the provider will set it to 1
-            values.put(Photos._SYNC_DIRTY, 0);
-            values.put(Photos.LOCAL_VERSION, photoVersion);
-            values.put(Photos.DATA, byteStream.toByteArray());
-            Uri photoUri = Uri.withAppendedPath(People.CONTENT_URI,
-                    "" + person + "/" + Photos.CONTENT_DIRECTORY);
-            if (getContext().getContentResolver().update(photoUri, values,
-                    "_sync_dirty=0", null) > 0) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "savePhoto: updated " + photoUri + " with values " + values);
-                }
-            } else {
-                Log.e(TAG, "savePhoto: update of " + photoUri + " with values " + values
-                        + " affected no rows");
-            }
-        } finally {
-            try {
-                if (photoInput != null) photoInput.close();
-            } catch (IOException e) {
-                // we don't care about exceptions here
-            }
-        }
-    }
-
-    /**
-     * Make sure the contacts subscriptions we expect based on the current
-     * accounts are present and that there aren't any extra subscriptions
-     * that we don't expect.
-     */
-    @Override
-    public void onAccountsChanged(Account[] accountsArray) {
-        if (!"yes".equals(SystemProperties.get("ro.config.sync"))) {
-            return;
-        }
-
-        ContentResolver cr = getContext().getContentResolver();
-        for (Account account : accountsArray) {
-            // TODO(fredq) should be using account instead of null
-            String value = Contacts.Settings.getSetting(cr, null,
-                    Contacts.Settings.SYNC_EVERYTHING);
-            if (value == null) {
-                // TODO(fredq) should be using account instead of null
-                Contacts.Settings.setSetting(cr, null, Contacts.Settings.SYNC_EVERYTHING, "1");
-            }
-            updateSubscribedFeeds(cr, account);
-        }
-    }
-
-    /**
-     *  Returns the contacts feed url for a specific account.
-     *  @param account The account
-     *  @return The contacts feed url for a specific account.
-     */
-    public static String getContactsFeedForAccount(Account account) {
-        String url = CONTACTS_FEED_URL + account.name + "/base2_property-android";
-        return rewriteUrlforAccount(account, url);
-    }
-
-    /**
-     *  Returns the contacts group feed url for a specific account.
-     *  @param account The account
-     *  @param groupSyncId The group id
-     *  @return The contacts feed url for a specific account and group.
-     */
-    public static String getContactsFeedForGroup(Account account, String groupSyncId) {
-        String groupId = getCanonicalGroupsFeedForAccount(account);
-        try {
-            groupId = URLEncoder.encode(groupId, "utf-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new IllegalArgumentException("unable to url encode group: " + groupId);
-        }
-        return getContactsFeedForAccount(account) + "?group=" + groupId + "/" + groupSyncId;
-    }
-
-    /**
-     *  Returns the groups feed url for a specific account.
-     *  @param account The account
-     *  @return The groups feed url for a specific account.
-     */
-    public static String getGroupsFeedForAccount(Account account) {
-        String url = GROUPS_FEED_URL + account.name + "/base2_property-android";
-        return rewriteUrlforAccount(account, url);
-    }
-
-    /**
-     *  Returns the groups feed url for a specific account that should be
-     *  used as the foreign reference to this group, e.g. in the
-     *  group membership element of the ContactEntry. The canonical groups
-     *  feed always uses http (so it doesn't need to be rewritten) and it always
-     *  uses the base projection. 
-     *  @param account The account
-     *  @return The groups feed url for a specific account.
-     */
-    public static String getCanonicalGroupsFeedForAccount(Account account) {
-        return GROUPS_FEED_URL + account.name + "/base";
-    }
-
-    /**
-     *  Returns the photo feed url for a specific account.
-     *  @param account The account
-     *  @return The photo feed url for a specific account.
-     */
-    public static String getPhotosFeedForAccount(Account account) {
-        String url = PHOTO_FEED_URL + account.name;
-        return rewriteUrlforAccount(account, url);
-    }
-
-    protected static boolean getFeedReturnsPartialDiffs() {
-        return true;
-    }
-
-    @Override
-    protected void updateQueryParameters(QueryParams params, GDataSyncData.FeedData feedSyncData) {
-        // we want to get the events ordered by last modified, so we can
-        // recover in case we cannot process the entire feed.
-        params.setParamValue("orderby", "lastmodified");
-        params.setParamValue("sortorder", "ascending");
-
-        // set showdeleted so that we get tombstones, only do this when we
-        // are doing an incremental sync
-        if (params.getUpdatedMin() != null) {
-            params.setParamValue("showdeleted", "true");
-        }
-    }
-
-    @Override
-    public void onSyncStarting(SyncContext context, Account account, boolean manualSync,
-            SyncResult result) {
-        mPerformedGetServerDiffs = false;
-        mIsManualSync = manualSync;
-        mPhotoDownloads = 0;
-        mPhotoUploads = 0;
-        super.onSyncStarting(context, account, manualSync, result);
-    }
-
-    @Override
-    public void onSyncEnding(SyncContext context, boolean success) {
-        final ContentResolver cr = getContext().getContentResolver();
-
-        if (success && mPerformedGetServerDiffs && !mSyncCanceled) {
-            final Account account = getAccount();
-            Cursor cursor = cr.query(
-                    Photos.CONTENT_URI,
-                    new String[]{Photos._SYNC_ID, Photos._SYNC_VERSION, Photos.PERSON_ID,
-                            Photos.DOWNLOAD_REQUIRED}, ""
-                    + "_sync_account=? AND _sync_account_type=? AND download_required != 0",
-                    new String[]{account.name, account.type}, null);
-            try {
-                if (cursor.getCount() != 0) {
-                    Bundle extras = new Bundle();
-                    extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, mIsManualSync);
-                    extras.putString("feed", ContactsSyncAdapter.getPhotosFeedForAccount(account));
-                    ContentResolver.requestSync(account, Contacts.AUTHORITY, extras);
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-
-        super.onSyncEnding(context, success);
-    }
-
-    public static void updateSubscribedFeeds(ContentResolver cr, Account account) {
-        Set<String> feedsToSync = Sets.newHashSet();
-        feedsToSync.add(getGroupsFeedForAccount(account));
-        addContactsFeedsToSync(cr, account, feedsToSync);
-
-        Cursor c = SubscribedFeeds.Feeds.query(cr, sSubscriptionProjection,
-                SubscribedFeeds.Feeds.AUTHORITY + "=?"
-                        + " AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT + "=?"
-                        + " AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?",
-                new String[]{Contacts.AUTHORITY, account.name, account.type}, null);
-        try {
-            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.v(TAG, "scanning over subscriptions with authority "
-                        + Contacts.AUTHORITY + " and account " + account);
-            }
-            c.moveToNext();
-            while (!c.isAfterLast()) {
-                String feedInCursor = c.getString(1);
-                if (feedsToSync.contains(feedInCursor)) {
-                    feedsToSync.remove(feedInCursor);
-                    c.moveToNext();
-                } else {
-                    c.deleteRow();
-                }
-            }
-            c.commitUpdates();
-        } finally {
-            c.close();
-        }
-
-        // any feeds remaining in feedsToSync need a subscription
-        for (String feed : feedsToSync) {
-            SubscribedFeeds.addFeed(cr, feed, account, Contacts.AUTHORITY, ContactsClient.SERVICE);
-
-            // request a sync of this feed
-            Bundle extras = new Bundle();
-            extras.putString("feed", feed);
-            ContentResolver.requestSync(account, Contacts.AUTHORITY, extras);
-        }
-    }
-}
diff --git a/src/com/android/providers/contacts/ContactsSyncAdapterService.java b/src/com/android/providers/contacts/ContactsSyncAdapterService.java
deleted file mode 100644
index ee95153..0000000
--- a/src/com/android/providers/contacts/ContactsSyncAdapterService.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.android.providers.contacts;
-
-import android.app.Service;
-import android.os.IBinder;
-import android.content.Intent;
-import android.content.ContentProviderClient;
-import android.content.ContentProvider;
-import android.content.SyncableContentProvider;
-import android.provider.Contacts;
-
-public class ContactsSyncAdapterService extends Service {
-    private ContentProviderClient mContentProviderClient = null;
-
-    public void onCreate() {
-        mContentProviderClient =
-                getContentResolver().acquireContentProviderClient(Contacts.CONTENT_URI);
-    }
-
-    public void onDestroy() {
-        mContentProviderClient.release();
-    }
-
-    public IBinder onBind(Intent intent) {
-        ContentProvider contentProvider = mContentProviderClient.getLocalContentProvider();
-        if (contentProvider == null) throw new IllegalStateException();
-        SyncableContentProvider syncableContentProvider = (SyncableContentProvider)contentProvider;
-        return syncableContentProvider.getTempProviderSyncAdapter().getISyncAdapter().asBinder();
-    }
-}
diff --git a/src/com/android/providers/contacts/GoogleContactsProvider.java b/src/com/android/providers/contacts/GoogleContactsProvider.java
deleted file mode 100644
index 77bce2c..0000000
--- a/src/com/android/providers/contacts/GoogleContactsProvider.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *	    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.providers.contacts;
-
-import com.google.android.collect.Sets;
-import com.google.android.providers.AbstractGDataSyncAdapter;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SyncContext;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.SystemClock;
-import android.provider.Contacts;
-import android.text.TextUtils;
-import android.accounts.Account;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A subclass of the platform contacts provider that adds the Google contacts
- * sync adapter.
- */
-public class GoogleContactsProvider extends ContactsProvider {
-    private static final int PURGE_CONTACTS_DELAY_IN_MS = 30000;
-    private static final String ACTION_PURGE_CONTACTS =
-            "com.android.providers.contacts.PURGE_CONTACTS";
-
-    /**
-     * SQL query that deletes all contacts for a given account that are not a member of
-     * at least one group that has the "should_sync" column set to a non-zero value.
-     */
-    private static final String PURGE_UNSYNCED_CONTACTS_SQL = ""
-            + "DELETE FROM people "
-            + "WHERE (_id IN ("
-            + "   SELECT person "
-            + "   FROM ("
-            + "     SELECT MAX(should_sync) AS max_should_sync, person "
-            + "     FROM ("
-            + "       SELECT should_sync, person "
-            + "       FROM groupmembership AS gm "
-            + "         OUTER JOIN groups AS g "
-            + "         ON (gm.group_id=g._id "
-            + "           OR (gm.group_sync_id=g._sync_id "
-            + "               AND gm.group_sync_account=g._sync_account "
-            + "               AND gm.group_sync_account_type=g._sync_account_type))) "
-            + "       GROUP BY person) "
-            + "   WHERE max_should_sync=0)"
-            + "  OR _id NOT IN (SELECT person FROM groupmembership))"
-            + " AND _sync_dirty=0 "
-            + " AND _sync_account=? "
-            + " AND _sync_account_type=?";
-
-    private AlarmManager mAlarmService = null;
-
-    @Override
-    public boolean onCreate() {
-        setTempProviderSyncAdapter(new ContactsSyncAdapter(getContext(), this));
-        BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (ACTION_PURGE_CONTACTS.equals(intent.getAction())) {
-                    purgeContacts((Account) intent.getParcelableExtra("account"));
-                }
-            }
-        };
-        getContext().registerReceiver(receiver, new IntentFilter(ACTION_PURGE_CONTACTS));
-        return super.onCreate();
-    }
-
-    @Override
-    protected void onLocalChangesForAccount(final ContentResolver resolver, Account account,
-            boolean groupsModified) {
-        ContactsSyncAdapter.updateSubscribedFeeds(resolver, account);
-        if (groupsModified) {
-            schedulePurge(account);
-        }
-    }
-
-    /**
-     * Delete any non-sync_dirty contacts associated with the given account
-     * that are not in any of the synced groups.
-     */
-    private void schedulePurge(Account account) {
-        if (isTemporary()) {
-            throw new IllegalStateException("this must not be called on temp providers");
-        }
-        ensureAlarmService();
-        final Intent intent = new Intent(ACTION_PURGE_CONTACTS);
-        intent.putExtra("account", account);
-        final PendingIntent pendingIntent = PendingIntent.getBroadcast(
-                getContext(), 0 /* ignored */, intent, 0);
-        mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + PURGE_CONTACTS_DELAY_IN_MS,
-                pendingIntent);
-    }
-
-    private void ensureAlarmService() {
-        if (mAlarmService == null) {
-            mAlarmService = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
-        }
-    }
-
-    @Override
-    public void onSyncStop(SyncContext context, boolean success) {
-        super.onSyncStop(context, success);
-        purgeContacts(getSyncingAccount());
-    }
-
-    private void purgeContacts(Account account) {
-        if (isTemporary()) {
-            throw new IllegalStateException("this must not be called on temp providers");
-        }
-        SQLiteDatabase db = getDatabase();
-        db.beginTransaction();
-        try {
-            // TODO(fredq) should be using account instead of null
-            final String value = Contacts.Settings.getSetting(getContext().getContentResolver(),
-                    null, Contacts.Settings.SYNC_EVERYTHING);
-            final boolean shouldSyncEverything = !TextUtils.isEmpty(value) && !"0".equals(value);
-            if (!shouldSyncEverything) {
-                db.execSQL(PURGE_UNSYNCED_CONTACTS_SQL, new String[]{account.name, account.type});
-            }
-
-            // remove any feeds in the SyncData that aren't in the current sync set.
-            Set<String> feedsToSync = Sets.newHashSet();
-            feedsToSync.add(ContactsSyncAdapter.getGroupsFeedForAccount(account));
-            ContactsSyncAdapter.addContactsFeedsToSync(getContext().getContentResolver(), account,
-                    feedsToSync);
-            AbstractGDataSyncAdapter.GDataSyncData syncData = readSyncData(account);
-            if (syncData != null) {
-                Iterator<Map.Entry<String, AbstractGDataSyncAdapter.GDataSyncData.FeedData>> iter =
-                        syncData.feedData.entrySet().iterator();
-                boolean updatedSyncData = false;
-                while (iter.hasNext()) {
-                    Map.Entry<String, AbstractGDataSyncAdapter.GDataSyncData.FeedData> entry =
-                            iter.next();
-                    if (!feedsToSync.contains(entry.getKey())) {
-                        iter.remove();
-                        updatedSyncData = true;
-                    }
-                }
-                if (updatedSyncData) {
-                    writeSyncData(account, syncData);
-                }
-            }
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    private AbstractGDataSyncAdapter.GDataSyncData readSyncData(Account account) {
-        if (!getDatabase().inTransaction()) {
-            throw new IllegalStateException("you can only call this from within a transaction");
-        }
-        Cursor c = getDatabase().query("_sync_state", new String[]{"data"},
-                "_sync_account=? AND _sync_account_type=?",
-                new String[]{account.name, account.type}, null, null, null);
-        try {
-            byte[] data = null;
-            if (c.moveToNext()) data = c.getBlob(0);
-            return ContactsSyncAdapter.newGDataSyncDataFromBytes(data);
-        } finally {
-            c.close();
-        }
-    }
-
-    private void writeSyncData(Account account, AbstractGDataSyncAdapter.GDataSyncData syncData) {
-        final SQLiteDatabase db = getDatabase();
-        if (!db.inTransaction()) {
-            throw new IllegalStateException("you can only call this from within a transaction");
-        }
-        db.delete("_sync_state", "_sync_account=? AND _sync_account_type=?",
-                new String[]{account.name, account.type});
-        ContentValues values = new ContentValues();
-        values.put("data", ContactsSyncAdapter.newBytesFromGDataSyncData(syncData));
-        values.put("_sync_account", account.name);
-        values.put("_sync_account_type", account.type);
-        db.insert("_sync_state", "_sync_account", values);
-    }
-}
-
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 7a93ffd..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := GoogleContactsProviderTests
-LOCAL_CERTIFICATE := shared
-
-LOCAL_INSTRUMENTATION_FOR := GoogleContactsProvider
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
deleted file mode 100644
index c06a5e6..0000000
--- a/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.providers.contactstests"
-        android:sharedUserId="android.uid.shared">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
-    <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
-    <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_SYNC_STATS" />
-
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.providers.contacts"
-        android:label="ContactsProvider Isolated Tests">
-    </instrumentation>
-
-    <instrumentation android:name="SyncContactsInstrumentation"
-        android:targetPackage="com.android.providers.contacts"
-        android:label="Contacts Sync Test">
-    </instrumentation>
-
-</manifest>
diff --git a/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java b/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java
deleted file mode 100644
index 018907a..0000000
--- a/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java
+++ /dev/null
@@ -1,870 +0,0 @@
-package com.android.providers.contacts;
-
-import com.google.wireless.gdata.contacts.data.ContactEntry;
-import com.google.wireless.gdata.contacts.data.EmailAddress;
-import com.google.wireless.gdata.contacts.data.GroupEntry;
-import com.google.wireless.gdata.contacts.data.GroupMembershipInfo;
-import com.google.wireless.gdata.contacts.data.ImAddress;
-import com.google.wireless.gdata.contacts.data.Organization;
-import com.google.wireless.gdata.contacts.data.PhoneNumber;
-import com.google.wireless.gdata.contacts.data.PostalAddress;
-import com.google.wireless.gdata.data.Entry;
-import com.google.wireless.gdata.data.ExtendedProperty;
-import com.google.wireless.gdata.parser.ParseException;
-
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.SyncContext;
-import android.content.SyncResult;
-import android.content.TempProviderSyncResult;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import android.provider.Contacts;
-import android.provider.Contacts.ContactMethods;
-import android.provider.Contacts.GroupMembership;
-import android.provider.Contacts.Groups;
-import android.provider.Contacts.People;
-import android.provider.Contacts.Photos;
-import android.provider.SyncConstValue;
-import android.test.ProviderTestCase;
-import android.util.Log;
-import android.accounts.Account;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class ContactsSyncAdapterTest extends ProviderTestCase<ContactsProvider> {
-    private static final Account ACCOUNT = new Account("testaccount@example.com", "example.type");
-
-    private MockSyncContext mMockSyncContext = new MockSyncContext();
-    private ContactsSyncAdapter mSyncAdapter = null;
-
-    public ContactsSyncAdapterTest() {
-        super(ContactsProvider.class, Contacts.AUTHORITY);
-    }
-
-    public void testUpdateProviderPeople() throws ParseException {
-        final ContactsProvider serverDiffs = newTemporaryProvider();
-
-        ContactEntry entry1 = newPerson("title1", "note1", "1", "a");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 11L, entry1, serverDiffs);
-
-        ContactEntry entry2 = newPerson("title2", "note2", "2", "b");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, null, entry2, serverDiffs);
-
-        ContactEntry entry3 = newPerson("title3", "note3", "3", "c");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 13L, entry3, serverDiffs);
-
-        ContactEntry entry4 = newPerson("title4", "note4", "4", "d");
-        entry4.setDeleted(true);
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 14L, entry4, serverDiffs);
-
-        ContactEntry entry5 = newDeletedPerson("5", "e");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 15L, entry5, serverDiffs);
-
-        checkTableIsEmpty(getProvider(), Contacts.ContactMethods.CONTENT_URI);
-        checkTableIsEmpty(getProvider(), Contacts.Organizations.CONTENT_URI);
-        checkTableIsEmpty(getProvider(), Contacts.Phones.CONTENT_URI);
-
-        checkEntries(serverDiffs, false, entry1, 11L, entry2, null, entry3, 13L);
-        checkEntries(serverDiffs, true, entry4, 14L, entry5, 15L);
-
-        // Convert the provider back to an entry and check that they match
-        Cursor cursor;
-        cursor = ContactsSyncAdapter.getCursorForTableImpl(serverDiffs, ContactEntry.class);
-        try {
-            checkNextCursorToEntry(cursor, entry1);
-            checkNextCursorToEntry(cursor, entry2);
-            checkNextCursorToEntry(cursor, entry3);
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-
-        cursor = ContactsSyncAdapter.getCursorForDeletedTableImpl(serverDiffs, ContactEntry.class);
-        try {
-            checkNextDeletedCursorToEntry(cursor, entry4);
-            checkNextDeletedCursorToEntry(cursor, entry5);
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-    }
-
-    public void testUpdateProviderGroups() throws ParseException {
-        final ContactsProvider serverDiffs = newTemporaryProvider();
-
-        GroupEntry g1 = newGroup("g1", "n1", "i1", "v1");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 21L, g1, serverDiffs);
-
-        GroupEntry g2 = newGroup("g2", "n2", "i2", "v2");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, null, g2, serverDiffs);
-
-        GroupEntry g3 = newGroup("g3", "n3", "i3", "v3");
-        g3.setDeleted(true);
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 23L, g3, serverDiffs);
-
-        GroupEntry g4 = newDeletedGroup("i4", "v4");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 24L, g4, serverDiffs);
-
-        // confirm that the entries we expect are in the Groups and DeletedGroups
-        // tables
-        checkEntries(serverDiffs, false, g1, 21L, g2, null);
-        checkEntries(serverDiffs, true, g3, 23L, g4, 24L);
-
-        // Convert the provider back to an entry and check that they match
-        Cursor cursor;
-        cursor = ContactsSyncAdapter.getCursorForTableImpl(serverDiffs, GroupEntry.class);
-        try {
-            checkNextCursorToEntry(cursor, g1);
-            checkNextCursorToEntry(cursor, g2);
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-
-        cursor = ContactsSyncAdapter.getCursorForDeletedTableImpl(serverDiffs, GroupEntry.class);
-        try {
-            checkNextDeletedCursorToEntry(cursor, g3);
-            checkNextDeletedCursorToEntry(cursor, g4);
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-    }
-
-    // The temp provider contains groups that mirror the GroupEntries
-    // The temp provider contains people rows that mirrow the ContactEntry people portion
-    // The temp provider contains groupmembership rows that mirror the group membership info
-    // These groupmembership rows have people._id as a foreign key
-    //   and a group _sync_id, but not as a foreign key
-    
-    public void testUpdateProviderGroupMembership() throws ParseException {
-        final ContactsProvider serverDiffs = newTemporaryProvider();
-
-        ContactEntry p = newPerson("p1", "pn1", "pi1", "pv1");
-
-        addGroupMembership(p, ACCOUNT, "gsi1");
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, 31L, p, serverDiffs);
-
-        // The provider should now have:
-        // - a row in the people table
-        // - a row in the groupmembership table
-
-        checkEntries(serverDiffs, false, p, 31L);
-
-        checkTableIsEmpty(serverDiffs, ContactsProvider.sPeopleTable);
-        checkTableIsEmpty(serverDiffs, ContactsProvider.sGroupmembershipTable);
-
-        // copy the server diffs into the provider
-        getProvider().merge(mMockSyncContext, serverDiffs, null, new SyncResult());
-        getProvider().getDatabase().execSQL("UPDATE people SET _sync_dirty=1");
-        ContentProvider clientDiffs = getClientDiffs();
-
-        // Convert the provider back to an entry and check that they match
-        Cursor cursor = ContactsSyncAdapter.getCursorForTableImpl(clientDiffs, ContactEntry.class);
-        try {
-            checkNextCursorToEntry(cursor, p);
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-    }
-
-    private static void addGroupMembership(ContactEntry p, Account account, String groupId) {
-        GroupMembershipInfo groupInfo = new GroupMembershipInfo();
-        final String serverId =
-                ContactsSyncAdapter.getCanonicalGroupsFeedForAccount(account) + "/" + groupId;
-        groupInfo.setGroup(serverId);
-        p.addGroup(groupInfo);
-    }
-
-    public void testUpdateProviderContactMethods() throws ParseException {
-        final String entryTitle = "title1";
-        ContactEntry entry = newPerson(entryTitle, "note1", "2", "3");
-
-        addEmail(entry, "a11111", false, EmailAddress.TYPE_HOME, null);
-        addEmail(entry, "a22222", true, EmailAddress.TYPE_WORK, null);
-        addEmail(entry, "a33333", false, EmailAddress.TYPE_OTHER, null);
-        addEmail(entry, "a44444", false, EmailAddress.TYPE_NONE, "lucky");
-
-        addPostal(entry, "b11111", false, PostalAddress.TYPE_HOME, null);
-        addPostal(entry, "b22222", false, PostalAddress.TYPE_WORK, null);
-        addPostal(entry, "b33333", true, PostalAddress.TYPE_OTHER, null);
-        addPostal(entry, "b44444", false, PostalAddress.TYPE_NONE, "lucky");
-
-        addIm(entry, "c11111", ImAddress.PROTOCOL_CUSTOM, "p1", false, ImAddress.TYPE_HOME, null);
-        addIm(entry, "c22222", ImAddress.PROTOCOL_NONE, null, true, ImAddress.TYPE_WORK, null);
-        addIm(entry, "c33333", ImAddress.PROTOCOL_SKYPE, null, false, ImAddress.TYPE_OTHER, null);
-        addIm(entry, "c44444", ImAddress.PROTOCOL_ICQ, null, false, ImAddress.TYPE_NONE, "l2");
-
-        final ContactsProvider provider = newTemporaryProvider();
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, null, entry, provider);
-
-        checkTableIsEmpty(getProvider(), Contacts.Phones.CONTENT_URI);
-        checkTableIsEmpty(getProvider(), Contacts.Organizations.CONTENT_URI);
-
-        long personId = getSinglePersonId(provider, entryTitle);
-
-        Cursor cursor;
-        cursor = provider.query(Contacts.ContactMethods.CONTENT_URI, null, null, null,
-                Contacts.ContactMethods.DATA);
-        try {
-            checkNextEmail(cursor, personId, "a11111",
-                    false, Contacts.ContactMethods.TYPE_HOME, null);
-            checkNextEmail(cursor, personId, "a22222",
-                    true, Contacts.ContactMethods.TYPE_WORK, null);
-            checkNextEmail(cursor, personId, "a33333",
-                    false, Contacts.ContactMethods.TYPE_OTHER, null);
-            checkNextEmail(cursor, personId, "a44444",
-                    false, Contacts.ContactMethods.TYPE_CUSTOM, "lucky");
-
-            checkNextPostal(cursor, personId, "b11111",
-                    false, Contacts.ContactMethods.TYPE_HOME, null);
-            checkNextPostal(cursor, personId, "b22222",
-                    false, Contacts.ContactMethods.TYPE_WORK, null);
-            checkNextPostal(cursor, personId, "b33333",
-                    true, Contacts.ContactMethods.TYPE_OTHER, null);
-            checkNextPostal(cursor, personId, "b44444",
-                    false, Contacts.ContactMethods.TYPE_CUSTOM, "lucky");
-
-            checkNextIm(cursor, personId, "c11111", ContactMethods.encodeCustomImProtocol("p1"),
-                    false, Contacts.ContactMethods.TYPE_HOME, null);
-            checkNextIm(cursor, personId, "c22222", null,
-                    true, Contacts.ContactMethods.TYPE_WORK, null);
-            checkNextIm(cursor, personId, "c33333",
-                    ContactMethods.encodePredefinedImProtocol(ContactMethods.PROTOCOL_SKYPE),
-                    false, Contacts.ContactMethods.TYPE_OTHER, null);
-            checkNextIm(cursor, personId, "c44444",
-                    ContactMethods.encodePredefinedImProtocol(ContactMethods.PROTOCOL_ICQ),
-                    false, Contacts.ContactMethods.TYPE_CUSTOM, "l2");
-
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-
-        checkCursorToEntry(provider, entry);
-    }
-
-    public void testUpdateProviderPhones() throws ParseException {
-        final String entryTitle = "title1";
-        ContactEntry entry = newPerson(entryTitle, "note1", "2", "3");
-        addPhoneNumber(entry, "11111", false, PhoneNumber.TYPE_HOME, null);
-        addPhoneNumber(entry, "22222", false, PhoneNumber.TYPE_HOME_FAX, null);
-        addPhoneNumber(entry, "33333", false, PhoneNumber.TYPE_MOBILE, null);
-        addPhoneNumber(entry, "44444", true, PhoneNumber.TYPE_PAGER, null);
-        addPhoneNumber(entry, "55555", false, PhoneNumber.TYPE_WORK, null);
-        addPhoneNumber(entry, "66666", false, PhoneNumber.TYPE_WORK_FAX, null);
-        addPhoneNumber(entry, "77777", false, PhoneNumber.TYPE_OTHER, null);
-        addPhoneNumber(entry, "88888", false, PhoneNumber.TYPE_NONE, "lucky");
-        final ContactsProvider provider = newTemporaryProvider();
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, null, entry, provider);
-
-        checkTableIsEmpty(getProvider(), Contacts.ContactMethods.CONTENT_URI);
-        checkTableIsEmpty(getProvider(), Contacts.Organizations.CONTENT_URI);
-
-        long personId = getSinglePersonId(provider, entryTitle);
-
-        Cursor cursor;
-        cursor = provider.query(Contacts.Phones.CONTENT_URI, null, null, null,
-                Contacts.Phones.NUMBER);
-        try {
-            checkNextNumber(cursor, personId, "11111", false, Contacts.Phones.TYPE_HOME, null);
-            checkNextNumber(cursor, personId, "22222", false, Contacts.Phones.TYPE_FAX_HOME, null);
-            checkNextNumber(cursor, personId, "33333", false, Contacts.Phones.TYPE_MOBILE, null);
-            checkNextNumber(cursor, personId, "44444", true, Contacts.Phones.TYPE_PAGER, null);
-            checkNextNumber(cursor, personId, "55555", false, Contacts.Phones.TYPE_WORK, null);
-            checkNextNumber(cursor, personId, "66666", false, Contacts.Phones.TYPE_FAX_WORK, null);
-            checkNextNumber(cursor, personId, "77777", false, Contacts.Phones.TYPE_OTHER, null);
-            checkNextNumber(cursor, personId, "88888", false, Contacts.Phones.TYPE_CUSTOM, "lucky");
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-
-        checkCursorToEntry(provider, entry);
-    }
-
-    public void testUpdateProviderOrganization() throws ParseException {
-        final String entryTitle = "title1";
-        ContactEntry entry = newPerson(entryTitle, "note1", "2", "3");
-        addOrganization(entry, "11111", "title1", true, Organization.TYPE_WORK, null);
-        addOrganization(entry, "22222", "title2", false, Organization.TYPE_OTHER, null);
-        addOrganization(entry, "33333", "title3", false, Organization.TYPE_NONE, "label1");
-        final ContactsProvider provider = newTemporaryProvider();
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, null, entry, provider);
-
-        checkTableIsEmpty(getProvider(), Contacts.ContactMethods.CONTENT_URI);
-        checkTableIsEmpty(getProvider(), Contacts.Phones.CONTENT_URI);
-
-        long personId = getSinglePersonId(provider, entryTitle);
-
-        Cursor cursor;
-        cursor = provider.query(Contacts.Organizations.CONTENT_URI, null, null, null,
-                Contacts.Organizations.COMPANY);
-        try {
-            checkNextOrganization(cursor, personId, "11111", "title1", true,
-                    Contacts.Organizations.TYPE_WORK, null);
-            checkNextOrganization(cursor, personId, "22222", "title2", false,
-                    Contacts.Organizations.TYPE_OTHER, null);
-            checkNextOrganization(cursor, personId, "33333", "title3", false,
-                    Contacts.Organizations.TYPE_CUSTOM, "label1");
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-
-        checkCursorToEntry(provider, entry);
-    }
-
-    public void testUpdateProviderExtensions() throws ParseException {
-        final String entryTitle = "title1";
-        ContactEntry entry = newPerson(entryTitle, "note1", "2", "3");
-        addExtendedProperty(entry, "android", null, "{\"other\":\"that\",\"more\":\"hello.mp3\"}");
-        final ContactsProvider provider = newTemporaryProvider();
-        ContactsSyncAdapter.updateProviderImpl(ACCOUNT, null, entry, provider);
-
-        long personId = getSinglePersonId(provider, entryTitle);
-
-        Cursor cursor;
-        cursor = provider.query(Contacts.Extensions.CONTENT_URI, null, null, null,
-                Contacts.Extensions.NAME);
-        try {
-            checkNextExtension(cursor, personId, "more", "hello.mp3");
-            checkNextExtension(cursor, personId, "other", "that");
-            assertTrue(dumpCursor(cursor), cursor.isLast());
-        } finally {
-            cursor.close();
-        }
-
-        checkCursorToEntry(provider, entry);
-    }
-
-    // test writing a photo via the content resolver
-    public void testPhotoAccess() throws IOException, InterruptedException {
-        // add a person to the real provider
-        Uri p = addPerson(getProvider(), ACCOUNT, "si1", "p1");
-        Uri ph = Uri.withAppendedPath(p, Contacts.Photos.CONTENT_DIRECTORY);
-
-        ContentValues values = new ContentValues();
-        values.put(Photos._SYNC_DIRTY, 1);
-        values.put(Photos._SYNC_VERSION, "pv1");
-        values.put(Photos.LOCAL_VERSION, "pv0");
-        getMockContentResolver().update(ph, values, null, null);
-        // check that the photos rows look correct
-        Cursor cursor = getProvider().getDatabase().query(ContactsProvider.sPhotosTable,
-                null, null, null, null, null, null);
-        try {
-            checkNextPhoto(cursor, true, "pv0", "pv1");
-            assertFalse(cursor.moveToNext());
-        } finally {
-            cursor.close();
-        }
-
-        values.clear();
-        values.put(Photos._SYNC_DIRTY, 0);
-        getMockContentResolver().update(ph, values, null, null);
-        // check that the photos rows look correct
-        cursor = getProvider().getDatabase().query(ContactsProvider.sPhotosTable,
-                null, null, null, null, null, null);
-        try {
-            checkNextPhoto(cursor, false, "pv0", "pv1");
-            assertFalse(cursor.moveToNext());
-        } finally {
-            cursor.close();
-        }
-
-        // save a downloaded photo for that person using the ContactsSyncAdapter
-        byte[] remotePhotoData = "remote photo data".getBytes();
-        InputStream photoStream = new ByteArrayInputStream(remotePhotoData);
-        mSyncAdapter.savePhoto(ContentUris.parseId(p), photoStream, "pv1");
-
-        // check that the photos rows look correct
-        cursor = getProvider().getDatabase().query(ContactsProvider.sPhotosTable, 
-                null, null, null, null, null, null);
-        try {
-            checkNextPhoto(cursor, false, "pv1", "pv1");
-            assertFalse(cursor.moveToNext());
-        } finally {
-            cursor.close();
-        }
-
-        InputStream inputStream =
-                Contacts.People.openContactPhotoInputStream(getMockContentResolver(), p);
-        byte[] inputBytes = new byte[100];
-        int totalBytesRead = 0;
-        while (true) {
-            int numBytesRead = inputStream.read(inputBytes, totalBytesRead, 
-                    inputBytes.length - totalBytesRead);
-            if (numBytesRead < 0) break;
-            totalBytesRead += numBytesRead;
-        }
-        inputStream.close();
-
-        assertByteArrayEquals(remotePhotoData, inputBytes, totalBytesRead);
-    }
-
-    private void assertByteArrayEquals(byte[] expected, byte[] actual, int lengthOfActual) {
-        assertEquals(expected.length, lengthOfActual);
-        for (int i = 0; i < expected.length; i++) assertEquals(expected[i], actual[i]);
-    }
-
-    private void checkNextPhoto(Cursor cursor, boolean expectedDirty, String expectedLocalVersion,
-            String expectedServerVersion) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(expectedDirty, getLong(cursor, Photos._SYNC_DIRTY) != 0);
-        assertEquals(expectedLocalVersion, getString(cursor, Photos.LOCAL_VERSION));
-        assertEquals(expectedServerVersion, getString(cursor, Photos._SYNC_VERSION));
-    }
-
-    private Uri addPerson(ContactsProvider provider, Account account,
-            String name, String syncId) {
-        ContentValues values = new ContentValues();
-        values.put(People.NAME, name);
-        values.put(People._SYNC_ACCOUNT, account.name);
-        values.put(People._SYNC_ACCOUNT_TYPE, account.type);
-        values.put(People._SYNC_ID, syncId);
-        return provider.insert(People.CONTENT_URI, values);
-    }
-
-    private static GroupEntry newGroup(String title, String notes, String id, String version) {
-        GroupEntry entry = new GroupEntry();
-        entry.setTitle(title);
-        entry.setContent(notes);
-        entry.setId(ContactsSyncAdapter.getGroupsFeedForAccount(ACCOUNT) + "/" + id);
-        entry.setEditUri(entry.getId() + "/" + version);
-        return entry;
-    }
-
-    private static GroupEntry newDeletedGroup(String id, String version) {
-        GroupEntry entry = new GroupEntry();
-        entry.setDeleted(true);
-        entry.setId(ContactsSyncAdapter.getGroupsFeedForAccount(ACCOUNT) + "/" + id);
-        entry.setEditUri(entry.getId() + "/" + version);
-        return entry;
-    }
-
-    private static void checkNextGroup(Cursor cursor, GroupEntry entry, Long syncLocalId) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), entry.getId(),
-                feedFromEntry(entry) + "/" + getString(cursor, SyncConstValue._SYNC_ID));
-        assertEquals(dumpRow(cursor), entry.getEditUri(),
-                entry.getId() + "/" + getString(cursor, SyncConstValue._SYNC_VERSION));
-        assertEquals(dumpRow(cursor), ACCOUNT.name,
-                getString(cursor, SyncConstValue._SYNC_ACCOUNT));
-        assertEquals(dumpRow(cursor), ACCOUNT.type,
-                getString(cursor, SyncConstValue._SYNC_ACCOUNT_TYPE));
-        assertEquals(dumpRow(cursor), entry.getTitle(), getString(cursor, Groups.NAME));
-        assertEquals(dumpRow(cursor), entry.getSystemGroup(), getString(cursor, Groups.SYSTEM_ID));
-        assertEquals(dumpRow(cursor), entry.getContent(), getString(cursor, Groups.NOTES));
-        if (syncLocalId != null) {
-            assertEquals(dumpRow(cursor),
-                    syncLocalId, getString(cursor, SyncConstValue._SYNC_LOCAL_ID));
-        }
-    }
-
-    private static ContactEntry newPerson(String title, String notes, String id, String version) {
-        ContactEntry entry = new ContactEntry();
-        entry.setTitle(title);
-        entry.setContent(notes);
-        entry.setId(ContactsSyncAdapter.getContactsFeedForAccount(ACCOUNT) + "/" + id);
-        entry.setEditUri(entry.getId() + "/" + version);
-        entry.setLinkEditPhoto(ContactsSyncAdapter.getContactsFeedForAccount(ACCOUNT)
-                + "/" + id + "/v1", "image/jpg");
-        return entry;
-    }
-
-    private static ContactEntry newDeletedPerson(String id, String version) {
-        ContactEntry entry = new ContactEntry();
-        entry.setDeleted(true);
-        entry.setId(ContactsSyncAdapter.getContactsFeedForAccount(ACCOUNT) + "/" + id);
-        entry.setEditUri(entry.getId() + "/" + version);
-        return entry;
-    }
-
-    private void checkNextCursorToEntry(Cursor cursor, Entry expectedEntry) 
-            throws ParseException {
-        Entry newEntry = newEmptyEntry(expectedEntry);
-        assertTrue(cursor.moveToNext());
-        String createUri = ContactsSyncAdapter.cursorToEntryImpl(getMockContentResolver(),
-                cursor, newEntry, ACCOUNT);
-        // since this is an update the createUri should be null
-        assertNull(createUri);
-        assertEquals(expectedEntry.getEditUri(), newEntry.getEditUri());
-        if (expectedEntry instanceof ContactEntry) {
-            ((ContactEntry)newEntry).setLinkEditPhoto(
-                    ((ContactEntry)expectedEntry).getLinkEditPhotoHref(),
-                    ((ContactEntry)expectedEntry).getLinkEditPhotoType());
-        }
-        final String expected = expectedEntry.toString();
-        String actual = newEntry.toString();
-        assertEquals("\nexpected:\n" + expected + "\nactual:\n" + actual, expected, actual);
-    }
-
-    private static void checkNextDeletedCursorToEntry(Cursor cursor, Entry expectedEntry)
-            throws ParseException {
-        Entry newEntry = newEmptyEntry(expectedEntry);
-        assertTrue(cursor.moveToNext());
-        ContactsSyncAdapter.deletedCursorToEntryImpl(cursor, newEntry, ACCOUNT);
-        assertEquals(expectedEntry.getEditUri(), newEntry.getEditUri());
-    }
-
-    private static Entry newEmptyEntry(Entry expectedEntry) {
-        if (expectedEntry instanceof ContactEntry) {
-            return new ContactEntry();
-        } else {
-            return new GroupEntry();
-        }
-    }
-
-    public static String feedFromEntry(Entry expectedEntry) {
-        if (expectedEntry instanceof ContactEntry) {
-            return ContactsSyncAdapter.getContactsFeedForAccount(ACCOUNT);
-        } else {
-            return ContactsSyncAdapter.getGroupsFeedForAccount(ACCOUNT);
-        }
-    }
-
-    private static void checkNextPerson(ContactsProvider provider, Cursor cursor,
-            ContactEntry entry, Long syncLocalId) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), entry.getId(),
-                feedFromEntry(entry) + "/" + getString(cursor, SyncConstValue._SYNC_ID));
-        assertEquals(dumpRow(cursor), entry.getEditUri(),
-                entry.getId() + "/" + getString(cursor, SyncConstValue._SYNC_VERSION));
-        assertEquals(dumpRow(cursor), ACCOUNT.name,
-                getString(cursor, SyncConstValue._SYNC_ACCOUNT));
-        assertEquals(dumpRow(cursor), ACCOUNT.type,
-                getString(cursor, SyncConstValue._SYNC_ACCOUNT_TYPE));
-        assertEquals(dumpRow(cursor), entry.getTitle(), getString(cursor, People.NAME));
-        assertEquals(dumpRow(cursor), entry.getContent(), getString(cursor, People.NOTES));
-        if (syncLocalId != null) {
-            assertEquals(dumpRow(cursor),
-                    syncLocalId, getString(cursor, SyncConstValue._SYNC_LOCAL_ID));
-        }
-
-        Cursor groupCursor = provider.getDatabase().query(ContactsProvider.sGroupmembershipTable,
-                null, Contacts.GroupMembership.PERSON_ID + "=?",
-                new String[]{getString(cursor, People._ID)}, null, null, null);
-        try {
-            for (Object object : entry.getGroups()) {
-                GroupMembershipInfo groupMembership = (GroupMembershipInfo) object;
-                assertTrue(groupCursor.moveToNext());
-                assertEquals(groupMembership.getGroup(),
-                        ContactsSyncAdapter.getCanonicalGroupsFeedForAccount(ACCOUNT) + "/"
-                                + getString(groupCursor, GroupMembership.GROUP_SYNC_ID));
-            }
-            assertFalse(groupCursor.moveToNext());
-        } finally {
-            groupCursor.close();
-        }
-    }
-
-    private static void checkNextDeleted(Cursor cursor, Entry entry, Long syncLocalId) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), entry.getId(),
-                feedFromEntry(entry) + "/" + getString(cursor, SyncConstValue._SYNC_ID));
-        assertEquals(dumpRow(cursor), entry.getEditUri(),
-                entry.getId() + "/" + getString(cursor, SyncConstValue._SYNC_VERSION));
-        assertEquals(dumpRow(cursor), ACCOUNT.name,
-                getString(cursor, SyncConstValue._SYNC_ACCOUNT));
-        assertEquals(dumpRow(cursor), ACCOUNT.type,
-                getString(cursor, SyncConstValue._SYNC_ACCOUNT_TYPE));
-        if (syncLocalId != null) {
-            assertEquals(dumpRow(cursor),
-                    syncLocalId.toString(), getString(cursor, SyncConstValue._SYNC_LOCAL_ID));
-        }
-    }
-
-
-    private ContactsProvider newTemporaryProvider() {
-        return (ContactsProvider)getProvider().getTemporaryInstance();
-    }
-
-    private void copyTempProviderToReal(ContactsProvider provider) {
-        // copy the server diffs into the provider
-        getProvider().merge(mMockSyncContext, provider, null, new SyncResult());
-
-        // clear the _sync_id and _sync_local_id to act as if these are locally inserted
-        ContentValues values = new ContentValues();
-        values.put(SyncConstValue._SYNC_ID, (String)null);
-        values.put(SyncConstValue._SYNC_LOCAL_ID, (String)null);
-        values.put(SyncConstValue._SYNC_DIRTY, "1");
-        getProvider().getDatabase().update("people", values, null, null);
-    }
-
-    private void checkCursorToEntry(ContactsProvider provider, ContactEntry entry)
-            throws ParseException {
-        copyTempProviderToReal(provider);
-        final ContentProvider clientDiffsProvider = getClientDiffs();
-
-        Cursor cursor = ContactsSyncAdapter.getCursorForTableImpl(clientDiffsProvider,
-                entry.getClass());
-        try {
-            assertTrue(cursor.moveToFirst());
-            assertEquals(dumpCursor(cursor), 1, cursor.getCount());
-            ContactEntry newEntry = new ContactEntry();
-            String editUrl = ContactsSyncAdapter.cursorToEntryImpl(getMockContentResolver(), cursor,
-                    newEntry, ACCOUNT);
-            entry.setId(null);
-            entry.setEditUri(null);
-            entry.setLinkEditPhoto(null, null);
-            final String expected = entry.toString();
-            final String actual = newEntry.toString();
-            assertEquals("\nexpected:\n" + expected + "\nactual:\n" + actual, expected, actual);
-        } finally {
-            cursor.close();
-        }
-    }
-
-    private ContentProvider getClientDiffs() {
-        // query the provider for the client diffs
-        TempProviderSyncResult result = new TempProviderSyncResult();
-        getProvider().merge(mMockSyncContext, null, result, new SyncResult());
-        return result.tempContentProvider;
-    }
-
-    private static long getSinglePersonId(ContactsProvider provider, String entryTitle) {
-        long personId;
-        Cursor cursor;
-        cursor = provider.query(People.CONTENT_URI, null, null, null, null);
-        try {
-            assertTrue(cursor.moveToFirst());
-            assertEquals(dumpCursor(cursor), 1, cursor.getCount());
-            assertEquals(dumpRow(cursor), entryTitle, getString(cursor, People.NAME));
-            personId = getLong(cursor, People._ID);
-        } finally {
-            cursor.close();
-        }
-        return personId;
-    }
-
-    private static String dumpRow(Cursor cursor) {
-        return DatabaseUtils.dumpCurrentRowToString(cursor);
-    }
-
-    private static String dumpCursor(Cursor cursor) {
-        return DatabaseUtils.dumpCursorToString(cursor);
-    }
-
-    private static void checkNextNumber(Cursor cursor, long personId, String number,
-            boolean isPrimary, int type, String label) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), personId, getLong(cursor, Contacts.Phones.PERSON_ID));
-        assertEquals(dumpRow(cursor), number, getString(cursor, Contacts.Phones.NUMBER));
-        assertEquals(dumpRow(cursor), type, getLong(cursor, Contacts.Phones.TYPE));
-        assertEquals(dumpCursor(cursor), isPrimary,
-                getLong(cursor, Contacts.Phones.ISPRIMARY) != 0);
-        assertEquals(dumpRow(cursor), label, getString(cursor, Contacts.Phones.LABEL));
-    }
-
-    private static long getLong(Cursor cursor, String column) {
-        return cursor.getLong(cursor.getColumnIndexOrThrow(column));
-    }
-
-    private static String getString(Cursor cursor, String column) {
-        return cursor.getString(cursor.getColumnIndexOrThrow(column));
-    }
-
-    private static boolean isNull(Cursor cursor, String column) {
-        return cursor.isNull(cursor.getColumnIndexOrThrow(column));
-    }
-
-    private static void checkNextContactMethod(Cursor cursor, long personId, String data,
-            String auxData, int kind, boolean isPrimary, int type, String label) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), personId, getLong(cursor, Contacts.ContactMethods.PERSON_ID));
-        assertEquals(dumpRow(cursor), kind, getLong(cursor, Contacts.ContactMethods.KIND));
-        assertEquals(dumpRow(cursor), data, getString(cursor, Contacts.ContactMethods.DATA));
-        assertEquals(dumpRow(cursor), auxData, getString(cursor, Contacts.ContactMethods.AUX_DATA));
-        assertEquals(dumpCursor(cursor), isPrimary,
-                getLong(cursor, Contacts.ContactMethods.ISPRIMARY) != 0);
-        assertEquals(dumpRow(cursor), type, getLong(cursor, Contacts.ContactMethods.TYPE));
-        assertEquals(dumpRow(cursor), label, getString(cursor, Contacts.ContactMethods.LABEL));
-    }
-
-    private static void addPhoneNumber(ContactEntry entry, String number, boolean isPrimary,
-            byte rel, String label) {
-        PhoneNumber phoneNumber = new PhoneNumber();
-        phoneNumber.setPhoneNumber(number);
-        phoneNumber.setIsPrimary(isPrimary);
-        phoneNumber.setType(rel);
-        phoneNumber.setLabel(label);
-        entry.addPhoneNumber(phoneNumber);
-    }
-
-    private static void addPostal(ContactEntry entry, String address, boolean isPrimary, byte rel,
-            String label) {
-        PostalAddress item = new PostalAddress();
-        item.setValue(address);
-        item.setType(rel);
-        item.setLabel(label);
-        item.setIsPrimary(isPrimary);
-        entry.addPostalAddress(item);
-    }
-
-    private static void checkNextPostal(Cursor cursor, long personId, String address,
-            boolean isPrimary, int type, String label) {
-        checkNextContactMethod(cursor, personId, address, null,
-                Contacts.KIND_POSTAL, isPrimary, type, label);
-    }
-
-    private static void addIm(ContactEntry entry, String address, byte protocol,
-            String protocolString, boolean isPrimary, byte rel,
-            String label) {
-        ImAddress item = new ImAddress();
-        item.setAddress(address);
-        item.setProtocolPredefined(protocol);
-        item.setProtocolCustom(protocolString);
-        item.setLabel(label);
-        item.setType(rel);
-        item.setIsPrimary(isPrimary);
-        entry.addImAddress(item);
-    }
-
-    private static void checkNextIm(Cursor cursor, long personId, String address,
-            String auxData, boolean isPrimary, int type, String label) {
-        checkNextContactMethod(cursor, personId, address, auxData,
-                Contacts.KIND_IM, isPrimary, type, label);
-    }
-
-    private static void addEmail(ContactEntry entry, String address, boolean isPrimary, byte rel,
-            String label) {
-        EmailAddress item = new EmailAddress();
-        item.setAddress(address);
-        item.setIsPrimary(isPrimary);
-        item.setType(rel);
-        item.setLabel(label);
-        entry.addEmailAddress(item);
-    }
-
-    private static void checkNextEmail(Cursor cursor, long personId, String address,
-            boolean isPrimary, int type, String label) {
-        checkNextContactMethod(cursor, personId, address, null,
-                Contacts.KIND_EMAIL, isPrimary, type, label);
-    }
-
-    private void checkTableIsEmpty(ContactsProvider provider, Uri uri) {
-        Cursor cursor;
-        cursor = getProvider().query(uri, null, null, null, null);
-        try {
-            assertEquals(0, cursor.getCount());
-        } finally {
-            cursor.close();
-        }
-    }
-
-    private void checkTableIsEmpty(ContactsProvider provider, String table) {
-        Cursor cursor;
-        cursor = getProvider().getDatabase().query(table, null, null, null, null, null, null);
-        try {
-            assertEquals(DatabaseUtils.dumpCursorToString(cursor), 0, cursor.getCount());
-        } finally {
-            cursor.close();
-        }
-    }
-
-    private static void addOrganization(ContactEntry entry, String name, String title,
-            boolean isPrimary, byte type, String label) {
-        Organization organization = new Organization();
-        organization.setName(name);
-        organization.setTitle(title);
-        organization.setIsPrimary(isPrimary);
-        organization.setType(type);
-        organization.setLabel(label);
-        entry.addOrganization(organization);
-    }
-
-    private static void addExtendedProperty(ContactEntry entry, String name, String value,
-            String blob) {
-        ExtendedProperty extendedProperty = new ExtendedProperty();
-        extendedProperty.setName(name);
-        extendedProperty.setValue(value);
-        extendedProperty.setXmlBlob(blob);
-        entry.addExtendedProperty(extendedProperty);
-    }
-
-    private static void checkNextOrganization(Cursor cursor, long personId, String company,
-            String title, boolean isPrimary, int type, String label) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), personId, getLong(cursor, Contacts.Organizations.PERSON_ID));
-        assertEquals(dumpRow(cursor), company, getString(cursor, Contacts.Organizations.COMPANY));
-        assertEquals(dumpRow(cursor), title, getString(cursor, Contacts.Organizations.TITLE));
-        assertEquals(dumpRow(cursor), isPrimary,
-                getLong(cursor, Contacts.Organizations.ISPRIMARY) != 0);
-        assertEquals(dumpRow(cursor), type, getLong(cursor, Contacts.Phones.TYPE));
-        assertEquals(dumpRow(cursor), label, getString(cursor, Contacts.Phones.LABEL));
-    }
-    
-    private static void checkNextExtension(Cursor cursor, long personId,
-            String name, String value) {
-        assertTrue(cursor.moveToNext());
-        assertEquals(dumpRow(cursor), personId, getLong(cursor, Contacts.Extensions.PERSON_ID));
-        assertEquals(dumpRow(cursor), name, getString(cursor, Contacts.Extensions.NAME));
-        assertEquals(dumpRow(cursor), value, getString(cursor, Contacts.Extensions.VALUE));
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mSyncAdapter = (ContactsSyncAdapter)getProvider().getTempProviderSyncAdapter();
-        getProvider().onSyncStart(mMockSyncContext, ACCOUNT);
-    }
-
-    void checkEntries(ContactsProvider provider, boolean deleted,
-            Object ... entriesAndLocalSyncIds) {
-        String table;
-        String sortOrder = deleted ? "_sync_id" : "name";
-        final Entry firstEntry = (Entry)entriesAndLocalSyncIds[0];
-        if (firstEntry instanceof GroupEntry) {
-            if (deleted) {
-                table = ContactsProvider.sDeletedGroupsTable;
-            } else {
-                table = ContactsProvider.sGroupsTable;
-            }
-        } else {
-            if (deleted) {
-                table = ContactsProvider.sDeletedPeopleTable;
-            } else {
-                table = ContactsProvider.sPeopleTable;
-            }
-        }
-        Cursor cursor;
-         cursor = provider.getDatabase().query(table, null, null, null, null, null, sortOrder);
-         try {
-             for (int i = 0; i < entriesAndLocalSyncIds.length; i += 2) {
-                 Entry entry = (Entry)entriesAndLocalSyncIds[i];
-                 Long syncLocalId = (Long)entriesAndLocalSyncIds[i+1];
-                 if (deleted) {
-                     checkNextDeleted(cursor, entry, syncLocalId);
-                 } else {
-                     if (firstEntry instanceof GroupEntry) {
-                         checkNextGroup(cursor, (GroupEntry)entry, null);
-                     } else {
-                         checkNextPerson(provider, cursor, (ContactEntry)entry, null);
-                     }
-                 }
-             }
-             assertTrue(dumpCursor(cursor), cursor.isLast());
-         } finally {
-             cursor.close();
-         }
-    }
-}
-
-class MockSyncContext extends SyncContext {
-
-    MockSyncContext() {
-        super(null);
-    }
-
-    @Override
-    public void setStatusText(String text) {
-        Log.i("SyncTest", text);
-    }
-}
\ No newline at end of file
diff --git a/tests/src/com/android/providers/contacts/SyncContactsTest.java b/tests/src/com/android/providers/contacts/SyncContactsTest.java
deleted file mode 100644
index 7456bfa..0000000
--- a/tests/src/com/android/providers/contacts/SyncContactsTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package com.android.providers.contacts;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.provider.Contacts;
-import android.test.RenamingDelegatingContext;
-import android.test.SyncBaseInstrumentation;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.OperationCanceledException;
-import android.accounts.AuthenticatorException;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.io.IOException;
-
-import com.google.android.collect.Maps;
-import com.google.android.googlelogin.GoogleLoginServiceConstants;
-
-public class SyncContactsTest extends SyncBaseInstrumentation {
-    private Context mTargetContext;
-    private String mAccount;
-    private static final String PEOPLE_PHONE_JOIN =
-            "people LEFT OUTER JOIN phones ON people.primary_phone=phones._id " +
-            " LEFT OUTER JOIN contact_methods ON people.primary_email=contact_methods._id" +
-            " LEFT OUTER JOIN organizations ON people.primary_organization=organizations._id" +
-            " ORDER BY people._sync_id;";
-
-    private static final Set<String> PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP = new HashSet<String>();
-
-    static {
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People._ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People.PRIMARY_PHONE_ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People._SYNC_MARK);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People._SYNC_TIME);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People._SYNC_LOCAL_ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People._SYNC_VERSION);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People._SYNC_DIRTY);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People.TIMES_CONTACTED);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People.LAST_TIME_CONTACTED);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.Phones._ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.Phones.PERSON_ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People.PRIMARY_EMAIL_ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People.PRIMARY_ORGANIZATION_ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.People.ContactMethods._ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.Organizations.PERSON_ID);
-        PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP.add(Contacts.Organizations._ID);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTargetContext = getInstrumentation().getTargetContext();
-        mAccount = getAccount();
-    }
-
-    /**
-     * A Simple test that syncs the contacts provider.
-     * @throws Exception
-     */
-    public void testSync() throws Exception {
-        cancelSyncsandDisableAutoSync();
-        syncProvider(Contacts.CONTENT_URI, mAccount, Contacts.AUTHORITY);
-    }
-
-    private String getAccount() {
-        try {
-            String[] features = new String[]{GoogleLoginServiceConstants.FEATURE_HOSTED_OR_GOOGLE};
-            Account[] accounts = AccountManager.get(mTargetContext).getAccountsByTypeAndFeatures(
-                    GoogleLoginServiceConstants.ACCOUNT_TYPE, features, null, null).getResult();
-            if (accounts.length > 0) {
-                return accounts[0].name;
-            }
-        } catch (OperationCanceledException e) {
-            // handle below
-        } catch (IOException e) {
-            // handle below
-        } catch (AuthenticatorException e) {
-            // handle below
-        }
-        return null;
-    }
-
-    /**
-     * This test compares the two contacts databases.
-     * This works well with the puppetmaster automated script.
-     * @throws Exception
-     */
-    public void testCompareResults() throws Exception {
-        ContactsProvider incrementalContentProvider =
-                RenamingDelegatingContext.providerWithRenamedContext(ContactsProvider.class,
-                        mTargetContext, "", true);
-
-        ContactsProvider initialSyncContentProvider =
-                RenamingDelegatingContext.providerWithRenamedContext(ContactsProvider.class,
-                        mTargetContext, "initialsync.", true);
-
-        SQLiteDatabase incrementalDb = incrementalContentProvider.getDatabase();
-        SQLiteDatabase initialSyncDb = initialSyncContentProvider.getDatabase();
-
-        Cursor incrementalPeopleCursor = incrementalDb.rawQuery("select * from " +
-                                         PEOPLE_PHONE_JOIN, null);
-        Cursor initialPeopleCursor = initialSyncDb.rawQuery("select * from " +
-                                     PEOPLE_PHONE_JOIN, null);
-
-        assertNotSame("Incremental db has no values - check test configuration",
-                      incrementalPeopleCursor.getCount(), 0);
-        try {
-            compareCursors(incrementalPeopleCursor, initialPeopleCursor,
-                           PEOPLE_PHONES_JOIN_COLUMNS_TO_SKIP, "People");
-        } finally {
-            incrementalPeopleCursor.close();
-            initialPeopleCursor.close();
-        }
-    }
-
-    private void compareCursors(Cursor incrementalCursor,
-                                Cursor initialSyncCursor, Set<String> columnsToSkip,
-                                String tableName) {
-
-        assertEquals(tableName + " count failed to match", incrementalCursor.getCount(),
-                             initialSyncCursor.getCount());
-
-        String[] cols = incrementalCursor.getColumnNames();
-        int length = cols.length;
-        Map<String,String> row = Maps.newHashMap();
-        
-        while (incrementalCursor.moveToNext() && initialSyncCursor.moveToNext()) {
-            for (int i = 0; i < length; i++) {
-                String col = cols[i];
-                if (columnsToSkip != null && columnsToSkip.contains(col)) {
-                    continue;
-                }
-                row.put(col, incrementalCursor.getString(i));
-                assertEquals("Row: " + row + " .Column: " + cols[i] + " failed to match",
-                             incrementalCursor.getString(i), initialSyncCursor.getString(i));
-            }
-        }
-    }
-}
diff --git a/tests/src/com/android/providers/contactstests/SyncContactsInstrumentation.java b/tests/src/com/android/providers/contactstests/SyncContactsInstrumentation.java
deleted file mode 100644
index 373523d..0000000
--- a/tests/src/com/android/providers/contactstests/SyncContactsInstrumentation.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.android.providers.contactstests;
-
-import com.android.providers.contacts.SyncContactsTest;
-
-import junit.framework.TestSuite;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import android.test.suitebuilder.annotation.Suppress;
-
-@Suppress
-public class SyncContactsInstrumentation extends InstrumentationTestRunner {
-    public TestSuite getAllTests() {
-        TestSuite suite = new InstrumentationTestSuite(this);
-        suite.addTestSuite(SyncContactsTest.class);
-        return suite;
-    }
-
-    public ClassLoader getLoader() {
-        return SyncContactsTest.class.getClassLoader();
-    }
-}
