Refactor vCard test code and modify unit tests.

Factor out all the classes previously embedded in VCardTestsBase.java so that readers are able to
look over each file easily and each class explicitly mention the dependency between each other.

Make all the test cases use mVerifier in VCardTestsBase so that verify() call will not be
forgotten. Actually there were three tests found in which verify() was not called.

Internal issue number: 2195990
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/ContentValuesVerifier.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/ContentValuesVerifier.java
new file mode 100644
index 0000000..3fa6ae6
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/ContentValuesVerifier.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.pim.vcard.VCardConfig;
+import android.pim.vcard.VCardEntry;
+import android.pim.vcard.VCardEntryConstructor;
+import android.pim.vcard.VCardEntryHandler;
+import android.pim.vcard.VCardParser;
+import android.pim.vcard.VCardParser_V21;
+import android.pim.vcard.VCardParser_V30;
+import android.pim.vcard.exception.VCardException;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/* package */ class ContentValuesVerifier implements VCardEntryHandler {
+    private AndroidTestCase mTestCase;
+    private List<ContentValuesVerifierElem> mContentValuesVerifierElemList =
+        new ArrayList<ContentValuesVerifierElem>();
+    private int mIndex;
+
+    public ContentValuesVerifierElem addElem(AndroidTestCase androidTestCase) {
+        mTestCase = androidTestCase;
+        ContentValuesVerifierElem importVerifier = new ContentValuesVerifierElem(androidTestCase);
+        mContentValuesVerifierElemList.add(importVerifier);
+        return importVerifier;
+    }
+
+    public void verify(int resId, int vCardType) throws IOException, VCardException {
+        verify(mTestCase.getContext().getResources().openRawResource(resId), vCardType);
+    }
+
+    public void verify(int resId, int vCardType, final VCardParser vCardParser)
+            throws IOException, VCardException {
+        verify(mTestCase.getContext().getResources().openRawResource(resId),
+                vCardType, vCardParser);
+    }
+
+    public void verify(InputStream is, int vCardType) throws IOException, VCardException {
+        final VCardParser vCardParser;
+        if (VCardConfig.isV30(vCardType)) {
+            vCardParser = new VCardParser_V30(true);  // use StrictParsing
+        } else {
+            vCardParser = new VCardParser_V21();
+        }
+        verify(is, vCardType, vCardParser);
+    }
+
+    public void verify(InputStream is, int vCardType, final VCardParser vCardParser)
+            throws IOException, VCardException {
+        VCardEntryConstructor builder =
+            new VCardEntryConstructor(null, null, false, vCardType, null);
+        builder.addEntryHandler(this);
+        try {
+            vCardParser.parse(is, builder);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    public void onStart() {
+        for (ContentValuesVerifierElem elem : mContentValuesVerifierElemList) {
+            elem.onParsingStart();
+        }
+    }
+
+    public void onEntryCreated(VCardEntry entry) {
+        mTestCase.assertTrue(mIndex < mContentValuesVerifierElemList.size());
+        mContentValuesVerifierElemList.get(mIndex).onEntryCreated(entry);
+        mIndex++;
+    }
+
+    public void onEnd() {
+        for (ContentValuesVerifierElem elem : mContentValuesVerifierElemList) {
+            elem.onParsingEnd();
+            elem.verifyResolver();
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/ContentValuesVerifierElem.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/ContentValuesVerifierElem.java
new file mode 100644
index 0000000..f511217
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/ContentValuesVerifierElem.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.content.ContentValues;
+import android.pim.vcard.VCardConfig;
+import android.pim.vcard.VCardEntry;
+import android.pim.vcard.VCardEntryCommitter;
+import android.pim.vcard.VCardEntryConstructor;
+import android.pim.vcard.VCardEntryHandler;
+import android.pim.vcard.VCardParser;
+import android.pim.vcard.VCardParser_V21;
+import android.pim.vcard.VCardParser_V30;
+import android.pim.vcard.exception.VCardException;
+import android.provider.ContactsContract.Data;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/* package */ class ContentValuesVerifierElem {
+    private final AndroidTestCase mTestCase;
+    private final ImportTestResolver mResolver;
+    private final VCardEntryHandler mHandler;
+
+    public ContentValuesVerifierElem(AndroidTestCase androidTestCase) {
+        mTestCase = androidTestCase;
+        mResolver = new ImportTestResolver(androidTestCase);
+        mHandler = new VCardEntryCommitter(mResolver);
+    }
+
+    public ContentValuesBuilder addExpected(String mimeType) {
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Data.MIMETYPE, mimeType);
+        mResolver.addExpectedContentValues(contentValues);
+        return new ContentValuesBuilder(contentValues);
+    }
+
+    public void verify(int resId, int vCardType)
+            throws IOException, VCardException {
+        verify(mTestCase.getContext().getResources().openRawResource(resId), vCardType);
+    }
+
+    public void verify(InputStream is, int vCardType) throws IOException, VCardException {
+        final VCardParser vCardParser;
+        if (VCardConfig.isV30(vCardType)) {
+            vCardParser = new VCardParser_V30(true);  // use StrictParsing
+        } else {
+            vCardParser = new VCardParser_V21();
+        }
+        VCardEntryConstructor builder =
+                new VCardEntryConstructor(null, null, false, vCardType, null);
+        builder.addEntryHandler(mHandler);
+        try {
+            vCardParser.parse(is, builder);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        verifyResolver();
+    }
+
+    public void verifyResolver() {
+        mResolver.verify();
+    }
+
+    public void onParsingStart() {
+        mHandler.onStart();
+    }
+
+    public void onEntryCreated(VCardEntry entry) {
+        mHandler.onEntryCreated(entry);
+    }
+
+    public void onParsingEnd() {
+        mHandler.onEnd();
+    }
+}
\ No newline at end of file
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/ExportTestResolver.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/ExportTestResolver.java
new file mode 100644
index 0000000..481c10f
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/ExportTestResolver.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Entity;
+import android.content.EntityIterator;
+import android.database.Cursor;
+import android.net.Uri;
+import android.pim.vcard.VCardComposer;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockCursor;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/* package */ public class ExportTestResolver extends MockContentResolver {
+    ExportTestProvider mProvider;
+    public ExportTestResolver(TestCase testCase) {
+        mProvider = new ExportTestProvider(testCase);
+        addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
+        addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
+    }
+
+    public ContactEntry addInputContactEntry() {
+        return mProvider.buildInputEntry();
+    }
+}
+
+/* package */ class MockEntityIterator implements EntityIterator {
+    List<Entity> mEntityList;
+    Iterator<Entity> mIterator;
+
+    public MockEntityIterator(List<ContentValues> contentValuesList) {
+        mEntityList = new ArrayList<Entity>();
+        Entity entity = new Entity(new ContentValues());
+        for (ContentValues contentValues : contentValuesList) {
+                entity.addSubValue(Data.CONTENT_URI, contentValues);
+        }
+        mEntityList.add(entity);
+        mIterator = mEntityList.iterator();
+    }
+
+    public boolean hasNext() {
+        return mIterator.hasNext();
+    }
+
+    public Entity next() {
+        return mIterator.next();
+    }
+
+    public void reset() {
+        mIterator = mEntityList.iterator();
+    }
+
+    public void close() {
+    }
+}
+
+/**
+ * Represents one contact, which should contain multiple ContentValues like
+ * StructuredName, Email, etc.
+ */
+/* package */ class ContactEntry {
+    private final List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
+
+    public ContentValuesBuilder addContentValues(String mimeType) {
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Data.MIMETYPE, mimeType);
+        mContentValuesList.add(contentValues);
+        return new ContentValuesBuilder(contentValues);
+    }
+
+    public List<ContentValues> getList() {
+        return mContentValuesList;
+    }
+}
+
+/* package */ class ExportTestProvider extends MockContentProvider {
+    final private TestCase mTestCase;
+    final private ArrayList<ContactEntry> mContactEntryList = new ArrayList<ContactEntry>();
+
+    public ExportTestProvider(TestCase testCase) {
+        mTestCase = testCase;
+    }
+
+    public ContactEntry buildInputEntry() {
+        ContactEntry contactEntry = new ContactEntry();
+        mContactEntryList.add(contactEntry);
+        return contactEntry;
+    }
+
+    @Override
+    public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
+            String sortOrder) {
+        mTestCase.assertTrue(uri != null);
+        mTestCase.assertTrue(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
+        final String authority = uri.getAuthority();
+        mTestCase.assertTrue(RawContacts.CONTENT_URI.getAuthority().equals(authority));
+        mTestCase.assertTrue((Data.CONTACT_ID + "=?").equals(selection));
+        mTestCase.assertEquals(1, selectionArgs.length);
+        int id = Integer.parseInt(selectionArgs[0]);
+        mTestCase.assertTrue(id >= 0 && id < mContactEntryList.size());
+
+        return new MockEntityIterator(mContactEntryList.get(id).getList());
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder) {
+        mTestCase.assertTrue(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
+        // In this test, following arguments are not supported.
+        mTestCase.assertNull(selection);
+        mTestCase.assertNull(selectionArgs);
+        mTestCase.assertNull(sortOrder);
+
+        return new MockCursor() {
+            int mCurrentPosition = -1;
+
+            @Override
+            public int getCount() {
+                return mContactEntryList.size();
+            }
+
+            @Override
+            public boolean moveToFirst() {
+                mCurrentPosition = 0;
+                return true;
+            }
+
+            @Override
+            public boolean moveToNext() {
+                if (mCurrentPosition < mContactEntryList.size()) {
+                    mCurrentPosition++;
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+
+            @Override
+            public boolean isBeforeFirst() {
+                return mCurrentPosition < 0;
+            }
+
+            @Override
+            public boolean isAfterLast() {
+                return mCurrentPosition >= mContactEntryList.size();
+            }
+
+            @Override
+            public int getColumnIndex(String columnName) {
+                mTestCase.assertEquals(Contacts._ID, columnName);
+                return 0;
+            }
+
+            @Override
+            public int getInt(int columnIndex) {
+                mTestCase.assertEquals(0, columnIndex);
+                mTestCase.assertTrue(mCurrentPosition >= 0
+                        && mCurrentPosition < mContactEntryList.size());
+                return mCurrentPosition;
+            }
+
+            @Override
+            public String getString(int columnIndex) {
+                return String.valueOf(getInt(columnIndex));
+            }
+
+            @Override
+            public void close() {
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/ImportTestResolver.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/ImportTestResolver.java
new file mode 100644
index 0000000..a1e9d75
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/ImportTestResolver.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Event;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.test.mock.MockContentResolver;
+import android.text.TextUtils;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+/* package */ class ImportTestResolver extends MockContentResolver {
+    final ImportTestProvider mProvider;
+
+    public ImportTestResolver(TestCase testCase) {
+        mProvider = new ImportTestProvider(testCase);
+    }
+
+    @Override
+    public ContentProviderResult[] applyBatch(String authority,
+            ArrayList<ContentProviderOperation> operations) {
+        equalsString(authority, RawContacts.CONTENT_URI.toString());
+        return mProvider.applyBatch(operations);
+    }
+
+    public void addExpectedContentValues(ContentValues expectedContentValues) {
+        mProvider.addExpectedContentValues(expectedContentValues);
+    }
+
+    public void verify() {
+        mProvider.verify();
+    }
+
+    private static boolean equalsString(String a, String b) {
+        if (a == null || a.length() == 0) {
+            return b == null || b.length() == 0;
+        } else {
+            return a.equals(b);
+        }
+    }
+}
+
+/* package */ class ImportTestProvider extends MockContentProvider {
+    private static final Set<String> sKnownMimeTypeSet =
+        new HashSet<String>(Arrays.asList(StructuredName.CONTENT_ITEM_TYPE,
+                Nickname.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE,
+                Email.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE,
+                Im.CONTENT_ITEM_TYPE, Organization.CONTENT_ITEM_TYPE,
+                Event.CONTENT_ITEM_TYPE, Photo.CONTENT_ITEM_TYPE,
+                Note.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE,
+                Relation.CONTENT_ITEM_TYPE, Event.CONTENT_ITEM_TYPE,
+                GroupMembership.CONTENT_ITEM_TYPE));
+
+    final Map<String, Collection<ContentValues>> mMimeTypeToExpectedContentValues;
+
+    private final TestCase mTestCase;
+
+    public ImportTestProvider(TestCase testCase) {
+        mTestCase = testCase;
+        mMimeTypeToExpectedContentValues =
+            new HashMap<String, Collection<ContentValues>>();
+        for (String acceptanbleMimeType : sKnownMimeTypeSet) {
+            // Do not use HashSet since the current implementation changes the content of
+            // ContentValues after the insertion, which make the result of hashCode()
+            // changes...
+            mMimeTypeToExpectedContentValues.put(
+                    acceptanbleMimeType, new ArrayList<ContentValues>());
+        }
+    }
+
+    public void addExpectedContentValues(ContentValues expectedContentValues) {
+        final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE);
+        if (!sKnownMimeTypeSet.contains(mimeType)) {
+            mTestCase.fail(String.format(
+                    "Unknow MimeType %s in the test code. Test code should be broken.",
+                    mimeType));
+        }
+
+        final Collection<ContentValues> contentValuesCollection =
+                mMimeTypeToExpectedContentValues.get(mimeType);
+        contentValuesCollection.add(expectedContentValues);
+    }
+
+    @Override
+    public ContentProviderResult[] applyBatch(
+            ArrayList<ContentProviderOperation> operations) {
+        if (operations == null) {
+            mTestCase.fail("There is no operation.");
+        }
+
+        final int size = operations.size();
+        ContentProviderResult[] fakeResultArray = new ContentProviderResult[size];
+        for (int i = 0; i < size; i++) {
+            Uri uri = Uri.withAppendedPath(RawContacts.CONTENT_URI, String.valueOf(i));
+            fakeResultArray[i] = new ContentProviderResult(uri);
+        }
+
+        for (int i = 0; i < size; i++) {
+            ContentProviderOperation operation = operations.get(i);
+            ContentValues contentValues = operation.resolveValueBackReferences(
+                    fakeResultArray, i);
+        }
+        for (int i = 0; i < size; i++) {
+            ContentProviderOperation operation = operations.get(i);
+            ContentValues actualContentValues = operation.resolveValueBackReferences(
+                    fakeResultArray, i);
+            final Uri uri = operation.getUri();
+            if (uri.equals(RawContacts.CONTENT_URI)) {
+                mTestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME));
+                mTestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE));
+            } else if (uri.equals(Data.CONTENT_URI)) {
+                final String mimeType = actualContentValues.getAsString(Data.MIMETYPE);
+                if (!sKnownMimeTypeSet.contains(mimeType)) {
+                    mTestCase.fail(String.format(
+                            "Unknown MimeType %s. Probably added after developing this test",
+                            mimeType));
+                }
+                // Remove data meaningless in this unit tests.
+                // Specifically, Data.DATA1 - DATA7 are set to null or empty String
+                // regardless of the input, but it may change depending on how
+                // resolver-related code handles it.
+                // Here, we ignore these implementation-dependent specs and
+                // just check whether vCard importer correctly inserts rellevent data.
+                Set<String> keyToBeRemoved = new HashSet<String>();
+                for (Entry<String, Object> entry : actualContentValues.valueSet()) {
+                    Object value = entry.getValue();
+                    if (value == null || TextUtils.isEmpty(value.toString())) {
+                        keyToBeRemoved.add(entry.getKey());
+                    }
+                }
+                for (String key: keyToBeRemoved) {
+                    actualContentValues.remove(key);
+                }
+                /* for testing
+                Log.d("@@@",
+                        String.format("MimeType: %s, data: %s",
+                                mimeType, actualContentValues.toString())); */
+                // Remove RAW_CONTACT_ID entry just for safety, since we do not care
+                // how resolver-related code handles the entry in this unit test,
+                if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) {
+                    actualContentValues.remove(Data.RAW_CONTACT_ID);
+                }
+                final Collection<ContentValues> contentValuesCollection =
+                    mMimeTypeToExpectedContentValues.get(mimeType);
+                if (contentValuesCollection.isEmpty()) {
+                    mTestCase.fail("ContentValues for MimeType " + mimeType
+                            + " is not expected at all (" + actualContentValues + ")");
+                }
+                boolean checked = false;
+                for (ContentValues expectedContentValues : contentValuesCollection) {
+                    /*for testing
+                    Log.d("@@@", "expected: "
+                            + convertToEasilyReadableString(expectedContentValues));
+                    Log.d("@@@", "actual  : "
+                            + convertToEasilyReadableString(actualContentValues));*/
+                    if (equalsForContentValues(expectedContentValues,
+                            actualContentValues)) {
+                        mTestCase.assertTrue(contentValuesCollection.remove(expectedContentValues));
+                        checked = true;
+                        break;
+                    }
+                }
+                if (!checked) {
+                    final StringBuilder builder = new StringBuilder();
+                    builder.append("Unexpected: ");
+                    builder.append(convertToEasilyReadableString(actualContentValues));
+                    builder.append("\nExpected: ");
+                    for (ContentValues expectedContentValues : contentValuesCollection) {
+                        builder.append(convertToEasilyReadableString(expectedContentValues));
+                    }
+                    mTestCase.fail(builder.toString());
+                }
+            } else {
+                mTestCase.fail("Unexpected Uri has come: " + uri);
+            }
+        }  // for (int i = 0; i < size; i++) {
+        return null;
+    }
+
+    public void verify() {
+        StringBuilder builder = new StringBuilder();
+        for (Collection<ContentValues> contentValuesCollection :
+                mMimeTypeToExpectedContentValues.values()) {
+            for (ContentValues expectedContentValues: contentValuesCollection) {
+                builder.append(convertToEasilyReadableString(expectedContentValues));
+                builder.append("\n");
+            }
+        }
+        if (builder.length() > 0) {
+            final String failMsg =
+                "There is(are) remaining expected ContentValues instance(s): \n"
+                    + builder.toString();
+            mTestCase.fail(failMsg);
+        }
+    }
+
+    /**
+     * Utility method to print ContentValues whose content is printed with sorted keys.
+     */
+    private String convertToEasilyReadableString(ContentValues contentValues) {
+        if (contentValues == null) {
+            return "null";
+        }
+        String mimeTypeValue = "";
+        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
+        for (Entry<String, Object> entry : contentValues.valueSet()) {
+            final String key = entry.getKey();
+            final Object value = entry.getValue();
+            final String valueString = (value != null ? value.toString() : null);
+            if (Data.MIMETYPE.equals(key)) {
+                mimeTypeValue = valueString;
+            } else {
+                mTestCase.assertNotNull(key);
+                sortedMap.put(key, valueString);
+            }
+        }
+        StringBuilder builder = new StringBuilder();
+        builder.append(Data.MIMETYPE);
+        builder.append('=');
+        builder.append(mimeTypeValue);
+        for (Entry<String, String> entry : sortedMap.entrySet()) {
+            final String key = entry.getKey();
+            final String value = entry.getValue();
+            builder.append(' ');
+            builder.append(key);
+            builder.append("=\"");
+            builder.append(value);
+            builder.append('"');
+        }
+        return builder.toString();
+    }
+
+    private static boolean equalsForContentValues(
+            ContentValues expected, ContentValues actual) {
+        if (expected == actual) {
+            return true;
+        } else if (expected == null || actual == null || expected.size() != actual.size()) {
+            return false;
+        }
+
+        for (Entry<String, Object> entry : expected.valueSet()) {
+            final String key = entry.getKey();
+            final Object value = entry.getValue();
+            if (!actual.containsKey(key)) {
+                return false;
+            }
+            if (value instanceof byte[]) {
+                Object actualValue = actual.get(key);
+                if (!Arrays.equals((byte[])value, (byte[])actualValue)) {
+                    return false;
+                }
+            } else if (!value.equals(actual.get(key))) {
+                    return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/LineVerifier.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/LineVerifier.java
new file mode 100644
index 0000000..27b95a6
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/LineVerifier.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.content.Context;
+import android.pim.vcard.VCardComposer;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+
+class LineVerifier implements VCardComposer.OneEntryHandler {
+    private final TestCase mTestCase;
+    private final ArrayList<LineVerifierElem> mLineVerifierElemList;
+    private int mVCardType;
+    private int index;
+
+    public LineVerifier(TestCase testCase, int vcardType) {
+        mTestCase = testCase;
+        mLineVerifierElemList = new ArrayList<LineVerifierElem>();
+        mVCardType = vcardType;
+    }
+
+    public LineVerifierElem addLineVerifierElem() {
+        LineVerifierElem lineVerifier = new LineVerifierElem(mTestCase, mVCardType);
+        mLineVerifierElemList.add(lineVerifier);
+        return lineVerifier;
+    }
+
+    public void verify(String vcard) {
+        if (index >= mLineVerifierElemList.size()) {
+            mTestCase.fail("Insufficient number of LineVerifier (" + index + ")");
+        }
+
+        LineVerifierElem lineVerifier = mLineVerifierElemList.get(index);
+        lineVerifier.verify(vcard);
+
+        index++;
+    }
+
+    public boolean onEntryCreated(String vcard) {
+        verify(vcard);
+        return true;
+    }
+
+    public boolean onInit(Context context) {
+        return true;
+    }
+
+    public void onTerminate() {
+    }
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/LineVerifierElem.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/LineVerifierElem.java
new file mode 100644
index 0000000..fc478afcf
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/LineVerifierElem.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.pim.vcard.VCardConfig;
+import android.text.TextUtils;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class LineVerifierElem {
+    private final TestCase mTestCase;
+    private final List<String> mExpectedLineList = new ArrayList<String>();
+    private final boolean mIsV30;
+
+    public LineVerifierElem(TestCase testCase, int vcardType) {
+        mTestCase = testCase;
+        mIsV30 = VCardConfig.isV30(vcardType);
+    }
+
+    public LineVerifierElem addExpected(final String line) {
+        if (!TextUtils.isEmpty(line)) {
+            mExpectedLineList.add(line);
+        }
+        return this;
+    }
+
+    public void verify(final String vcard) {
+        final String[] lineArray = vcard.split("\\r?\\n");
+        final int length = lineArray.length;
+        boolean beginExists = false;
+        boolean endExists = false;
+        boolean versionExists = false;
+
+        for (int i = 0; i < length; i++) {
+            final String line = lineArray[i];
+            if (TextUtils.isEmpty(line)) {
+                continue;
+            }
+
+            if ("BEGIN:VCARD".equalsIgnoreCase(line)) {
+                if (beginExists) {
+                    mTestCase.fail("Multiple \"BEGIN:VCARD\" line found");
+                } else {
+                    beginExists = true;
+                    continue;
+                }
+            } else if ("END:VCARD".equalsIgnoreCase(line)) {
+                if (endExists) {
+                    mTestCase.fail("Multiple \"END:VCARD\" line found");
+                } else {
+                    endExists = true;
+                    continue;
+                }
+            } else if ((mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equalsIgnoreCase(line)) {
+                if (versionExists) {
+                    mTestCase.fail("Multiple VERSION line + found");
+                } else {
+                    versionExists = true;
+                    continue;
+                }
+            }
+
+            if (!beginExists) {
+                mTestCase.fail("Property other than BEGIN came before BEGIN property: "
+                        + line);
+            } else if (endExists) {
+                mTestCase.fail("Property other than END came after END property: "
+                        + line);
+            }
+
+            final int index = mExpectedLineList.indexOf(line);
+            if (index >= 0) {
+                mExpectedLineList.remove(index);
+            } else {
+                mTestCase.fail("Unexpected line: " + line);
+            }
+        }
+
+        if (!mExpectedLineList.isEmpty()) {
+            StringBuffer buffer = new StringBuffer();
+            for (String expectedLine : mExpectedLineList) {
+                buffer.append(expectedLine);
+                buffer.append("\n");
+            }
+
+            mTestCase.fail("Expected line(s) not found:" + buffer.toString());
+        }
+    }
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java
index 190a355..0afad49 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.unit_tests.vcard;
 
 import android.content.ContentValues;
@@ -34,7 +33,7 @@
 import java.util.HashSet;
 import java.util.List;
 
-public class PropertyNodesVerifier extends VNodeBuilder {
+/* package */ class PropertyNodesVerifier extends VNodeBuilder {
     private final List<PropertyNodesVerifierElem> mPropertyNodesVerifierElemList;
     private final AndroidTestCase mAndroidTestCase;
     private int mIndex;
@@ -103,7 +102,7 @@
  * If the node does not exist in the "ordered list", the class refers to
  * "unorderd expected property set" and checks the node is expected somewhere.
  */
-class PropertyNodesVerifierElem {
+/* package */ class PropertyNodesVerifierElem {
     public static class TypeSet extends HashSet<String> {
         public TypeSet(String ... array) {
             super(Arrays.asList(array));
@@ -130,56 +129,60 @@
 
     // WithOrder
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue) {
-        return addNodeWithOrder(propName, propValue, null, null, null, null, null);
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue) {
+        return addExpectedNodeWithOrder(propName, propValue, null, null, null, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
-            ContentValues contentValues) {
-        return addNodeWithOrder(propName, propValue, null, null, contentValues, null, null);
-    }
-
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName,
-            List<String> propValueList, ContentValues contentValues) {
-        return addNodeWithOrder(propName, null, propValueList,
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(
+            String propName, String propValue, ContentValues contentValues) {
+        return addExpectedNodeWithOrder(propName, propValue, null,
                 null, contentValues, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
-            List<String> propValueList) {
-        return addNodeWithOrder(propName, propValue, propValueList, null, null, null, null);
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(
+            String propName, List<String> propValueList, ContentValues contentValues) {
+        return addExpectedNodeWithOrder(propName, null, propValueList,
+                null, contentValues, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, List<String> propValueList) {
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(
+            String propName, String propValue, List<String> propValueList) {
+        return addExpectedNodeWithOrder(propName, propValue, propValueList, null,
+                null, null, null);
+    }
+
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(
+            String propName, List<String> propValueList) {
         final String propValue = concatinateListWithSemiColon(propValueList);
-        return addNodeWithOrder(propName, propValue.toString(), propValueList,
+        return addExpectedNodeWithOrder(propName, propValue.toString(), propValueList,
                 null, null, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
             TypeSet paramMap_TYPE) {
-        return addNodeWithOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
+        return addExpectedNodeWithOrder(propName, propValue, null,
+                null, null, paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName,
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName,
             List<String> propValueList, TypeSet paramMap_TYPE) {
-        return addNodeWithOrder(propName, null, propValueList, null, null,
+        return addExpectedNodeWithOrder(propName, null, propValueList, null, null,
                 paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
             ContentValues paramMap, TypeSet paramMap_TYPE) {
-        return addNodeWithOrder(propName, propValue, null, null,
+        return addExpectedNodeWithOrder(propName, propValue, null, null,
                 paramMap, paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
             List<String> propValueList, TypeSet paramMap_TYPE) {
-        return addNodeWithOrder(propName, propValue, propValueList, null, null,
+        return addExpectedNodeWithOrder(propName, propValue, propValueList, null, null,
                 paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
             List<String> propValueList, byte[] propValue_bytes,
             ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
         if (propValue == null && propValueList != null) {
@@ -199,57 +202,57 @@
 
     // WithoutOrder
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue) {
-        return addNodeWithoutOrder(propName, propValue, null, null, null, null, null);
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue) {
+        return addExpectedNode(propName, propValue, null, null, null, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
             ContentValues contentValues) {
-        return addNodeWithoutOrder(propName, propValue, null, null, contentValues, null, null);
+        return addExpectedNode(propName, propValue, null, null, contentValues, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName,
+    public PropertyNodesVerifierElem addExpectedNode(String propName,
             List<String> propValueList, ContentValues contentValues) {
-        return addNodeWithoutOrder(propName, null,
+        return addExpectedNode(propName, null,
                 propValueList, null, contentValues, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
             List<String> propValueList) {
-        return addNodeWithoutOrder(propName, propValue, propValueList, null, null, null, null);
+        return addExpectedNode(propName, propValue, propValueList, null, null, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName,
+    public PropertyNodesVerifierElem addExpectedNode(String propName,
             List<String> propValueList) {
-        return addNodeWithoutOrder(propName, null, propValueList,
+        return addExpectedNode(propName, null, propValueList,
                 null, null, null, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
             TypeSet paramMap_TYPE) {
-        return addNodeWithoutOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
+        return addExpectedNode(propName, propValue, null, null, null, paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName,
+    public PropertyNodesVerifierElem addExpectedNode(String propName,
             List<String> propValueList, TypeSet paramMap_TYPE) {
         final String propValue = concatinateListWithSemiColon(propValueList);
-        return addNodeWithoutOrder(propName, propValue, propValueList, null, null,
+        return addExpectedNode(propName, propValue, propValueList, null, null,
                 paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
             List<String> propValueList, TypeSet paramMap_TYPE) {
-        return addNodeWithoutOrder(propName, propValue, propValueList, null, null,
+        return addExpectedNode(propName, propValue, propValueList, null, null,
                 paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
             ContentValues paramMap, TypeSet paramMap_TYPE) {
-        return addNodeWithoutOrder(propName, propValue, null, null,
+        return addExpectedNode(propName, propValue, null, null,
                 paramMap, paramMap_TYPE, null);
     }
 
-    public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
+    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
             List<String> propValueList, byte[] propValue_bytes,
             ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
         if (propValue == null && propValueList != null) {
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java
index 212795b..e744a92 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java
@@ -45,24 +45,20 @@
         VCardImporterTests.sPhotoByteArrayForComplicatedCase;
 
     public void testSimpleV21() {
-        VCardVerifier verifier = new VCardVerifier(V21);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(V21);
+        mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "Ando")
                 .put(StructuredName.GIVEN_NAME, "Roid");
-
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("FN", "Roid Ando")
-                .addNodeWithoutOrder("N", "Ando;Roid;;;",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("FN", "Roid Ando")
+                .addExpectedNode("N", "Ando;Roid;;;",
                         Arrays.asList("Ando", "Roid", "", "", ""));
-        verifier.verify();
     }
 
     private void testStructuredNameBasic(int vcardType) {
         final boolean isV30 = VCardConfig.isV30(vcardType);
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
@@ -72,26 +68,24 @@
                 .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven")
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");
 
-        PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("N",
+        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("N",
                         "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                         + "AppropriatePrefix;AppropriateSuffix",
                         Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                                 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
-                .addNodeWithOrder("FN",
+                .addExpectedNodeWithOrder("FN",
                         "AppropriatePrefix AppropriateGivenName "
                         + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
-                .addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
-                .addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
-                .addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
+                .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
+                .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
+                .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
 
         if (isV30) {
-            elem.addNodeWithoutOrder("SORT-STRING",
+            elem.addExpectedNode("SORT-STRING",
                     "AppropriatePhoneticGiven AppropriatePhoneticMiddle "
                     + "AppropriatePhoneticFamily");
         }
-
-        verifier.verify();
     }
 
     public void testStructuredNameBasicV21() {
@@ -110,9 +104,9 @@
      */
     private void testStructuredNameUsePrimaryCommon(int vcardType) {
         final boolean isV30 = (vcardType == V30);
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
                 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
                 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
@@ -123,7 +117,7 @@
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1");
 
         // With "IS_PRIMARY=1". This is what we should use.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
@@ -135,7 +129,7 @@
                 .put(StructuredName.IS_PRIMARY, 1);
 
         // With "IS_PRIMARY=1", but we should ignore this time, since this is second, not first.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
                 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
                 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
@@ -146,26 +140,24 @@
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2")
                 .put(StructuredName.IS_PRIMARY, 1);
 
-        PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("N",
+        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("N",
                         "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                         + "AppropriatePrefix;AppropriateSuffix",
                         Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                                 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
-                .addNodeWithOrder("FN",
+                .addExpectedNodeWithOrder("FN",
                         "AppropriatePrefix AppropriateGivenName "
                         + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
-                .addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
-                .addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
-                .addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
+                .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
+                .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
+                .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
 
         if (isV30) {
-            elem.addNodeWithoutOrder("SORT-STRING",
+            elem.addExpectedNode("SORT-STRING",
                     "AppropriatePhoneticGiven AppropriatePhoneticMiddle "
                     + "AppropriatePhoneticFamily");
         }
-
-        verifier.verify();
     }
 
     public void testStructuredNameUsePrimaryV21() {
@@ -182,9 +174,9 @@
      */
     private void testStructuredNameUseSuperPrimaryCommon(int vcardType) {
         final boolean isV30 = (vcardType == V30);
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
                 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
                 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
@@ -195,7 +187,7 @@
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1");
 
         // With "IS_PRIMARY=1", but we should ignore this time.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
                 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
                 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
@@ -207,7 +199,7 @@
                 .put(StructuredName.IS_PRIMARY, 1);
 
         // With "IS_SUPER_PRIMARY=1". This is what we should use.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
@@ -218,7 +210,7 @@
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle")
                 .put(StructuredName.IS_SUPER_PRIMARY, 1);
 
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3")
                 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3")
                 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3")
@@ -229,26 +221,24 @@
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle3")
                 .put(StructuredName.IS_PRIMARY, 1);
 
-        PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("N",
+        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("N",
                         "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                         + "AppropriatePrefix;AppropriateSuffix",
                         Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                                 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
-                .addNodeWithOrder("FN",
+                .addExpectedNodeWithOrder("FN",
                         "AppropriatePrefix AppropriateGivenName "
                         + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
-                .addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
-                .addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
-                .addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
+                .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
+                .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
+                .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
 
         if (isV30) {
-            elem.addNodeWithoutOrder("SORT-STRING",
+            elem.addExpectedNode("SORT-STRING",
                     "AppropriatePhoneticGiven AppropriatePhoneticMiddle"
                     + " AppropriatePhoneticFamily");
         }
-
-        verifier.verify();
     }
 
     public void testStructuredNameUseSuperPrimaryV21() {
@@ -260,28 +250,21 @@
     }
 
     public void testNickNameV30() {
-        VCardVerifier verifier = new VCardVerifier(V30);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Nickname.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(V30);
+        mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
                 .put(Nickname.NAME, "Nicky");
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-            .addNodeWithOrder("NICKNAME", "Nicky");
-
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+            .addExpectedNodeWithOrder("NICKNAME", "Nicky");
     }
 
     private void testPhoneBasicCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "1")
                 .put(Phone.TYPE, Phone.TYPE_HOME);
-
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "1", new TypeSet("HOME"));
-
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "1", new TypeSet("HOME"));
     }
 
     public void testPhoneBasicV21() {
@@ -296,75 +279,74 @@
      * Tests that vCard composer emits corresponding type param which we expect.
      */
     private void testPhoneVariousTypeSupport(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "10")
                 .put(Phone.TYPE, Phone.TYPE_HOME);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "20")
                 .put(Phone.TYPE, Phone.TYPE_WORK);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "30")
                 .put(Phone.TYPE, Phone.TYPE_FAX_HOME);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "40")
                 .put(Phone.TYPE, Phone.TYPE_FAX_WORK);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "50")
                 .put(Phone.TYPE, Phone.TYPE_MOBILE);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "60")
                 .put(Phone.TYPE, Phone.TYPE_PAGER);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "70")
                 .put(Phone.TYPE, Phone.TYPE_OTHER);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "80")
                 .put(Phone.TYPE, Phone.TYPE_CAR);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "90")
                 .put(Phone.TYPE, Phone.TYPE_COMPANY_MAIN);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "100")
                 .put(Phone.TYPE, Phone.TYPE_ISDN);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "110")
                 .put(Phone.TYPE, Phone.TYPE_MAIN);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "120")
                 .put(Phone.TYPE, Phone.TYPE_OTHER_FAX);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "130")
                 .put(Phone.TYPE, Phone.TYPE_TELEX);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "140")
                 .put(Phone.TYPE, Phone.TYPE_WORK_MOBILE);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "150")
                 .put(Phone.TYPE, Phone.TYPE_WORK_PAGER);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "160")
                 .put(Phone.TYPE, Phone.TYPE_MMS);
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "10", new TypeSet("HOME"))
-                .addNodeWithoutOrder("TEL", "20", new TypeSet("WORK"))
-                .addNodeWithoutOrder("TEL", "30", new TypeSet("HOME", "FAX"))
-                .addNodeWithoutOrder("TEL", "40", new TypeSet("WORK", "FAX"))
-                .addNodeWithoutOrder("TEL", "50", new TypeSet("CELL"))
-                .addNodeWithoutOrder("TEL", "60", new TypeSet("PAGER"))
-                .addNodeWithoutOrder("TEL", "70", new TypeSet("VOICE"))
-                .addNodeWithoutOrder("TEL", "80", new TypeSet("CAR"))
-                .addNodeWithoutOrder("TEL", "90", new TypeSet("WORK", "PREF"))
-                .addNodeWithoutOrder("TEL", "100", new TypeSet("ISDN"))
-                .addNodeWithoutOrder("TEL", "110", new TypeSet("PREF"))
-                .addNodeWithoutOrder("TEL", "120", new TypeSet("FAX"))
-                .addNodeWithoutOrder("TEL", "130", new TypeSet("TLX"))
-                .addNodeWithoutOrder("TEL", "140", new TypeSet("WORK", "CELL"))
-                .addNodeWithoutOrder("TEL", "150", new TypeSet("WORK", "PAGER"))
-                .addNodeWithoutOrder("TEL", "160", new TypeSet("MSG"));
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "10", new TypeSet("HOME"))
+                .addExpectedNode("TEL", "20", new TypeSet("WORK"))
+                .addExpectedNode("TEL", "30", new TypeSet("HOME", "FAX"))
+                .addExpectedNode("TEL", "40", new TypeSet("WORK", "FAX"))
+                .addExpectedNode("TEL", "50", new TypeSet("CELL"))
+                .addExpectedNode("TEL", "60", new TypeSet("PAGER"))
+                .addExpectedNode("TEL", "70", new TypeSet("VOICE"))
+                .addExpectedNode("TEL", "80", new TypeSet("CAR"))
+                .addExpectedNode("TEL", "90", new TypeSet("WORK", "PREF"))
+                .addExpectedNode("TEL", "100", new TypeSet("ISDN"))
+                .addExpectedNode("TEL", "110", new TypeSet("PREF"))
+                .addExpectedNode("TEL", "120", new TypeSet("FAX"))
+                .addExpectedNode("TEL", "130", new TypeSet("TLX"))
+                .addExpectedNode("TEL", "140", new TypeSet("WORK", "CELL"))
+                .addExpectedNode("TEL", "150", new TypeSet("WORK", "PAGER"))
+                .addExpectedNode("TEL", "160", new TypeSet("MSG"));
     }
 
     public void testPhoneVariousTypeSupportV21() {
@@ -379,29 +361,28 @@
      * Tests that "PREF"s are emitted appropriately.
      */
     private void testPhonePrefHandlingCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "1")
                 .put(Phone.TYPE, Phone.TYPE_HOME);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "2")
                 .put(Phone.TYPE, Phone.TYPE_WORK)
                 .put(Phone.IS_PRIMARY, 1);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "3")
                 .put(Phone.TYPE, Phone.TYPE_FAX_HOME)
                 .put(Phone.IS_PRIMARY, 1);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "4")
                 .put(Phone.TYPE, Phone.TYPE_FAX_WORK);
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "4", new TypeSet("WORK", "FAX"))
-                .addNodeWithoutOrder("TEL", "3", new TypeSet("HOME", "FAX", "PREF"))
-                .addNodeWithoutOrder("TEL", "2", new TypeSet("WORK", "PREF"))
-                .addNodeWithoutOrder("TEL", "1", new TypeSet("HOME"));
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "4", new TypeSet("WORK", "FAX"))
+                .addExpectedNode("TEL", "3", new TypeSet("HOME", "FAX", "PREF"))
+                .addExpectedNode("TEL", "2", new TypeSet("WORK", "PREF"))
+                .addExpectedNode("TEL", "1", new TypeSet("HOME"));
     }
 
     public void testPhonePrefHandlingV21() {
@@ -413,50 +394,48 @@
     }
 
     private void testMiscPhoneTypeHandling(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "1")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "Modem");
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "2")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "MSG");
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "3")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "BBS");
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "4")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "VIDEO");
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "5")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "6")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "_AUTO_CELL");  // The old indicator for the type mobile.
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "7")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "\u643A\u5E2F");  // Mobile phone in Japanese Kanji
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "8")
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "invalid");
-
-        PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElemWithEmptyName();
-        elem.addNodeWithoutOrder("TEL", "1", new TypeSet("MODEM"))
-                .addNodeWithoutOrder("TEL", "2", new TypeSet("MSG"))
-                .addNodeWithoutOrder("TEL", "3", new TypeSet("BBS"))
-                .addNodeWithoutOrder("TEL", "4", new TypeSet("VIDEO"))
-                .addNodeWithoutOrder("TEL", "5", new TypeSet("VOICE"))
-                .addNodeWithoutOrder("TEL", "6", new TypeSet("CELL"))
-                .addNodeWithoutOrder("TEL", "7", new TypeSet("CELL"))
-                .addNodeWithoutOrder("TEL", "8", new TypeSet("X-invalid"));
-        verifier.verify();
+        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
+        elem.addExpectedNode("TEL", "1", new TypeSet("MODEM"))
+                .addExpectedNode("TEL", "2", new TypeSet("MSG"))
+                .addExpectedNode("TEL", "3", new TypeSet("BBS"))
+                .addExpectedNode("TEL", "4", new TypeSet("VIDEO"))
+                .addExpectedNode("TEL", "5", new TypeSet("VOICE"))
+                .addExpectedNode("TEL", "6", new TypeSet("CELL"))
+                .addExpectedNode("TEL", "7", new TypeSet("CELL"))
+                .addExpectedNode("TEL", "8", new TypeSet("X-invalid"));
     }
 
     public void testPhoneTypeHandlingV21() {
@@ -468,15 +447,11 @@
     }
 
     private void testEmailBasicCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "sample@example.com");
-
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-            .addNodeWithoutOrder("EMAIL", "sample@example.com");
-
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+            .addExpectedNode("EMAIL", "sample@example.com");
     }
 
     public void testEmailBasicV21() {
@@ -488,28 +463,25 @@
     }
 
     private void testEmailVariousTypeSupportCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "type_home@example.com")
                 .put(Email.TYPE, Email.TYPE_HOME);
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "type_work@example.com")
                 .put(Email.TYPE, Email.TYPE_WORK);
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "type_mobile@example.com")
                 .put(Email.TYPE, Email.TYPE_MOBILE);
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "type_other@example.com")
                 .put(Email.TYPE, Email.TYPE_OTHER);
-
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("EMAIL", "type_home@example.com", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "type_work@example.com", new TypeSet("WORK"))
-                .addNodeWithoutOrder("EMAIL", "type_mobile@example.com", new TypeSet("CELL"))
-                .addNodeWithoutOrder("EMAIL", "type_other@example.com");
-
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "type_work@example.com", new TypeSet("WORK"))
+                .addExpectedNode("EMAIL", "type_mobile@example.com", new TypeSet("CELL"))
+                .addExpectedNode("EMAIL", "type_other@example.com");
     }
 
     public void testEmailVariousTypeSupportV21() {
@@ -521,21 +493,19 @@
     }
 
     private void testEmailPrefHandlingCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "type_home@example.com")
                 .put(Email.TYPE, Email.TYPE_HOME)
                 .put(Email.IS_PRIMARY, 1);
-        entry.buildData(Email.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "type_notype@example.com")
                 .put(Email.IS_PRIMARY, 1);
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("EMAIL", "type_notype@example.com", new TypeSet("PREF"))
-                .addNodeWithoutOrder("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF"));
-
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("EMAIL", "type_notype@example.com", new TypeSet("PREF"))
+                .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF"));
     }
 
     public void testEmailPrefHandlingV21() {
@@ -547,9 +517,8 @@
     }
 
     private void testPostalAddressCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POBOX, "Pobox")
                 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood")
                 .put(StructuredPostal.STREET, "Street")
@@ -559,17 +528,15 @@
                 .put(StructuredPostal.COUNTRY, "Country")
                 .put(StructuredPostal.FORMATTED_ADDRESS, "Formatted Address")
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK);
-
         // adr-value    = 0*6(text-value ";") text-value
         //              ; PO Box, Extended Address, Street, Locality, Region, Postal Code,
         //              ; Country Name
         //
         // The NEIGHBORHOOD field is appended after the CITY field.
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("ADR",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("ADR",
                         Arrays.asList("Pobox", "", "Street", "City Neighborhood",
                                 "Region", "100", "Country"), new TypeSet("WORK"));
-        verifier.verify();
     }
 
     public void testPostalAddressV21() {
@@ -581,14 +548,12 @@
     }
 
     private void testPostalAddressNonNeighborhood(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.CITY, "City");
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("ADR",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("ADR",
                         Arrays.asList("", "", "", "City", "", "", ""), new TypeSet("HOME"));
-        verifier.verify();
     }
 
     public void testPostalAddressNonNeighborhoodV21() {
@@ -600,14 +565,12 @@
     }
 
     private void testPostalAddressNonCity(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood");
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("ADR",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("ADR",
                         Arrays.asList("", "", "", "Neighborhood", "", "", ""), new TypeSet("HOME"));
-        verifier.verify();
     }
 
     public void testPostalAddressNonCityV21() {
@@ -619,18 +582,15 @@
     }
 
     private void testPostalOnlyWithFormattedAddressCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.REGION, "")  // Must be ignored.
                 .put(StructuredPostal.FORMATTED_ADDRESS,
                 "Formatted address CA 123-334 United Statue");
-
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;",
                         Arrays.asList("", "Formatted address CA 123-334 United Statue",
                                 "", "", "", "", ""), new TypeSet("HOME"));
-        verifier.verify();
     }
 
     public void testPostalOnlyWithFormattedAddressV21() {
@@ -646,20 +606,16 @@
      * even when it is partial.
      */
     private void testPostalWithBothStructuredAndFormattedCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POBOX, "Pobox")
                 .put(StructuredPostal.COUNTRY, "Country")
                 .put(StructuredPostal.FORMATTED_ADDRESS,
                         "Formatted address CA 123-334 United Statue");  // Should be ignored
-
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("ADR", "Pobox;;;;;;Country",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("ADR", "Pobox;;;;;;Country",
                         Arrays.asList("Pobox", "", "", "", "", "", "Country"),
                         new TypeSet("HOME"));
-
-        verifier.verify();
     }
 
     public void testPostalWithBothStructuredAndFormattedV21() {
@@ -671,9 +627,9 @@
     }
 
     private void testOrganizationCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Organization.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "CompanyX")
                 .put(Organization.DEPARTMENT, "DepartmentY")
                 .put(Organization.TITLE, "TitleZ")
@@ -681,26 +637,22 @@
                 .put(Organization.OFFICE_LOCATION, "Mountain View")  // Ignored.
                 .put(Organization.PHONETIC_NAME, "PhoneticName!")  // Ignored
                 .put(Organization.SYMBOL, "(^o^)/~~");  // Ignore him (her).
-
-        entry.buildData(Organization.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Organization.CONTENT_ITEM_TYPE)
                 .putNull(Organization.COMPANY)
                 .put(Organization.DEPARTMENT, "DepartmentXX")
                 .putNull(Organization.TITLE);
-
-        entry.buildData(Organization.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "CompanyXYZ")
                 .putNull(Organization.DEPARTMENT)
                 .put(Organization.TITLE, "TitleXYZYX");
-
         // Currently we do not use group but depend on the order.
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithOrder("ORG", "CompanyX;DepartmentY",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNodeWithOrder("ORG", "CompanyX;DepartmentY",
                         Arrays.asList("CompanyX", "DepartmentY"))
-                .addNodeWithOrder("TITLE", "TitleZ")
-                .addNodeWithOrder("ORG", "DepartmentXX")
-                .addNodeWithOrder("ORG", "CompanyXYZ")
-                .addNodeWithOrder("TITLE", "TitleXYZYX");
-        verifier.verify();
+                .addExpectedNodeWithOrder("TITLE", "TitleZ")
+                .addExpectedNodeWithOrder("ORG", "DepartmentXX")
+                .addExpectedNodeWithOrder("ORG", "CompanyXYZ")
+                .addExpectedNodeWithOrder("TITLE", "TitleXYZYX");
     }
 
     public void testOrganizationV21() {
@@ -712,56 +664,47 @@
     }
 
     private void testImVariousTypeSupportCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_AIM)
                 .put(Im.DATA, "aim");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_MSN)
                 .put(Im.DATA, "msn");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_YAHOO)
                 .put(Im.DATA, "yahoo");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_SKYPE)
                 .put(Im.DATA, "skype");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_QQ)
                 .put(Im.DATA, "qq");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK)
                 .put(Im.DATA, "google talk");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_ICQ)
                 .put(Im.DATA, "icq");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_JABBER)
                 .put(Im.DATA, "jabber");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_NETMEETING)
                 .put(Im.DATA, "netmeeting");
 
         // No determined way to express unknown type...
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("X-JABBER", "jabber")
-                .addNodeWithoutOrder("X-ICQ", "icq")
-                .addNodeWithoutOrder("X-GOOGLE-TALK", "google talk")
-                .addNodeWithoutOrder("X-QQ", "qq")
-                .addNodeWithoutOrder("X-SKYPE-USERNAME", "skype")
-                .addNodeWithoutOrder("X-YAHOO", "yahoo")
-                .addNodeWithoutOrder("X-MSN", "msn")
-                .addNodeWithoutOrder("X-NETMEETING", "netmeeting")
-                .addNodeWithoutOrder("X-AIM", "aim");
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("X-JABBER", "jabber")
+                .addExpectedNode("X-ICQ", "icq")
+                .addExpectedNode("X-GOOGLE-TALK", "google talk")
+                .addExpectedNode("X-QQ", "qq")
+                .addExpectedNode("X-SKYPE-USERNAME", "skype")
+                .addExpectedNode("X-YAHOO", "yahoo")
+                .addExpectedNode("X-MSN", "msn")
+                .addExpectedNode("X-NETMEETING", "netmeeting")
+                .addExpectedNode("X-AIM", "aim");
     }
 
     public void testImBasiV21() {
@@ -773,22 +716,20 @@
     }
 
     private void testImPrefHandlingCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_AIM)
                 .put(Im.DATA, "aim1");
-
-        entry.buildData(Im.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                 .put(Im.PROTOCOL, Im.PROTOCOL_AIM)
                 .put(Im.DATA, "aim2")
                 .put(Im.TYPE, Im.TYPE_HOME)
                 .put(Im.IS_PRIMARY, 1);
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("X-AIM", "aim1")
-                .addNodeWithoutOrder("X-AIM", "aim2", new TypeSet("HOME", "PREF"));
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("X-AIM", "aim1")
+                .addExpectedNode("X-AIM", "aim2", new TypeSet("HOME", "PREF"));
     }
 
     public void testImPrefHandlingV21() {
@@ -800,21 +741,19 @@
     }
 
     private void testWebsiteCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Website.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Website.CONTENT_ITEM_TYPE)
                 .put(Website.URL, "http://website.example.android.com/index.html")
                 .put(Website.TYPE, Website.TYPE_BLOG);
-
-        entry.buildData(Website.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Website.CONTENT_ITEM_TYPE)
                 .put(Website.URL, "ftp://ftp.example.android.com/index.html")
                 .put(Website.TYPE, Website.TYPE_FTP);
 
         // We drop TYPE information since vCard (especially 3.0) does not allow us to emit it.
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("URL", "ftp://ftp.example.android.com/index.html")
-                .addNodeWithoutOrder("URL", "http://website.example.android.com/index.html");
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("URL", "ftp://ftp.example.android.com/index.html")
+                .addExpectedNode("URL", "http://website.example.android.com/index.html");
     }
 
     public void testWebsiteV21() {
@@ -837,38 +776,37 @@
     }
 
     private void testEventCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Event.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                 .put(Event.TYPE, Event.TYPE_ANNIVERSARY)
                 .put(Event.START_DATE, "1982-06-16");
-        entry.buildData(Event.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                 .put(Event.TYPE, Event.TYPE_BIRTHDAY)
                 .put(Event.START_DATE, "2008-10-22");
-        entry.buildData(Event.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                 .put(Event.TYPE, Event.TYPE_OTHER)
                 .put(Event.START_DATE, "2018-03-12");
-        entry.buildData(Event.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                 .put(Event.TYPE, Event.TYPE_CUSTOM)
                 .put(Event.LABEL, "The last day")
                 .put(Event.START_DATE, "When the Tower of Hanoi with 64 rings is completed.");
-        entry.buildData(Event.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                 .put(Event.TYPE, Event.TYPE_BIRTHDAY)
                 .put(Event.START_DATE, "2009-05-19");  // Should be ignored.
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("BDAY", "2008-10-22")
-                .addNodeWithoutOrder("X-ANDROID-CUSTOM",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("BDAY", "2008-10-22")
+                .addExpectedNode("X-ANDROID-CUSTOM",
                         getAndroidPropValue(
                                 Event.CONTENT_ITEM_TYPE, "1982-06-16", Event.TYPE_ANNIVERSARY))
-                .addNodeWithoutOrder("X-ANDROID-CUSTOM",
+                .addExpectedNode("X-ANDROID-CUSTOM",
                         getAndroidPropValue(
                                 Event.CONTENT_ITEM_TYPE, "2018-03-12", Event.TYPE_OTHER))
-                .addNodeWithoutOrder("X-ANDROID-CUSTOM",
+                .addExpectedNode("X-ANDROID-CUSTOM",
                         getAndroidPropValue(
                                 Event.CONTENT_ITEM_TYPE,
                                 "When the Tower of Hanoi with 64 rings is completed.",
                                 Event.TYPE_CUSTOM, "The last day"));
-        verifier.verify();
     }
 
     public void testEventV21() {
@@ -880,17 +818,16 @@
     }
 
     private void testNoteCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Note.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "note1");
-        entry.buildData(Note.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "note2")
                 .put(Note.IS_PRIMARY, 1);  // Just ignored.
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithOrder("NOTE", "note1")
-                .addNodeWithOrder("NOTE", "note2");
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNodeWithOrder("NOTE", "note1")
+                .addExpectedNodeWithOrder("NOTE", "note2");
     }
 
     public void testNoteV21() {
@@ -903,22 +840,21 @@
 
     private void testPhotoCommon(int vcardType) {
         final boolean isV30 = vcardType == V30;
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "PhotoTest");
-        entry.buildData(Photo.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Photo.CONTENT_ITEM_TYPE)
                 .put(Photo.PHOTO, sPhotoByteArray);
 
         ContentValues contentValuesForPhoto = new ContentValues();
         contentValuesForPhoto.put("ENCODING", (isV30 ? "b" : "BASE64"));
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("FN", "PhotoTest")
-                .addNodeWithoutOrder("N", "PhotoTest;;;;",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("FN", "PhotoTest")
+                .addExpectedNode("N", "PhotoTest;;;;",
                         Arrays.asList("PhotoTest", "", "", "", ""))
-                .addNodeWithOrder("PHOTO", null, null, sPhotoByteArray,
+                .addExpectedNodeWithOrder("PHOTO", null, null, sPhotoByteArray,
                         contentValuesForPhoto, new TypeSet("JPEG"), null);
-        verifier.verify();
     }
 
     public void testPhotoV21() {
@@ -930,16 +866,13 @@
     }
 
     private void testRelationCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Relation.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        mVerifier.addInputEntry().addContentValues(Relation.CONTENT_ITEM_TYPE)
                 .put(Relation.TYPE, Relation.TYPE_MOTHER)
                 .put(Relation.NAME, "Ms. Mother");
-        ImportVerifierElem elem = verifier.addImportVerifier();
-        elem.addExpected(Relation.CONTENT_ITEM_TYPE)
+        mVerifier.addContentValuesVerifierElem().addExpected(Relation.CONTENT_ITEM_TYPE)
                 .put(Relation.TYPE, Relation.TYPE_MOTHER)
                 .put(Relation.NAME, "Ms. Mother");
-        verifier.verify();
     }
 
     public void testRelationV21() {
@@ -951,23 +884,20 @@
     }
 
     public void testV30HandleEscape() {
-        final int vcardType = V30;
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(V30);
+        mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\\")
                 .put(StructuredName.GIVEN_NAME, ";")
                 .put(StructuredName.MIDDLE_NAME, ",")
                 .put(StructuredName.PREFIX, "\n")
                 .put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]");
         // Verifies the vCard String correctly escapes each character which must be escaped.
-        verifier.addLineVerifier()
+        mVerifier.addLineVerifierElem()
                 .addExpected("N:\\\\;\\;;\\,;\\n;")
                 .addExpected("FN:[<{Unescaped:Asciis}>]");
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("FN", "[<{Unescaped:Asciis}>]")
-                .addNodeWithoutOrder("N", Arrays.asList("\\", ";", ",", "\n", ""));
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("FN", "[<{Unescaped:Asciis}>]")
+                .addExpectedNode("N", Arrays.asList("\\", ";", ",", "\n", ""));
     }
 
     /**
@@ -976,52 +906,47 @@
      * This test verifies the functionality.
      */
     public void testNickNameV21() {
-        VCardVerifier verifier = new VCardVerifier(V21);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Nickname.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(V21);
+        mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
                 .put(Nickname.NAME, "Nicky");
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithOrder("X-ANDROID-CUSTOM",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("X-ANDROID-CUSTOM",
                         Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;");
-        verifier.addImportVerifier()
-                .addExpected(Nickname.CONTENT_ITEM_TYPE)
-                        .put(Nickname.NAME, "Nicky");
-        verifier.verify();
+        mVerifier.addContentValuesVerifierElem().addExpected(Nickname.CONTENT_ITEM_TYPE)
+                .put(Nickname.NAME, "Nicky");
     }
 
     public void testTolerateBrokenPhoneNumberEntryV21() {
-        VCardVerifier verifier = new VCardVerifier(V21);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(V21);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_HOME)
                 .put(Phone.NUMBER, "111-222-3333 (Miami)\n444-5555-666 (Tokyo);"
                         + "777-888-9999 (Chicago);111-222-3333 (Miami)");
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "111-222-3333", new TypeSet("HOME"))
-                .addNodeWithoutOrder("TEL", "444-555-5666", new TypeSet("HOME"))
-                .addNodeWithoutOrder("TEL", "777-888-9999", new TypeSet("HOME"));
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "111-222-3333", new TypeSet("HOME"))
+                .addExpectedNode("TEL", "444-555-5666", new TypeSet("HOME"))
+                .addExpectedNode("TEL", "777-888-9999", new TypeSet("HOME"));
     }
 
     private void testPickUpNonEmptyContentValuesCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.IS_PRIMARY, 1);  // Empty name. Should be ignored.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "family1");  // Not primary. Should be ignored.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.IS_PRIMARY, 1)
                 .put(StructuredName.FAMILY_NAME, "family2");  // This entry is what we want.
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.IS_PRIMARY, 1)
                 .put(StructuredName.FAMILY_NAME, "family3");
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "family4");
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("N", Arrays.asList("family2", "", "", "", ""))
-                .addNodeWithoutOrder("FN", "family2");
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("N", Arrays.asList("family2", "", "", "", ""))
+                .addExpectedNode("FN", "family2");
     }
 
     public void testPickUpNonEmptyContentValuesV21() {
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java
index d891497..45d3e3c 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java
@@ -13,13 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.unit_tests.vcard;
 
 import android.content.ContentValues;
 import android.pim.vcard.VCardConfig;
-import android.pim.vcard.VCardParser_V21;
-import android.pim.vcard.exception.VCardException;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Event;
@@ -34,7 +31,6 @@
 import com.android.unit_tests.R;
 import com.android.unit_tests.vcard.PropertyNodesVerifierElem.TypeSet;
 
-import java.io.IOException;
 import java.util.Arrays;
 
 public class VCardImporterTests extends VCardTestsBase {
@@ -407,26 +403,24 @@
         }
     }
 
-    public void testV21SimpleCase1_Parsing() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("N", "Ando;Roid;", Arrays.asList("Ando", "Roid", ""));
-        verifier.verify(R.raw.v21_simple_1, V21);
+    public void testV21SimpleCase1_Parsing() {
+        mVerifier.initForImportTest(V21, R.raw.v21_simple_1);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("N", "Ando;Roid;", Arrays.asList("Ando", "Roid", ""));
     }
 
-    public void testV21SimpleCase1_Type_Generic() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        verifier.addImportVerifierElem()
+    public void testV21SimpleCase1_Type_Generic() {
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, R.raw.v21_simple_1);
+        mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE)
                         .put(StructuredName.FAMILY_NAME, "Ando")
                         .put(StructuredName.GIVEN_NAME, "Roid")
                         .put(StructuredName.DISPLAY_NAME, "Roid Ando");
-        verifier.verify(R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
-    public void testV21SimpleCase1_Type_Japanese() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        verifier.addImportVerifierElem()
+    public void testV21SimpleCase1_Type_Japanese() {
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, R.raw.v21_simple_1);
+        mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE)
                         .put(StructuredName.FAMILY_NAME, "Ando")
                         .put(StructuredName.GIVEN_NAME, "Roid")
@@ -434,49 +428,46 @@
                         // the order is remained to be US's:
                         // "Prefix Given Middle Family Suffix"
                         .put(StructuredName.DISPLAY_NAME, "Roid Ando");
-        verifier.verify(R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
     }
 
-    public void testV21SimpleCase2() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        verifier.addImportVerifierElem()
+    public void testV21SimpleCase2() {
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, R.raw.v21_simple_2);
+        mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE)
                         .put(StructuredName.DISPLAY_NAME, "Ando Roid");
-        verifier.verify(R.raw.v21_simple_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
-    public void testV21SimpleCase3() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        verifier.addImportVerifierElem()
+    public void testV21SimpleCase3() {
+        mVerifier.initForImportTest(V21, R.raw.v21_simple_3);
+        mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE)
                         .put(StructuredName.FAMILY_NAME, "Ando")
                         .put(StructuredName.GIVEN_NAME, "Roid")
                         // "FN" field should be prefered since it should contain the original
                         // order intended by the author of the file.
                         .put(StructuredName.DISPLAY_NAME, "Ando Roid");
-        verifier.verify(R.raw.v21_simple_3, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
     /**
      * Tests ';' is properly handled by VCardParser implementation.
      */
-    public void testV21BackslashCase_Parsing() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", ";A;B\\;C\\;;D;:E;\\\\;",
+    public void testV21BackslashCase_Parsing() {
+        mVerifier.initForImportTest(V21, R.raw.v21_backslash);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", ";A;B\\;C\\;;D;:E;\\\\;",
                         Arrays.asList("", "A;B\\", "C\\;", "D", ":E", "\\\\", ""))
-                .addNodeWithOrder("FN", "A;B\\C\\;D:E\\\\");
-        verifier.verify(R.raw.v21_backslash, V21);
+                .addExpectedNodeWithOrder("FN", "A;B\\C\\;D:E\\\\");
+        
     }
 
     /**
      * Tests ContactStruct correctly ignores redundant fields in "N" property values and
      * inserts name related data.
      */
-    public void testV21BackslashCase() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        verifier.addImportVerifierElem()
+    public void testV21BackslashCase() {
+        mVerifier.initForImportTest(V21, R.raw.v21_backslash);
+        mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE)
                         // FAMILY_NAME is empty and removed in this test...
                         .put(StructuredName.GIVEN_NAME, "A;B\\")
@@ -484,150 +475,135 @@
                         .put(StructuredName.PREFIX, "D")
                         .put(StructuredName.SUFFIX, ":E")
                         .put(StructuredName.DISPLAY_NAME, "A;B\\C\\;D:E\\\\");
-        verifier.verify(R.raw.v21_backslash, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
-    public void testOrgBeforTitle() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testOrgBeforTitle() {
+        mVerifier.initForImportTest(V21, R.raw.v21_org_before_title);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.DISPLAY_NAME, "Normal Guy");
-
         elem.addExpected(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "Company")
                 .put(Organization.DEPARTMENT, "Organization Devision Room Sheet No.")
                 .put(Organization.TITLE, "Excellent Janitor")
                 .put(Organization.TYPE, Organization.TYPE_WORK);
-        verifier.verify(R.raw.v21_org_before_title, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
-    public void testTitleBeforOrg() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testTitleBeforOrg() {
+        mVerifier.initForImportTest(V21, R.raw.v21_title_before_org);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.DISPLAY_NAME, "Nice Guy");
-
         elem.addExpected(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "Marverous")
                 .put(Organization.DEPARTMENT, "Perfect Great Good Bad Poor")
                 .put(Organization.TITLE, "Cool Title")
                 .put(Organization.TYPE, Organization.TYPE_WORK);
-        verifier.verify(R.raw.v21_title_before_org, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
     /**
      * Verifies that vCard importer correctly interpret "PREF" attribute to IS_PRIMARY.
      * The data contain three cases: one "PREF", no "PREF" and multiple "PREF", in each type.
      */
-    public void testV21PrefToIsPrimary() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testV21PrefToIsPrimary() {
+        mVerifier.initForImportTest(V21, R.raw.v21_pref_handling);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.DISPLAY_NAME, "Smith");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "1")
                 .put(Phone.TYPE, Phone.TYPE_HOME);
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "2")
                 .put(Phone.TYPE, Phone.TYPE_WORK)
                 .put(Phone.IS_PRIMARY, 1);
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "3")
                 .put(Phone.TYPE, Phone.TYPE_ISDN);
-
         elem.addExpected(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "test@example.com")
                 .put(Email.TYPE, Email.TYPE_HOME)
                 .put(Email.IS_PRIMARY, 1);
-
         elem.addExpected(Email.CONTENT_ITEM_TYPE)
                 .put(Email.DATA, "test2@examination.com")
                 .put(Email.TYPE, Email.TYPE_MOBILE)
                 .put(Email.IS_PRIMARY, 1);
-
         elem.addExpected(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "Company")
                 .put(Organization.TITLE, "Engineer")
                 .put(Organization.TYPE, Organization.TYPE_WORK);
-
         elem.addExpected(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "Mystery")
                 .put(Organization.TITLE, "Blogger")
                 .put(Organization.TYPE, Organization.TYPE_WORK);
-
         elem.addExpected(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.COMPANY, "Poetry")
                 .put(Organization.TITLE, "Poet")
                 .put(Organization.TYPE, Organization.TYPE_WORK);
-        verifier.verify(R.raw.v21_pref_handling, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
     /**
      * Tests all the properties in a complicated vCard are correctly parsed by the VCardParser.
      */
-    public void testV21ComplicatedCase_Parsing() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", "Gump;Forrest;Hoge;Pos;Tao",
+    public void testV21ComplicatedCase_Parsing() {
+        mVerifier.initForImportTest(V21, R.raw.v21_complicated);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", "Gump;Forrest;Hoge;Pos;Tao",
                         Arrays.asList("Gump", "Forrest", "Hoge", "Pos", "Tao"))
-                .addNodeWithOrder("FN", "Joe Due")
-                .addNodeWithOrder("ORG", "Gump Shrimp Co.;Sales Dept.;Manager;Fish keeper",
+                .addExpectedNodeWithOrder("FN", "Joe Due")
+                .addExpectedNodeWithOrder("ORG", "Gump Shrimp Co.;Sales Dept.;Manager;Fish keeper",
                         Arrays.asList("Gump Shrimp Co.", "Sales Dept.;Manager", "Fish keeper"))
-                .addNodeWithOrder("ROLE", "Fish Cake Keeper!")
-                .addNodeWithOrder("TITLE", "Shrimp Man")
-                .addNodeWithOrder("X-CLASS", "PUBLIC")
-                .addNodeWithOrder("TEL", "(111) 555-1212", new TypeSet("WORK", "VOICE"))
-                .addNodeWithOrder("TEL", "(404) 555-1212", new TypeSet("HOME", "VOICE"))
-                .addNodeWithOrder("TEL", "0311111111", new TypeSet("CELL"))
-                .addNodeWithOrder("TEL", "0322222222", new TypeSet("VIDEO"))
-                .addNodeWithOrder("TEL", "0333333333", new TypeSet("VOICE"))
-                .addNodeWithOrder("ADR",
+                .addExpectedNodeWithOrder("ROLE", "Fish Cake Keeper!")
+                .addExpectedNodeWithOrder("TITLE", "Shrimp Man")
+                .addExpectedNodeWithOrder("X-CLASS", "PUBLIC")
+                .addExpectedNodeWithOrder("TEL", "(111) 555-1212", new TypeSet("WORK", "VOICE"))
+                .addExpectedNodeWithOrder("TEL", "(404) 555-1212", new TypeSet("HOME", "VOICE"))
+                .addExpectedNodeWithOrder("TEL", "0311111111", new TypeSet("CELL"))
+                .addExpectedNodeWithOrder("TEL", "0322222222", new TypeSet("VIDEO"))
+                .addExpectedNodeWithOrder("TEL", "0333333333", new TypeSet("VOICE"))
+                .addExpectedNodeWithOrder("ADR",
                         ";;100 Waters Edge;Baytown;LA;30314;United States of America",
                         Arrays.asList("", "", "100 Waters Edge", "Baytown",
                                 "LA", "30314", "United States of America"),
                                 null, null, new TypeSet("WORK"), null)
-                .addNodeWithOrder("LABEL",
+                .addExpectedNodeWithOrder("LABEL",
                         "100 Waters Edge\r\nBaytown, LA 30314\r\nUnited  States of America",
                         null, null, mContentValuesForQP, new TypeSet("WORK"), null)
-                .addNodeWithOrder("ADR",
+                .addExpectedNodeWithOrder("ADR",
                         ";;42 Plantation St.;Baytown;LA;30314;United States of America",
                         Arrays.asList("", "", "42 Plantation St.", "Baytown",
                                 "LA", "30314", "United States of America"), null, null,
                                 new TypeSet("HOME"), null)
-                .addNodeWithOrder("LABEL",
+                .addExpectedNodeWithOrder("LABEL",
                         "42 Plantation St.\r\nBaytown, LA 30314\r\nUnited  States of America",
                         null, null, mContentValuesForQP,
                         new TypeSet("HOME"), null)
-                .addNodeWithOrder("EMAIL", "forrestgump@walladalla.com",
+                .addExpectedNodeWithOrder("EMAIL", "forrestgump@walladalla.com",
                         new TypeSet("PREF", "INTERNET"))
-                .addNodeWithOrder("EMAIL", "cell@example.com", new TypeSet("CELL"))
-                .addNodeWithOrder("NOTE", "The following note is the example from RFC 2045.")
-                .addNodeWithOrder("NOTE",
+                .addExpectedNodeWithOrder("EMAIL", "cell@example.com", new TypeSet("CELL"))
+                .addExpectedNodeWithOrder("NOTE", "The following note is the example from RFC 2045.")
+                .addExpectedNodeWithOrder("NOTE",
                         "Now's the time for all folk to come to the aid of their country.",
                         null, null, mContentValuesForQP, null, null)
-                .addNodeWithOrder("PHOTO", null,
+                .addExpectedNodeWithOrder("PHOTO", null,
                         null, sPhotoByteArrayForComplicatedCase, mContentValuesForBase64V21,
                         new TypeSet("JPEG"), null)
-                .addNodeWithOrder("X-ATTRIBUTE", "Some String")
-                .addNodeWithOrder("BDAY", "19800101")
-                .addNodeWithOrder("GEO", "35.6563854,139.6994233")
-                .addNodeWithOrder("URL", "http://www.example.com/")
-                .addNodeWithOrder("REV", "20080424T195243Z");
-        verifier.verify(R.raw.v21_complicated, V21);
+                .addExpectedNodeWithOrder("X-ATTRIBUTE", "Some String")
+                .addExpectedNodeWithOrder("BDAY", "19800101")
+                .addExpectedNodeWithOrder("GEO", "35.6563854,139.6994233")
+                .addExpectedNodeWithOrder("URL", "http://www.example.com/")
+                .addExpectedNodeWithOrder("REV", "20080424T195243Z");
     }
 
     /**
      * Checks ContactStruct correctly inserts values in a complicated vCard
      * into ContentResolver.
      */
-    public void testV21ComplicatedCase() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testV21ComplicatedCase() {
+        mVerifier.initForImportTest(V21, R.raw.v21_complicated);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "Gump")
                 .put(StructuredName.GIVEN_NAME, "Forrest")
@@ -635,36 +611,29 @@
                 .put(StructuredName.PREFIX, "Pos")
                 .put(StructuredName.SUFFIX, "Tao")
                 .put(StructuredName.DISPLAY_NAME, "Joe Due");
-        
         elem.addExpected(Organization.CONTENT_ITEM_TYPE)
                 .put(Organization.TYPE, Organization.TYPE_WORK)
                 .put(Organization.COMPANY, "Gump Shrimp Co.")
                 .put(Organization.DEPARTMENT, "Sales Dept.;Manager Fish keeper")
                 .put(Organization.TITLE, "Shrimp Man");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_WORK)
                 // Phone number is expected to be formated with NAMP format in default.
                 .put(Phone.NUMBER, "111-555-1212");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_HOME)
                 .put(Phone.NUMBER, "404-555-1212");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_MOBILE)
                 .put(Phone.NUMBER, "031-111-1111");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "VIDEO")
                 .put(Phone.NUMBER, "032-222-2222");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "VOICE")
                 .put(Phone.NUMBER, "033-333-3333");
-
         elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
                 .put(StructuredPostal.COUNTRY, "United States of America")
@@ -674,7 +643,6 @@
                 .put(StructuredPostal.STREET, "100 Waters Edge")
                 .put(StructuredPostal.FORMATTED_ADDRESS,
                         "100 Waters Edge Baytown LA 30314 United States of America");
-
         elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME)
                 .put(StructuredPostal.COUNTRY, "United States of America")
@@ -684,60 +652,51 @@
                 .put(StructuredPostal.STREET, "42 Plantation St.")
                 .put(StructuredPostal.FORMATTED_ADDRESS,
                         "42 Plantation St. Baytown LA 30314 United States of America");
-
         elem.addExpected(Email.CONTENT_ITEM_TYPE)
                 // "TYPE=INTERNET" -> TYPE_CUSTOM + the label "INTERNET"
                 .put(Email.TYPE, Email.TYPE_CUSTOM)
                 .put(Email.LABEL, "INTERNET")
                 .put(Email.DATA, "forrestgump@walladalla.com")
                 .put(Email.IS_PRIMARY, 1);
-
         elem.addExpected(Email.CONTENT_ITEM_TYPE)
                 .put(Email.TYPE, Email.TYPE_MOBILE)
                 .put(Email.DATA, "cell@example.com");
-
         elem.addExpected(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "The following note is the example from RFC 2045.");
-
         elem.addExpected(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE,
                         "Now's the time for all folk to come to the aid of their country.");
-
         elem.addExpected(Photo.CONTENT_ITEM_TYPE)
                 // No information about its image format can be inserted.
                 .put(Photo.PHOTO, sPhotoByteArrayForComplicatedCase);
-
         elem.addExpected(Event.CONTENT_ITEM_TYPE)
                 .put(Event.START_DATE, "19800101")
                 .put(Event.TYPE, Event.TYPE_BIRTHDAY);
-
         elem.addExpected(Website.CONTENT_ITEM_TYPE)
                 .put(Website.URL, "http://www.example.com/")
                 .put(Website.TYPE, Website.TYPE_HOMEPAGE);
-        verifier.verify(R.raw.v21_complicated, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
-    public void testV30Simple_Parsing() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "3.0")
-                .addNodeWithOrder("FN", "And Roid")
-                .addNodeWithOrder("N", "And;Roid;;;", Arrays.asList("And", "Roid", "", "", ""))
-                .addNodeWithOrder("ORG", "Open;Handset; Alliance",
+    public void testV30Simple_Parsing() {
+        mVerifier.initForImportTest(V30, R.raw.v30_simple);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "3.0")
+                .addExpectedNodeWithOrder("FN", "And Roid")
+                .addExpectedNodeWithOrder("N", "And;Roid;;;", Arrays.asList("And", "Roid", "", "", ""))
+                .addExpectedNodeWithOrder("ORG", "Open;Handset; Alliance",
                         Arrays.asList("Open", "Handset", " Alliance"))
-                .addNodeWithOrder("SORT-STRING", "android")
-                .addNodeWithOrder("TEL", "0300000000", new TypeSet("PREF", "VOICE"))
-                .addNodeWithOrder("CLASS", "PUBLIC")
-                .addNodeWithOrder("X-GNO", "0")
-                .addNodeWithOrder("X-GN", "group0")
-                .addNodeWithOrder("X-REDUCTION", "0")
-                .addNodeWithOrder("REV", "20081031T065854Z");
-        verifier.verify(R.raw.v30_simple, V30);
+                .addExpectedNodeWithOrder("SORT-STRING", "android")
+                .addExpectedNodeWithOrder("TEL", "0300000000", new TypeSet("PREF", "VOICE"))
+                .addExpectedNodeWithOrder("CLASS", "PUBLIC")
+                .addExpectedNodeWithOrder("X-GNO", "0")
+                .addExpectedNodeWithOrder("X-GN", "group0")
+                .addExpectedNodeWithOrder("X-REDUCTION", "0")
+                .addExpectedNodeWithOrder("REV", "20081031T065854Z");
     }
 
-    public void testV30Simple() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testV30Simple() {
+        mVerifier.initForImportTest(V30, R.raw.v30_simple);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "And")
                 .put(StructuredName.GIVEN_NAME, "Roid")
@@ -752,32 +711,30 @@
                 .put(Phone.LABEL, "VOICE")
                 .put(Phone.NUMBER, "030-000-0000")
                 .put(Phone.IS_PRIMARY, 1);
-        verifier.verify(R.raw.v30_simple, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8);
     }
 
-    public void testV21Japanese1_Parsing() throws IOException, VCardException {
+    public void testV21Japanese1_Parsing() {
         // Though Japanese careers append ";;;;" at the end of the value of "SOUND",
         // vCard 2.1/3.0 specification does not allow multiple values.
         // Do not need to handle it as multiple values.
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1", null, null, null, null, null)
-                .addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9;;;;",
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
+                R.raw.v21_japanese_1);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1", null, null, null, null, null)
+                .addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9;;;;",
                         Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9", "", "", "", ""),
                         null, mContentValuesForSJis, null, null)
-                .addNodeWithOrder("SOUND",
+                .addExpectedNodeWithOrder("SOUND",
                         "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E;;;;",
                         null, null, mContentValuesForSJis,
                         new TypeSet("X-IRMC-N"), null)
-                .addNodeWithOrder("TEL", "0300000000", null, null, null,
+                .addExpectedNodeWithOrder("TEL", "0300000000", null, null, null,
                         new TypeSet("VOICE", "PREF"), null);
-        verifier.verify(R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
     }
 
-    private void testV21Japanese1Common(int resId, int vcardType, boolean japanese)
-            throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    private void testV21Japanese1Common(int resId, int vcardType, boolean japanese) {
+        mVerifier.initForImportTest(vcardType, resId);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9")
                 .put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9")
@@ -785,21 +742,19 @@
                 // ContactStruct care it.
                 .put(StructuredName.PHONETIC_GIVEN_NAME,
                         "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E");
-
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 // Phone number formatting is different.
                 .put(Phone.NUMBER, (japanese ? "03-0000-0000" : "030-000-0000"))
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "VOICE")
                 .put(Phone.IS_PRIMARY, 1);
-        verifier.verify(resId, vcardType);
     }
 
     /**
      * Verifies vCard with Japanese can be parsed correctly with
      * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_GENERIC_UTF8}.
      */
-    public void testV21Japanese1_Type_Generic_Utf8() throws IOException, VCardException {
+    public void testV21Japanese1_Type_Generic_Utf8() {
         testV21Japanese1Common(
                 R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, false);
     }
@@ -808,7 +763,7 @@
      * Verifies vCard with Japanese can be parsed correctly with
      * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_SJIS}.
      */
-    public void testV21Japanese1_Type_Japanese_Sjis() throws IOException, VCardException {
+    public void testV21Japanese1_Type_Japanese_Sjis() {
         testV21Japanese1Common(
                 R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, true);
     }
@@ -818,26 +773,27 @@
      * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_UTF8}.
      * since vCard 2.1 specifies the charset of each line if it contains non-Ascii.
      */
-    public void testV21Japanese1_Type_Japanese_Utf8() throws IOException, VCardException {
+    public void testV21Japanese1_Type_Japanese_Utf8() {
         testV21Japanese1Common(
                 R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8, true);
     }
 
-    public void testV21Japanese2_Parsing() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", "\u5B89\u85E4;\u30ED\u30A4\u30C9\u0031;;;",
+    public void testV21Japanese2_Parsing() {
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
+                R.raw.v21_japanese_2);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", "\u5B89\u85E4;\u30ED\u30A4\u30C9\u0031;;;",
                         Arrays.asList("\u5B89\u85E4", "\u30ED\u30A4\u30C9\u0031",
                                 "", "", ""),
                         null, mContentValuesForSJis, null, null)
-                .addNodeWithOrder("FN", "\u5B89\u85E4\u0020\u30ED\u30A4\u30C9\u0020\u0031",
+                .addExpectedNodeWithOrder("FN", "\u5B89\u85E4\u0020\u30ED\u30A4\u30C9\u0020\u0031",
                         null, null, mContentValuesForSJis, null, null)
-                .addNodeWithOrder("SOUND",
+                .addExpectedNodeWithOrder("SOUND",
                         "\uFF71\uFF9D\uFF84\uFF9E\uFF73;\uFF9B\uFF72\uFF84\uFF9E\u0031;;;",
                         null, null, mContentValuesForSJis,
                         new TypeSet("X-IRMC-N"), null)
-                .addNodeWithOrder("ADR",
+                .addExpectedNodeWithOrder("ADR",
                         ";\u6771\u4EAC\u90FD\u6E0B\u8C37\u533A\u685C" +
                         "\u4E18\u753A\u0032\u0036\u002D\u0031\u30BB" +
                         "\u30EB\u30EA\u30A2\u30F3\u30BF\u30EF\u30FC\u0036" +
@@ -848,14 +804,13 @@
                                 "\u30EB\u30EA\u30A2\u30F3\u30BF\u30EF\u30FC" +
                                 "\u0036\u968E", "", "", "", "150-8512", ""),
                         null, mContentValuesForQPAndSJis, new TypeSet("HOME"), null)
-                .addNodeWithOrder("NOTE", "\u30E1\u30E2", null, null,
+                .addExpectedNodeWithOrder("NOTE", "\u30E1\u30E2", null, null,
                         mContentValuesForQPAndSJis, null, null);
-        verifier.verify(R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
     }
 
-    public void testV21Japanese2_Type_Generic_Utf8() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testV21Japanese2_Type_Generic_Utf8() {
+        mVerifier.initForImportTest(V21, R.raw.v21_japanese_2);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4")
                 .put(StructuredName.GIVEN_NAME, "\u30ED\u30A4\u30C9\u0031")
@@ -865,7 +820,6 @@
                 // even though VCardParser side does not care it.
                 .put(StructuredName.PHONETIC_FAMILY_NAME, "\uFF71\uFF9D\uFF84\uFF9E\uFF73")
                 .put(StructuredName.PHONETIC_GIVEN_NAME, "\uFF9B\uFF72\uFF84\uFF9E\u0031");
-
         elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POSTCODE, "150-8512")
                 .put(StructuredPostal.STREET,
@@ -881,58 +835,56 @@
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME);
         elem.addExpected(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "\u30E1\u30E2");
-        verifier.verify(R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
     }
 
-    public void testV21MultipleEntryCase_Parse() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033;;;;",
+    public void testV21MultipleEntryCase_Parse() {
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
+                R.raw.v21_multiple_entry);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033;;;;",
                         Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0033", "", "", "", ""),
                         null, mContentValuesForSJis, null, null)
-                .addNodeWithOrder("SOUND",
+                .addExpectedNodeWithOrder("SOUND",
                         "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0033;;;;",
                         null, null, mContentValuesForSJis,
                         new TypeSet("X-IRMC-N"), null)
-                .addNodeWithOrder("TEL", "9", new TypeSet("X-NEC-SECRET"))
-                .addNodeWithOrder("TEL", "10", new TypeSet("X-NEC-HOTEL"))
-                .addNodeWithOrder("TEL", "11", new TypeSet("X-NEC-SCHOOL"))
-                .addNodeWithOrder("TEL", "12", new TypeSet("FAX", "HOME"));
-
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034;;;;",
+                .addExpectedNodeWithOrder("TEL", "9", new TypeSet("X-NEC-SECRET"))
+                .addExpectedNodeWithOrder("TEL", "10", new TypeSet("X-NEC-HOTEL"))
+                .addExpectedNodeWithOrder("TEL", "11", new TypeSet("X-NEC-SCHOOL"))
+                .addExpectedNodeWithOrder("TEL", "12", new TypeSet("FAX", "HOME"));
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034;;;;",
                         Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0034", "", "", "", ""),
                         null, mContentValuesForSJis, null, null)
-                .addNodeWithOrder("SOUND",
+                .addExpectedNodeWithOrder("SOUND",
                         "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0034;;;;",
                         null, null, mContentValuesForSJis,
                         new TypeSet("X-IRMC-N"), null)
-                .addNodeWithOrder("TEL", "13", new TypeSet("MODEM"))
-                .addNodeWithOrder("TEL", "14", new TypeSet("PAGER"))
-                .addNodeWithOrder("TEL", "15", new TypeSet("X-NEC-FAMILY"))
-                .addNodeWithOrder("TEL", "16", new TypeSet("X-NEC-GIRL"));
-
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035;;;;",
+                .addExpectedNodeWithOrder("TEL", "13", new TypeSet("MODEM"))
+                .addExpectedNodeWithOrder("TEL", "14", new TypeSet("PAGER"))
+                .addExpectedNodeWithOrder("TEL", "15", new TypeSet("X-NEC-FAMILY"))
+                .addExpectedNodeWithOrder("TEL", "16", new TypeSet("X-NEC-GIRL"));
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035;;;;",
                         Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0035", "", "", "", ""),
                         null, mContentValuesForSJis, null, null)
-                .addNodeWithOrder("SOUND",
+                .addExpectedNodeWithOrder("SOUND",
                         "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0035;;;;",
                         null, null, mContentValuesForSJis,
                         new TypeSet("X-IRMC-N"), null)
-                .addNodeWithOrder("TEL", "17", new TypeSet("X-NEC-BOY"))
-                .addNodeWithOrder("TEL", "18", new TypeSet("X-NEC-FRIEND"))
-                .addNodeWithOrder("TEL", "19", new TypeSet("X-NEC-PHS"))
-                .addNodeWithOrder("TEL", "20", new TypeSet("X-NEC-RESTAURANT"));
-        verifier.verify(R.raw.v21_multiple_entry, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
+                .addExpectedNodeWithOrder("TEL", "17", new TypeSet("X-NEC-BOY"))
+                .addExpectedNodeWithOrder("TEL", "18", new TypeSet("X-NEC-FRIEND"))
+                .addExpectedNodeWithOrder("TEL", "19", new TypeSet("X-NEC-PHS"))
+                .addExpectedNodeWithOrder("TEL", "20", new TypeSet("X-NEC-RESTAURANT"));
     }
 
-    public void testV21MultipleEntryCase() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testV21MultipleEntryCase() {
+        mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
+                R.raw.v21_multiple_entry);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033")
                 .put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033")
@@ -954,7 +906,7 @@
                 .put(Phone.TYPE, Phone.TYPE_FAX_HOME)
                 .put(Phone.NUMBER, "12");
 
-        elem = verifier.addImportVerifierElem();
+        elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034")
                 .put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034")
@@ -976,7 +928,7 @@
                 .put(Phone.LABEL, "NEC-GIRL")
                 .put(Phone.NUMBER, "16");
 
-        elem = verifier.addImportVerifierElem();
+        elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035")
                 .put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035")
@@ -998,61 +950,55 @@
                 .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                 .put(Phone.LABEL, "NEC-RESTAURANT")
                 .put(Phone.NUMBER, "20");
-        verifier.verify(R.raw.v21_multiple_entry, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
     }
 
-    public void testIgnoreAgentV21_Parse() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
+    public void testIgnoreAgentV21_Parse() {
+        mVerifier.initForImportTest(V21, R.raw.v21_winmo_65);
         ContentValues contentValuesForValue = new ContentValues();
         contentValuesForValue.put("VALUE", "DATE");
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "2.1")
-                .addNodeWithOrder("N", Arrays.asList("Example", "", "", "", ""))
-                .addNodeWithOrder("FN", "Example")
-                .addNodeWithOrder("ANNIVERSARY", "20091010", contentValuesForValue)
-                .addNodeWithOrder("AGENT", "")
-                .addNodeWithOrder("X-CLASS", "PUBLIC")
-                .addNodeWithOrder("X-REDUCTION", "")
-                .addNodeWithOrder("X-NO", "");
-
-        // Only scan mode lets vCard parser accepts invalid AGENT lines like above.
-        verifier.verify(R.raw.v21_winmo_65, V21, new VCardParser_V21());
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "2.1")
+                .addExpectedNodeWithOrder("N", Arrays.asList("Example", "", "", "", ""))
+                .addExpectedNodeWithOrder("FN", "Example")
+                .addExpectedNodeWithOrder("ANNIVERSARY", "20091010", contentValuesForValue)
+                .addExpectedNodeWithOrder("AGENT", "")
+                .addExpectedNodeWithOrder("X-CLASS", "PUBLIC")
+                .addExpectedNodeWithOrder("X-REDUCTION", "")
+                .addExpectedNodeWithOrder("X-NO", "");
     }
 
-    public void testIgnoreAgentV21()  throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testIgnoreAgentV21() {
+        mVerifier.initForImportTest(V21, R.raw.v21_winmo_65);
+        ContentValuesVerifier verifier = new ContentValuesVerifier();
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "Example")
                 .put(StructuredName.DISPLAY_NAME, "Example");
-        verifier.verify(R.raw.v21_winmo_65, V21, new VCardParser_V21());
     }
 
-    public void testTolerateInvalidCommentLikeLineV21() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testTolerateInvalidCommentLikeLineV21() {
+        mVerifier.initForImportTest(V21, R.raw.v21_invalid_comment_line);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.GIVEN_NAME, "Conference Call")
                 .put(StructuredName.DISPLAY_NAME, "Conference Call");
         elem.addExpected(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "This is an (sharp ->#<- sharp) example. "
                         + "This message must NOT be ignored.");
-        verifier.verify(R.raw.v21_invalid_comment_line, V21);
     }
 
-    public void testPagerV30_Parse() throws IOException, VCardException {
-        PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithOrder("VERSION", "3.0")
-                .addNodeWithOrder("N", Arrays.asList("F", "G", "M", "", ""))
-                .addNodeWithOrder("TEL", "6101231234@pagersample.com",
+    public void testPagerV30_Parse() {
+        mVerifier.initForImportTest(V30, R.raw.v30_comma_separated);
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNodeWithOrder("VERSION", "3.0")
+                .addExpectedNodeWithOrder("N", Arrays.asList("F", "G", "M", "", ""))
+                .addExpectedNodeWithOrder("TEL", "6101231234@pagersample.com",
                         new TypeSet("WORK", "MSG", "PAGER"));
-        verifier.verify(R.raw.v30_comma_separated, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8);
     }
 
-    public void testPagerV30() throws IOException, VCardException {
-        ImportVerifier verifier = new ImportVerifier();
-        ImportVerifierElem elem = verifier.addImportVerifierElem();
+    public void testPagerV30() {
+        mVerifier.initForImportTest(V30, R.raw.v30_comma_separated);
+        ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
         elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "F")
                 .put(StructuredName.MIDDLE_NAME, "M")
@@ -1061,6 +1007,5 @@
         elem.addExpected(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.TYPE, Phone.TYPE_PAGER)
                 .put(Phone.NUMBER, "6101231234@pagersample.com");
-        verifier.verify(R.raw.v30_comma_separated, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8);
     }
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java
index 5ce0dee..967c22d 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardJapanizationTests.java
@@ -24,16 +24,14 @@
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 
 import com.android.unit_tests.vcard.PropertyNodesVerifierElem.TypeSet;
-import com.android.unit_tests.vcard.VCardTestsBase.ContactEntry;
-import com.android.unit_tests.vcard.VCardTestsBase.VCardVerifier;
 
 import java.util.Arrays;
 
 public class VCardJapanizationTests extends VCardTestsBase {
     private void testNameUtf8Common(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u3075\u308B\u3069")
                 .put(StructuredName.GIVEN_NAME, "\u3091\u308A\u304B")
                 .put(StructuredName.MIDDLE_NAME, "B")
@@ -41,14 +39,13 @@
                 .put(StructuredName.SUFFIX, "Ph.D");
         ContentValues contentValues =
             (VCardConfig.isV30(vcardType) ? null : mContentValuesForQPAndUtf8);
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("FN", "Dr. \u3075\u308B\u3069 B \u3091\u308A\u304B Ph.D",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("FN", "Dr. \u3075\u308B\u3069 B \u3091\u308A\u304B Ph.D",
                         contentValues)
-                .addNodeWithoutOrder("N", "\u3075\u308B\u3069;\u3091\u308A\u304B;B;Dr.;Ph.D",
+                .addExpectedNode("N", "\u3075\u308B\u3069;\u3091\u308A\u304B;B;Dr.;Ph.D",
                         Arrays.asList(
                                 "\u3075\u308B\u3069", "\u3091\u308A\u304B", "B", "Dr.", "Ph.D"),
                                 null, contentValues, null, null);
-        verifier.verify();
     }
 
     public void testNameUtf8V21() {
@@ -60,32 +57,31 @@
     }
 
     public void testNameShiftJis() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_V30_JAPANESE_SJIS);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V30_JAPANESE_SJIS);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u3075\u308B\u3069")
                 .put(StructuredName.GIVEN_NAME, "\u3091\u308A\u304B")
                 .put(StructuredName.MIDDLE_NAME, "B")
                 .put(StructuredName.PREFIX, "Dr.")
                 .put(StructuredName.SUFFIX, "Ph.D");
 
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("FN", "Dr. \u3075\u308B\u3069 B \u3091\u308A\u304B Ph.D",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("FN", "Dr. \u3075\u308B\u3069 B \u3091\u308A\u304B Ph.D",
                         mContentValuesForSJis)
-                .addNodeWithoutOrder("N", "\u3075\u308B\u3069;\u3091\u308A\u304B;B;Dr.;Ph.D",
+                .addExpectedNode("N", "\u3075\u308B\u3069;\u3091\u308A\u304B;B;Dr.;Ph.D",
                         Arrays.asList(
                                 "\u3075\u308B\u3069", "\u3091\u308A\u304B", "B", "Dr.", "Ph.D"),
                                 null, mContentValuesForSJis, null, null);
-        verifier.verify();
     }
 
     /**
      * DoCoMo phones require all name elements should be in "family name" field.
      */
     public void testNameDoCoMo() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.FAMILY_NAME, "\u3075\u308B\u3069")
                 .put(StructuredName.GIVEN_NAME, "\u3091\u308A\u304B")
                 .put(StructuredName.MIDDLE_NAME, "B")
@@ -93,26 +89,25 @@
                 .put(StructuredName.SUFFIX, "Ph.D");
 
         final String fullName = "Dr. \u3075\u308B\u3069 B \u3091\u308A\u304B Ph.D";
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("N", fullName + ";;;;",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("N", fullName + ";;;;",
                         Arrays.asList(fullName, "", "", "", ""),
                         null, mContentValuesForSJis, null, null)
-                .addNodeWithoutOrder("FN", fullName, mContentValuesForSJis)
-                .addNodeWithoutOrder("SOUND", ";;;;", new TypeSet("X-IRMC-N"))
-                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("ADR", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
-                .addNodeWithoutOrder("X-REDUCTION", "")
-                .addNodeWithoutOrder("X-NO", "")
-                .addNodeWithoutOrder("X-DCM-HMN-MODE", "");
-        verifier.verify();
+                .addExpectedNode("FN", fullName, mContentValuesForSJis)
+                .addExpectedNode("SOUND", ";;;;", new TypeSet("X-IRMC-N"))
+                .addExpectedNode("TEL", "", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("ADR", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "");
     }
 
     private void testPhoneticNameCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0")
                 .put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
@@ -122,20 +117,20 @@
                     (VCardConfig.isV30(vcardType) ? mContentValuesForSJis :
                             mContentValuesForQPAndSJis) :
                     (VCardConfig.isV30(vcardType) ? null : mContentValuesForQPAndUtf8));
-        PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElemWithEmptyName();
-        elem.addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "\u3084\u307E\u3060",
+        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
+        elem.addExpectedNode("X-PHONETIC-LAST-NAME", "\u3084\u307E\u3060",
                         contentValues)
-                .addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME",
+                .addExpectedNode("X-PHONETIC-MIDDLE-NAME",
                         "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0",
                         contentValues)
-                .addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "\u305F\u308D\u3046",
+                .addExpectedNode("X-PHONETIC-FIRST-NAME", "\u305F\u308D\u3046",
                         contentValues);
         if (VCardConfig.isV30(vcardType)) {
-            elem.addNodeWithoutOrder("SORT-STRING",
+            elem.addExpectedNode("SORT-STRING",
                     "\u3084\u307E\u3060 \u30DF\u30C9\u30EB\u30CD\u30FC\u30E0 \u305F\u308D\u3046",
                     contentValues);
         }
-        ContentValuesBuilder builder = verifier.addImportVerifier()
+        ContentValuesBuilder builder = mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE);
         builder.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0")
@@ -143,7 +138,6 @@
                 .put(StructuredName.DISPLAY_NAME,
                         "\u3084\u307E\u3060 \u30DF\u30C9\u30EB\u30CD\u30FC\u30E0 " +
                         "\u305F\u308D\u3046");
-        verifier.verify();
     }
 
     public void testPhoneticNameForJapaneseV21Utf8() {
@@ -163,19 +157,19 @@
     }
 
     public void testPhoneticNameForMobileV21_1() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
                 .put(StructuredName.PHONETIC_MIDDLE_NAME, "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0")
                 .put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
 
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("SOUND",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("SOUND",
                         "\uFF94\uFF8F\uFF80\uFF9E \uFF90\uFF84\uFF9E\uFF99\uFF88\uFF70\uFF91 " +
                         "\uFF80\uFF9B\uFF73;;;;",
                         mContentValuesForSJis, new TypeSet("X-IRMC-N"));
-        ContentValuesBuilder builder = verifier.addImportVerifier()
+        ContentValuesBuilder builder = mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE);
         builder.put(StructuredName.PHONETIC_FAMILY_NAME, "\uFF94\uFF8F\uFF80\uFF9E")
                 .put(StructuredName.PHONETIC_MIDDLE_NAME,
@@ -184,31 +178,29 @@
                 .put(StructuredName.DISPLAY_NAME,
                         "\uFF94\uFF8F\uFF80\uFF9E \uFF90\uFF84\uFF9E\uFF99\uFF88\uFF70\uFF91 " +
                         "\uFF80\uFF9B\uFF73");
-        verifier.verify();
     }
 
     public void testPhoneticNameForMobileV21_2() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredName.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                 .put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
                 .put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
 
-        verifier.addPropertyNodesVerifierElem()
-                .addNodeWithoutOrder("SOUND", "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73;;;;",
+        mVerifier.addPropertyNodesVerifierElem()
+                .addExpectedNode("SOUND", "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73;;;;",
                                 mContentValuesForSJis, new TypeSet("X-IRMC-N"));
-        ContentValuesBuilder builder = verifier.addImportVerifier()
+        ContentValuesBuilder builder = mVerifier.addContentValuesVerifierElem()
                 .addExpected(StructuredName.CONTENT_ITEM_TYPE);
         builder.put(StructuredName.PHONETIC_FAMILY_NAME, "\uFF94\uFF8F\uFF80\uFF9E")
                 .put(StructuredName.PHONETIC_GIVEN_NAME, "\uFF80\uFF9B\uFF73")
                 .put(StructuredName.DISPLAY_NAME, "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73");
-        verifier.verify();
     }
 
     private void testPostalAddressWithJapaneseCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POBOX, "\u79C1\u66F8\u7BB107")
                 .put(StructuredPostal.STREET, "\u96DB\u898B\u6CA2\u6751")
                 .put(StructuredPostal.CITY, "\u9E7F\u9AA8\u5E02")
@@ -227,14 +219,14 @@
                 (VCardConfig.isV30(vcardType) ? mContentValuesForUtf8 :
                     mContentValuesForQPAndUtf8));
 
-        PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElemWithEmptyName();
+        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
         // LABEL must be ignored in vCard 2.1. As for vCard 3.0, the current behavior is
         // same as that in vCard 3.0, which can be changed in the future.
-        elem.addNodeWithoutOrder("ADR", Arrays.asList("\u79C1\u66F8\u7BB107",
+        elem.addExpectedNode("ADR", Arrays.asList("\u79C1\u66F8\u7BB107",
                 "", "\u96DB\u898B\u6CA2\u6751", "\u9E7F\u9AA8\u5E02", "\u00D7\u00D7\u770C",
                 "494-1313", "\u65E5\u672C"),
                 contentValues);
-        verifier.addImportVerifier().addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.addContentValuesVerifierElem().addExpected(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POBOX, "\u79C1\u66F8\u7BB107")
                 .put(StructuredPostal.STREET, "\u96DB\u898B\u6CA2\u6751")
                 .put(StructuredPostal.CITY, "\u9E7F\u9AA8\u5E02")
@@ -245,7 +237,6 @@
                         "\u65E5\u672C 494-1313 \u00D7\u00D7\u770C \u9E7F\u9AA8\u5E02 " +
                         "\u96DB\u898B\u6CA2\u6751 " + "\u79C1\u66F8\u7BB107")
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME);
-        verifier.verify();
     }
     public void testPostalAddresswithJapaneseV21() {
         testPostalAddressWithJapaneseCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
@@ -256,164 +247,175 @@
      * Prefered type must (should?) be: HOME > WORK > OTHER > CUSTOM
      */
     public void testPostalAdrressForDoCoMo_1() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
                 .put(StructuredPostal.POBOX, "1");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
                 .put(StructuredPostal.POBOX, "2");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME)
                 .put(StructuredPostal.POBOX, "3");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
                 .put(StructuredPostal.LABEL, "custom")
                 .put(StructuredPostal.POBOX, "4");
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
-                .addNodeWithoutOrder("X-REDUCTION", "")
-                .addNodeWithoutOrder("X-NO", "")
-                .addNodeWithoutOrder("X-DCM-HMN-MODE", "")
-                .addNodeWithoutOrder("ADR",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "")
+                .addExpectedNode("ADR",
                         Arrays.asList("3", "", "", "", "", "", ""), new TypeSet("HOME"));
-        verifier.verify();
     }
 
     public void testPostalAdrressForDoCoMo_2() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
                 .put(StructuredPostal.POBOX, "1");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
                 .put(StructuredPostal.POBOX, "2");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
                 .put(StructuredPostal.LABEL, "custom")
                 .put(StructuredPostal.POBOX, "3");
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
-                .addNodeWithoutOrder("X-REDUCTION", "")
-                .addNodeWithoutOrder("X-NO", "")
-                .addNodeWithoutOrder("X-DCM-HMN-MODE", "")
-                .addNodeWithoutOrder("ADR",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "")
+                .addExpectedNode("ADR",
                         Arrays.asList("2", "", "", "", "", "", ""), new TypeSet("WORK"));
-        verifier.verify();
     }
 
     public void testPostalAdrressForDoCoMo_3() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
                 .put(StructuredPostal.LABEL, "custom1")
                 .put(StructuredPostal.POBOX, "1");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
                 .put(StructuredPostal.POBOX, "2");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
                 .put(StructuredPostal.LABEL, "custom2")
                 .put(StructuredPostal.POBOX, "3");
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
-                .addNodeWithoutOrder("X-REDUCTION", "")
-                .addNodeWithoutOrder("X-NO", "")
-                .addNodeWithoutOrder("X-DCM-HMN-MODE", "")
-                .addNodeWithoutOrder("ADR", Arrays.asList("2", "", "", "", "", "", ""));
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "")
+                .addExpectedNode("ADR", Arrays.asList("2", "", "", "", "", "", ""));
     }
 
     /**
      * Verifies the vCard exporter tolerates null TYPE.
      */
     public void testPostalAdrressForDoCoMo_4() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POBOX, "1");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
                 .put(StructuredPostal.POBOX, "2");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME)
                 .put(StructuredPostal.POBOX, "3");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
                 .put(StructuredPostal.POBOX, "4");
-        entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
+        entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                 .put(StructuredPostal.POBOX, "5");
 
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
-                .addNodeWithoutOrder("X-REDUCTION", "")
-                .addNodeWithoutOrder("X-NO", "")
-                .addNodeWithoutOrder("X-DCM-HMN-MODE", "")
-                .addNodeWithoutOrder("ADR",
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "")
+                .addExpectedNode("ADR",
                         Arrays.asList("3", "", "", "", "", "", ""), new TypeSet("HOME"));
-        verifier.verify();
     }
 
     private void testJapanesePhoneNumberCommon(int vcardType) {
-        VCardVerifier verifier = new VCardVerifier(vcardType);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(vcardType);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "0312341234")
                 .put(Phone.TYPE, Phone.TYPE_HOME);
-        entry.buildData(Phone.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                 .put(Phone.NUMBER, "09012341234")
                 .put(Phone.TYPE, Phone.TYPE_MOBILE);
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "03-1234-1234", new TypeSet("HOME"))
-                .addNodeWithoutOrder("TEL", "090-1234-1234", new TypeSet("WORK"));
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "03-1234-1234", new TypeSet("HOME"))
+                .addExpectedNode("TEL", "090-1234-1234", new TypeSet("CELL"));
     }
 
     public void testJapanesePhoneNumberV21_1() {
         testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
     }
 
-    public void testJapanesePhoneNumberDoCoMo() {
-        testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_DOCOMO);
-    }
-
     public void testJapanesePhoneNumberV30() {
         testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8);
     }
 
+    public void testJapanesePhoneNumberDoCoMo() {
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
+                .put(Phone.NUMBER, "0312341234")
+                .put(Phone.TYPE, Phone.TYPE_HOME);
+        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
+                .put(Phone.NUMBER, "09012341234")
+                .put(Phone.TYPE, Phone.TYPE_MOBILE);
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "")
+                .addExpectedNode("ADR", "", new TypeSet("HOME"))
+                .addExpectedNode("TEL", "03-1234-1234", new TypeSet("HOME"))
+                .addExpectedNode("TEL", "090-1234-1234", new TypeSet("CELL"));
+    }
+
     public void testNoteDoCoMo() {
-        VCardVerifier verifier = new VCardVerifier(VCardConfig.VCARD_TYPE_DOCOMO);
-        ContactEntry entry = verifier.addInputEntry();
-        entry.buildData(Note.CONTENT_ITEM_TYPE)
+        mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+        ContactEntry entry = mVerifier.addInputEntry();
+        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "note1");
-        entry.buildData(Note.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "note2");
-        entry.buildData(Note.CONTENT_ITEM_TYPE)
+        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                 .put(Note.NOTE, "note3");
 
         // More than one note fields must be aggregated into one note.
-        verifier.addPropertyNodesVerifierElemWithEmptyName()
-                .addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("X-CLASS", "PUBLIC")
-                .addNodeWithoutOrder("X-REDUCTION", "")
-                .addNodeWithoutOrder("X-NO", "")
-                .addNodeWithoutOrder("X-DCM-HMN-MODE", "")
-                .addNodeWithoutOrder("ADR", "", new TypeSet("HOME"))
-                .addNodeWithoutOrder("NOTE", "note1\nnote2\nnote3", mContentValuesForQP);
-        verifier.verify();
+        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+                .addExpectedNode("TEL", "", new TypeSet("HOME"))
+                .addExpectedNode("EMAIL", "", new TypeSet("HOME"))
+                .addExpectedNode("X-CLASS", "PUBLIC")
+                .addExpectedNode("X-REDUCTION", "")
+                .addExpectedNode("X-NO", "")
+                .addExpectedNode("X-DCM-HMN-MODE", "")
+                .addExpectedNode("ADR", "", new TypeSet("HOME"))
+                .addExpectedNode("NOTE", "note1\nnote2\nnote3", mContentValuesForQP);
     }
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java
index 7b5f216..c13d060 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestsBase.java
@@ -19,10 +19,7 @@
 import android.content.ContentProvider;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
-import android.content.ContentResolver;
 import android.content.ContentValues;
-import android.content.Context;
-import android.content.Entity;
 import android.content.EntityIterator;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
@@ -33,57 +30,11 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.pim.vcard.VCardEntry;
-import android.pim.vcard.VCardEntryCommitter;
-import android.pim.vcard.VCardEntryHandler;
-import android.pim.vcard.VCardInterpreter;
-import android.pim.vcard.VCardInterpreterCollection;
-import android.pim.vcard.VCardComposer;
 import android.pim.vcard.VCardConfig;
-import android.pim.vcard.VCardEntryConstructor;
-import android.pim.vcard.VCardParser;
-import android.pim.vcard.VCardParser_V21;
-import android.pim.vcard.VCardParser_V30;
-import android.pim.vcard.exception.VCardException;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Event;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-import android.provider.ContactsContract.CommonDataKinds.Note;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.CommonDataKinds.Relation;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Website;
 import android.test.AndroidTestCase;
-import android.test.mock.MockContentResolver;
-import android.test.mock.MockContext;
-import android.test.mock.MockCursor;
-import android.text.TextUtils;
+import android.util.Log;
 
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.Map.Entry;
 
 /**
  * Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
@@ -164,18 +115,6 @@
     }
 }
 
-class CustomMockContext extends MockContext {
-    final ContentResolver mResolver;
-    public CustomMockContext(ContentResolver resolver) {
-        mResolver = resolver;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        return mResolver;
-    }
-}
-
 /**
  * BaseClass for vCard unit tests with utility classes.
  * Please do not add each unit test here.
@@ -193,6 +132,9 @@
     protected final ContentValues mContentValuesForBase64V21;
     protected final ContentValues mContentValuesForBase64V30;
 
+    protected VCardVerifier mVerifier;
+    private boolean mSkipVerification;
+
     public VCardTestsBase() {
         super();
         mContentValuesForQP = new ContentValues();
@@ -213,788 +155,24 @@
         mContentValuesForBase64V30.put("ENCODING", "b");
     }
 
-    public class ImportTestResolver extends MockContentResolver {
-        ImportTestProvider mProvider = new ImportTestProvider();
-        @Override
-        public ContentProviderResult[] applyBatch(String authority,
-                ArrayList<ContentProviderOperation> operations) {
-            equalsString(authority, RawContacts.CONTENT_URI.toString());
-            return mProvider.applyBatch(operations);
-        }
-
-        public void addExpectedContentValues(ContentValues expectedContentValues) {
-            mProvider.addExpectedContentValues(expectedContentValues);
-        }
-
-        public void verify() {
-            mProvider.verify();
-        }
+    @Override
+    public void testAndroidTestCaseSetupProperly() {
+        super.testAndroidTestCaseSetupProperly();
+        mSkipVerification = true;
     }
 
-    private static final Set<String> sKnownMimeTypeSet =
-        new HashSet<String>(Arrays.asList(StructuredName.CONTENT_ITEM_TYPE,
-                Nickname.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE,
-                Email.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE,
-                Im.CONTENT_ITEM_TYPE, Organization.CONTENT_ITEM_TYPE,
-                Event.CONTENT_ITEM_TYPE, Photo.CONTENT_ITEM_TYPE,
-                Note.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE,
-                Relation.CONTENT_ITEM_TYPE, Event.CONTENT_ITEM_TYPE,
-                GroupMembership.CONTENT_ITEM_TYPE));
-
-    public class ImportTestProvider extends MockContentProvider {
-        final Map<String, Collection<ContentValues>> mMimeTypeToExpectedContentValues;
-
-        public ImportTestProvider() {
-            mMimeTypeToExpectedContentValues =
-                new HashMap<String, Collection<ContentValues>>();
-            for (String acceptanbleMimeType : sKnownMimeTypeSet) {
-                // Do not use HashSet since the current implementation changes the content of
-                // ContentValues after the insertion, which make the result of hashCode()
-                // changes...
-                mMimeTypeToExpectedContentValues.put(
-                        acceptanbleMimeType, new ArrayList<ContentValues>());
-            }
-        }
-
-        public void addExpectedContentValues(ContentValues expectedContentValues) {
-            final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE);
-            if (!sKnownMimeTypeSet.contains(mimeType)) {
-                fail(String.format(
-                        "Unknow MimeType %s in the test code. Test code should be broken.",
-                        mimeType));
-            }
-
-            final Collection<ContentValues> contentValuesCollection =
-                    mMimeTypeToExpectedContentValues.get(mimeType);
-            contentValuesCollection.add(expectedContentValues);
-        }
-
-        @Override
-        public ContentProviderResult[] applyBatch(
-                ArrayList<ContentProviderOperation> operations) {
-            if (operations == null) {
-                fail("There is no operation.");
-            }
-
-            final int size = operations.size();
-            ContentProviderResult[] fakeResultArray = new ContentProviderResult[size];
-            for (int i = 0; i < size; i++) {
-                Uri uri = Uri.withAppendedPath(RawContacts.CONTENT_URI, String.valueOf(i));
-                fakeResultArray[i] = new ContentProviderResult(uri);
-            }
-
-            for (int i = 0; i < size; i++) {
-                ContentProviderOperation operation = operations.get(i);
-                ContentValues contentValues = operation.resolveValueBackReferences(
-                        fakeResultArray, i);
-            }
-            for (int i = 0; i < size; i++) {
-                ContentProviderOperation operation = operations.get(i);
-                ContentValues actualContentValues = operation.resolveValueBackReferences(
-                        fakeResultArray, i);
-                final Uri uri = operation.getUri();
-                if (uri.equals(RawContacts.CONTENT_URI)) {
-                    assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME));
-                    assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE));
-                } else if (uri.equals(Data.CONTENT_URI)) {
-                    final String mimeType = actualContentValues.getAsString(Data.MIMETYPE);
-                    if (!sKnownMimeTypeSet.contains(mimeType)) {
-                        fail(String.format(
-                                "Unknown MimeType %s. Probably added after developing this test",
-                                mimeType));
-                    }
-                    // Remove data meaningless in this unit tests.
-                    // Specifically, Data.DATA1 - DATA7 are set to null or empty String
-                    // regardless of the input, but it may change depending on how
-                    // resolver-related code handles it.
-                    // Here, we ignore these implementation-dependent specs and
-                    // just check whether vCard importer correctly inserts rellevent data.
-                    Set<String> keyToBeRemoved = new HashSet<String>();
-                    for (Entry<String, Object> entry : actualContentValues.valueSet()) {
-                        Object value = entry.getValue();
-                        if (value == null || TextUtils.isEmpty(value.toString())) {
-                            keyToBeRemoved.add(entry.getKey());
-                        }
-                    }
-                    for (String key: keyToBeRemoved) {
-                        actualContentValues.remove(key);
-                    }
-                    /* for testing
-                    Log.d("@@@",
-                            String.format("MimeType: %s, data: %s",
-                                    mimeType, actualContentValues.toString())); */
-                    // Remove RAW_CONTACT_ID entry just for safety, since we do not care
-                    // how resolver-related code handles the entry in this unit test,
-                    if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) {
-                        actualContentValues.remove(Data.RAW_CONTACT_ID);
-                    }
-                    final Collection<ContentValues> contentValuesCollection =
-                        mMimeTypeToExpectedContentValues.get(mimeType);
-                    if (contentValuesCollection.isEmpty()) {
-                        fail("ContentValues for MimeType " + mimeType
-                                + " is not expected at all (" + actualContentValues + ")");
-                    }
-                    boolean checked = false;
-                    for (ContentValues expectedContentValues : contentValuesCollection) {
-                        /*for testing
-                        Log.d("@@@", "expected: "
-                                + convertToEasilyReadableString(expectedContentValues));
-                        Log.d("@@@", "actual  : "
-                                + convertToEasilyReadableString(actualContentValues));*/
-                        if (equalsForContentValues(expectedContentValues,
-                                actualContentValues)) {
-                            assertTrue(contentValuesCollection.remove(expectedContentValues));
-                            checked = true;
-                            break;
-                        }
-                    }
-                    if (!checked) {
-                        final StringBuilder builder = new StringBuilder();
-                        builder.append("Unexpected: ");
-                        builder.append(convertToEasilyReadableString(actualContentValues));
-                        builder.append("\nExpected: ");
-                        for (ContentValues expectedContentValues : contentValuesCollection) {
-                            builder.append(convertToEasilyReadableString(expectedContentValues));
-                        }
-                        fail(builder.toString());
-                    }
-                } else {
-                    fail("Unexpected Uri has come: " + uri);
-                }
-            }  // for (int i = 0; i < size; i++) {
-            return null;
-        }
-
-        public void verify() {
-            StringBuilder builder = new StringBuilder();
-            for (Collection<ContentValues> contentValuesCollection :
-                    mMimeTypeToExpectedContentValues.values()) {
-                for (ContentValues expectedContentValues: contentValuesCollection) {
-                    builder.append(convertToEasilyReadableString(expectedContentValues));
-                    builder.append("\n");
-                }
-            }
-            if (builder.length() > 0) {
-                final String failMsg =
-                    "There is(are) remaining expected ContentValues instance(s): \n"
-                        + builder.toString();
-                fail(failMsg);
-            }
-        }
+    @Override
+    public void setUp() throws Exception{
+        super.setUp();
+        mVerifier = new VCardVerifier(this);
+        mSkipVerification = false;
     }
 
-    class ImportVerifierElem {
-        private final ImportTestResolver mResolver;
-        private final VCardEntryHandler mHandler;
-
-        public ImportVerifierElem() {
-            mResolver = new ImportTestResolver();
-            mHandler = new VCardEntryCommitter(mResolver);
-        }
-
-        public ContentValuesBuilder addExpected(String mimeType) {
-            ContentValues contentValues = new ContentValues();
-            contentValues.put(Data.MIMETYPE, mimeType);
-            mResolver.addExpectedContentValues(contentValues);
-            return new ContentValuesBuilder(contentValues);
-        }
-
-        public void verify(int resId, int vCardType)
-                throws IOException, VCardException {
-            verify(getContext().getResources().openRawResource(resId), vCardType);
-        }
-
-        public void verify(InputStream is, int vCardType) throws IOException, VCardException {
-            final VCardParser vCardParser;
-            if (VCardConfig.isV30(vCardType)) {
-                vCardParser = new VCardParser_V30(true);  // use StrictParsing
-            } else {
-                vCardParser = new VCardParser_V21();
-            }
-            VCardEntryConstructor builder =
-                    new VCardEntryConstructor(null, null, false, vCardType, null);
-            builder.addEntryHandler(mHandler);
-            try {
-                vCardParser.parse(is, builder);
-            } finally {
-                if (is != null) {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-            verifyResolver();
-        }
-
-        public void verifyResolver() {
-            mResolver.verify();
-        }
-
-        public void onParsingStart() {
-            mHandler.onStart();
-        }
-
-        public void onEntryCreated(VCardEntry entry) {
-            mHandler.onEntryCreated(entry);
-        }
-
-        public void onParsingEnd() {
-            mHandler.onEnd();
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (!mSkipVerification) {
+            mVerifier.verify();
         }
     }
-
-    class ImportVerifier implements VCardEntryHandler {
-        private List<ImportVerifierElem> mImportVerifierElemList =
-            new ArrayList<ImportVerifierElem>();
-        private int mIndex;
-
-        public ImportVerifierElem addImportVerifierElem() {
-            ImportVerifierElem importVerifier = new ImportVerifierElem();
-            mImportVerifierElemList.add(importVerifier);
-            return importVerifier;
-        }
-
-        public void verify(int resId, int vCardType) throws IOException, VCardException {
-            verify(getContext().getResources().openRawResource(resId), vCardType);
-        }
-
-        public void verify(int resId, int vCardType, final VCardParser vCardParser)
-                throws IOException, VCardException {
-            verify(getContext().getResources().openRawResource(resId), vCardType, vCardParser);
-        }
-
-        public void verify(InputStream is, int vCardType) throws IOException, VCardException {
-            final VCardParser vCardParser;
-            if (VCardConfig.isV30(vCardType)) {
-                vCardParser = new VCardParser_V30(true);  // use StrictParsing
-            } else {
-                vCardParser = new VCardParser_V21();
-            }
-            verify(is, vCardType, vCardParser);
-        }
-
-        public void verify(InputStream is, int vCardType, final VCardParser vCardParser)
-                throws IOException, VCardException {
-            VCardEntryConstructor builder =
-                new VCardEntryConstructor(null, null, false, vCardType, null);
-            builder.addEntryHandler(this);
-            try {
-                vCardParser.parse(is, builder);
-            } finally {
-                if (is != null) {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-        }
-
-        public void onStart() {
-            for (ImportVerifierElem elem : mImportVerifierElemList) {
-                elem.onParsingStart();
-            }
-        }
-
-        public void onEntryCreated(VCardEntry entry) {
-            assertTrue(mIndex < mImportVerifierElemList.size());
-            mImportVerifierElemList.get(mIndex).onEntryCreated(entry);
-            mIndex++;
-        }
-
-        public void onEnd() {
-            for (ImportVerifierElem elem : mImportVerifierElemList) {
-                elem.onParsingEnd();
-                elem.verifyResolver();
-            }
-        }
-    }
-
-    public class ExportTestResolver extends MockContentResolver {
-        ExportTestProvider mProvider = new ExportTestProvider();
-        public ExportTestResolver() {
-            addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
-            addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
-        }
-
-        public ContactEntry buildContactEntry() {
-            return mProvider.buildInputEntry();
-        }
-    }
-
-    public static class MockEntityIterator implements EntityIterator {
-        List<Entity> mEntityList;
-        Iterator<Entity> mIterator;
-
-        public MockEntityIterator(List<ContentValues> contentValuesList) {
-            mEntityList = new ArrayList<Entity>();
-            Entity entity = new Entity(new ContentValues());
-            for (ContentValues contentValues : contentValuesList) {
-                    entity.addSubValue(Data.CONTENT_URI, contentValues);
-            }
-            mEntityList.add(entity);
-            mIterator = mEntityList.iterator();
-        }
-
-        public boolean hasNext() {
-            return mIterator.hasNext();
-        }
-
-        public Entity next() {
-            return mIterator.next();
-        }
-
-        public void reset() {
-            mIterator = mEntityList.iterator();
-        }
-
-        public void close() {
-        }
-    }
-
-    /**
-     * Represents one contact, which should contain multiple ContentValues like
-     * StructuredName, Email, etc.
-     */
-    static class ContactEntry {
-        private final List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
-
-        public ContentValuesBuilder buildData(String mimeType) {
-            ContentValues contentValues = new ContentValues();
-            contentValues.put(Data.MIMETYPE, mimeType);
-            mContentValuesList.add(contentValues);
-            return new ContentValuesBuilder(contentValues);
-        }
-
-        public List<ContentValues> getList() {
-            return mContentValuesList;
-        }
-    }
-
-    class ExportTestProvider extends MockContentProvider {
-        ArrayList<ContactEntry> mContactEntryList = new ArrayList<ContactEntry>();
-
-        public ContactEntry buildInputEntry() {
-            ContactEntry contactEntry = new ContactEntry();
-            mContactEntryList.add(contactEntry);
-            return contactEntry;
-        }
-
-        @Override
-        public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
-                String sortOrder) {
-            assertTrue(uri != null);
-            assertTrue(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
-            final String authority = uri.getAuthority();
-            assertTrue(RawContacts.CONTENT_URI.getAuthority().equals(authority));
-            assertTrue((Data.CONTACT_ID + "=?").equals(selection));
-            assertEquals(1, selectionArgs.length);
-            int id = Integer.parseInt(selectionArgs[0]);
-            assertTrue(id >= 0 && id < mContactEntryList.size());
-
-            return new MockEntityIterator(mContactEntryList.get(id).getList());
-        }
-
-        @Override
-        public Cursor query(Uri uri, String[] projection,
-                String selection, String[] selectionArgs, String sortOrder) {
-            assertTrue(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
-            // In this test, following arguments are not supported.
-            assertNull(selection);
-            assertNull(selectionArgs);
-            assertNull(sortOrder);
-
-            return new MockCursor() {
-                int mCurrentPosition = -1;
-
-                @Override
-                public int getCount() {
-                    return mContactEntryList.size();
-                }
-
-                @Override
-                public boolean moveToFirst() {
-                    mCurrentPosition = 0;
-                    return true;
-                }
-
-                @Override
-                public boolean moveToNext() {
-                    if (mCurrentPosition < mContactEntryList.size()) {
-                        mCurrentPosition++;
-                        return true;
-                    } else {
-                        return false;
-                    }
-                }
-
-                @Override
-                public boolean isBeforeFirst() {
-                    return mCurrentPosition < 0;
-                }
-
-                @Override
-                public boolean isAfterLast() {
-                    return mCurrentPosition >= mContactEntryList.size();
-                }
-
-                @Override
-                public int getColumnIndex(String columnName) {
-                    assertEquals(Contacts._ID, columnName);
-                    return 0;
-                }
-
-                @Override
-                public int getInt(int columnIndex) {
-                    assertEquals(0, columnIndex);
-                    assertTrue(mCurrentPosition >= 0
-                            && mCurrentPosition < mContactEntryList.size());
-                    return mCurrentPosition;
-                }
-
-                @Override
-                public String getString(int columnIndex) {
-                    return String.valueOf(getInt(columnIndex));
-                }
-
-                @Override
-                public void close() {
-                }
-            };
-        }
-    }
-
-    class LineVerifierElem {
-        private final List<String> mExpectedLineList = new ArrayList<String>();
-        private final boolean mIsV30;
-
-        public LineVerifierElem(boolean isV30) {
-            mIsV30 = isV30;
-        }
-
-        public LineVerifierElem addExpected(final String line) {
-            if (!TextUtils.isEmpty(line)) {
-                mExpectedLineList.add(line);
-            }
-            return this;
-        }
-
-        public void verify(final String vcard) {
-            final String[] lineArray = vcard.split("\\r?\\n");
-            final int length = lineArray.length;
-            final TestCase testCase = VCardTestsBase.this;
-            boolean beginExists = false;
-            boolean endExists = false;
-            boolean versionExists = false;
-
-            for (int i = 0; i < length; i++) {
-                final String line = lineArray[i];
-                if (TextUtils.isEmpty(line)) {
-                    continue;
-                }
-
-                if ("BEGIN:VCARD".equalsIgnoreCase(line)) {
-                    if (beginExists) {
-                        testCase.fail("Multiple \"BEGIN:VCARD\" line found");
-                    } else {
-                        beginExists = true;
-                        continue;
-                    }
-                } else if ("END:VCARD".equalsIgnoreCase(line)) {
-                    if (endExists) {
-                        testCase.fail("Multiple \"END:VCARD\" line found");
-                    } else {
-                        endExists = true;
-                        continue;
-                    }
-                } else if (
-                        (mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equalsIgnoreCase(line)) {
-                    if (versionExists) {
-                        testCase.fail("Multiple VERSION line + found");
-                    } else {
-                        versionExists = true;
-                        continue;
-                    }
-                }
-
-                if (!beginExists) {
-                    testCase.fail(
-                            "Property other than BEGIN came before BEGIN property: " + line);
-                } else if (endExists) {
-                    testCase.fail("Property other than END came after END property: " + line);
-                }
-
-                final int index = mExpectedLineList.indexOf(line);
-                if (index >= 0) {
-                    mExpectedLineList.remove(index);
-                } else {
-                    testCase.fail("Unexpected line: " + line);
-                }
-            }
-
-            if (!mExpectedLineList.isEmpty()) {
-                StringBuffer buffer = new StringBuffer();
-                for (String expectedLine : mExpectedLineList) {
-                    buffer.append(expectedLine);
-                    buffer.append("\n");
-                }
-
-                testCase.fail("Expected line(s) not found:" + buffer.toString());
-            }
-        }
-    }
-
-    class LineVerifier implements VCardComposer.OneEntryHandler {
-        private final ArrayList<LineVerifierElem> mLineVerifierElemList;
-        private final boolean mIsV30;
-        private int index;
-
-        public LineVerifier(final boolean isV30) {
-            mLineVerifierElemList = new ArrayList<LineVerifierElem>();
-            mIsV30 = isV30;
-        }
-
-        public LineVerifierElem addLineVerifierElem() {
-            LineVerifierElem lineVerifier = new LineVerifierElem(mIsV30);
-            mLineVerifierElemList.add(lineVerifier);
-            return lineVerifier;
-        }
-
-        public void verify(String vcard) {
-            if (index >= mLineVerifierElemList.size()) {
-                VCardTestsBase.this.fail("Insufficient number of LineVerifier (" + index + ")");
-            }
-
-            LineVerifierElem lineVerifier = mLineVerifierElemList.get(index);
-            lineVerifier.verify(vcard);
-
-            index++;
-        }
-
-        public boolean onEntryCreated(String vcard) {
-            verify(vcard);
-            return true;
-        }
-
-        public boolean onInit(Context context) {
-            return true;
-        }
-
-        public void onTerminate() {
-        }
-    }
-
-    class VCardVerifier {
-        private class VCardVerifierInternal implements VCardComposer.OneEntryHandler {
-            public boolean onInit(Context context) {
-                return true;
-            }
-            public boolean onEntryCreated(String vcard) {
-                verifyOneVCard(vcard);
-                return true;
-            }
-            public void onTerminate() {
-            }
-        }
-
-        private final VCardVerifierInternal mVCardVerifierInternal;
-        private final int mVCardType;
-        private final boolean mIsV30;
-        private final boolean mIsDoCoMo;
-
-        private ExportTestResolver mInputResolver;
-
-        // To allow duplication, use list instead of set.
-        // When null, we don't need to do the verification.
-        private PropertyNodesVerifier mPropertyNodesVerifier;
-        private LineVerifier mLineVerificationHandler;
-        private ImportVerifier mImportVerifier;
-
-        public VCardVerifier(int vcardType) {
-            mVCardVerifierInternal = new VCardVerifierInternal();
-            mIsV30 = VCardConfig.isV30(vcardType);
-            mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
-            mVCardType = vcardType;
-
-            mInputResolver = null;
-        }
-
-        public ContactEntry addInputEntry() {
-            if (mInputResolver == null) {
-                mInputResolver = new ExportTestResolver();
-            }
-            return mInputResolver.buildContactEntry();
-        }
-
-        public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
-            if (mPropertyNodesVerifier == null) {
-                mPropertyNodesVerifier = new PropertyNodesVerifier(VCardTestsBase.this);
-            }
-            PropertyNodesVerifierElem elem =
-                    mPropertyNodesVerifier.addPropertyNodesVerifierElem();
-            elem.addNodeWithOrder("VERSION", (mIsV30 ? "3.0" : "2.1"));
-
-            return elem;
-        }
-
-        public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithEmptyName() {
-            PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem();
-            if (mIsV30) {
-                elem.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
-            } else if (mIsDoCoMo) {
-                elem.addNodeWithOrder("N", "");
-            }
-            return elem;
-        }
-
-        public LineVerifierElem addLineVerifier() {
-            if (mLineVerificationHandler == null) {
-                mLineVerificationHandler = new LineVerifier(mIsV30);
-            }
-            return mLineVerificationHandler.addLineVerifierElem();
-        }
-
-        public ImportVerifierElem addImportVerifier() {
-            if (mImportVerifier == null) {
-                mImportVerifier = new ImportVerifier();
-            }
-
-            return mImportVerifier.addImportVerifierElem();
-        }
-
-        private void verifyOneVCard(final String vcard) {
-            // Log.d("@@@", vcard);
-            final VCardInterpreter builder;
-            if (mImportVerifier != null) {
-                final VNodeBuilder vnodeBuilder = mPropertyNodesVerifier;
-                final VCardEntryConstructor vcardDataBuilder =
-                        new VCardEntryConstructor(mVCardType);
-                vcardDataBuilder.addEntryHandler(mImportVerifier);
-                if (mPropertyNodesVerifier != null) {
-                    builder = new VCardInterpreterCollection(Arrays.asList(
-                            mPropertyNodesVerifier, vcardDataBuilder));
-                } else {
-                    builder = vnodeBuilder;
-                }
-            } else {
-                if (mPropertyNodesVerifier != null) {
-                    builder = mPropertyNodesVerifier;
-                } else {
-                    return;
-                }
-            }
-
-            final VCardParser parser =
-                    (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
-            final TestCase testCase = VCardTestsBase.this;
-
-            InputStream is = null;
-            try {
-                String charset =
-                    (VCardConfig.usesShiftJis(mVCardType) ? "SHIFT_JIS" : "UTF-8");
-                is = new ByteArrayInputStream(vcard.getBytes(charset));
-                testCase.assertEquals(true, parser.parse(is, null, builder));
-            } catch (IOException e) {
-                testCase.fail("Unexpected IOException: " + e.getMessage());
-            } catch (VCardException e) {
-                testCase.fail("Unexpected VCardException: " + e.getMessage());
-            } finally {
-                if (is != null) {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-        }
-
-        public void verify() {
-            VCardComposer composer =
-                    new VCardComposer(new CustomMockContext(mInputResolver), mVCardType);
-            composer.addHandler(mLineVerificationHandler);
-            composer.addHandler(mVCardVerifierInternal);
-            if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
-                fail("init() failed. Reason: " + composer.getErrorReason());
-            }
-            assertFalse(composer.isAfterLast());
-            try {
-                while (!composer.isAfterLast()) {
-                    assertTrue(composer.createOneEntry());
-                }
-            } finally {
-                composer.terminate();
-            }
-        }
-    }
-
-    /**
-     * Utility method to print ContentValues whose content is printed with sorted keys.
-     */
-    private static String convertToEasilyReadableString(ContentValues contentValues) {
-        if (contentValues == null) {
-            return "null";
-        }
-        String mimeTypeValue = "";
-        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
-        for (Entry<String, Object> entry : contentValues.valueSet()) {
-            final String key = entry.getKey();
-            final Object value = entry.getValue();
-            final String valueString = (value != null ? value.toString() : null);
-            if (Data.MIMETYPE.equals(key)) {
-                mimeTypeValue = valueString;
-            } else {
-                assertNotNull(key);
-                sortedMap.put(key, valueString);
-            }
-        }
-        StringBuilder builder = new StringBuilder();
-        builder.append(Data.MIMETYPE);
-        builder.append('=');
-        builder.append(mimeTypeValue);
-        for (Entry<String, String> entry : sortedMap.entrySet()) {
-            final String key = entry.getKey();
-            final String value = entry.getValue();
-            builder.append(' ');
-            builder.append(key);
-            builder.append("=\"");
-            builder.append(value);
-            builder.append('"');
-        }
-        return builder.toString();
-    }
-
-    private static boolean equalsForContentValues(
-            ContentValues expected, ContentValues actual) {
-        if (expected == actual) {
-            return true;
-        } else if (expected == null || actual == null || expected.size() != actual.size()) {
-            return false;
-        }
-
-        for (Entry<String, Object> entry : expected.valueSet()) {
-            final String key = entry.getKey();
-            final Object value = entry.getValue();
-            if (!actual.containsKey(key)) {
-                return false;
-            }
-            if (value instanceof byte[]) {
-                Object actualValue = actual.get(key);
-                if (!Arrays.equals((byte[])value, (byte[])actualValue)) {
-                    return false;
-                }
-            } else if (!value.equals(actual.get(key))) {
-                    return false;
-            }
-        }
-        return true;
-    }
-
-    private static boolean equalsString(String a, String b) {
-        if (a == null || a.length() == 0) {
-            return b == null || b.length() == 0;
-        } else {
-            return a.equals(b);
-        }
-    }
-}
\ No newline at end of file
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardVerifier.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardVerifier.java
new file mode 100644
index 0000000..e5cdf63
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardVerifier.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.unit_tests.vcard;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.pim.vcard.VCardComposer;
+import android.pim.vcard.VCardConfig;
+import android.pim.vcard.VCardEntryConstructor;
+import android.pim.vcard.VCardInterpreter;
+import android.pim.vcard.VCardInterpreterCollection;
+import android.pim.vcard.VCardParser;
+import android.pim.vcard.VCardParser_V21;
+import android.pim.vcard.VCardParser_V30;
+import android.pim.vcard.exception.VCardException;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+/* package */ class CustomMockContext extends MockContext {
+    final ContentResolver mResolver;
+    public CustomMockContext(ContentResolver resolver) {
+        mResolver = resolver;
+    }
+
+    @Override
+    public ContentResolver getContentResolver() {
+        return mResolver;
+    }
+}
+
+/* package */ class VCardVerifier {
+    private class VCardVerifierInternal implements VCardComposer.OneEntryHandler {
+        public boolean onInit(Context context) {
+            return true;
+        }
+        public boolean onEntryCreated(String vcard) {
+            verifyOneVCard(vcard);
+            return true;
+        }
+        public void onTerminate() {
+        }
+    }
+
+    private final AndroidTestCase mTestCase;
+    private final VCardVerifierInternal mVCardVerifierInternal;
+    private int mVCardType;
+    private boolean mIsV30;
+    private boolean mIsDoCoMo;
+
+    // Only one of them must be non-empty.
+    private ExportTestResolver mExportTestResolver;
+    private InputStream mInputStream;
+
+    // To allow duplication, use list instead of set.
+    // When null, we don't need to do the verification.
+    private PropertyNodesVerifier mPropertyNodesVerifier;
+    private LineVerifier mLineVerifier;
+    private ContentValuesVerifier mContentValuesVerifier;
+    private boolean mInitialized;
+    private boolean mVerified = false;
+
+    public VCardVerifier(AndroidTestCase androidTestCase) {
+        mTestCase = androidTestCase;
+        mVCardVerifierInternal = new VCardVerifierInternal();
+        mExportTestResolver = null;
+        mInputStream = null;
+        mInitialized = false;
+        mVerified = false;
+    }
+
+    public void initForExportTest(int vcardType) {
+        if (mInitialized) {
+            mTestCase.fail("Already initialized");
+        }
+        mExportTestResolver = new ExportTestResolver(mTestCase);
+        mVCardType = vcardType;
+        mIsV30 = VCardConfig.isV30(vcardType);
+        mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
+        mInitialized = true;
+    }
+
+    public void initForImportTest(int vcardType, int resId) {
+        if (mInitialized) {
+            mTestCase.fail("Already initialized");
+        }
+        mVCardType = vcardType;
+        mIsV30 = VCardConfig.isV30(vcardType);
+        mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
+        setInputResourceId(resId);
+        mInitialized = true;
+    }
+
+    private void setInputResourceId(int resId) {
+        InputStream inputStream = mTestCase.getContext().getResources().openRawResource(resId);
+        if (inputStream == null) {
+            mTestCase.fail("Wrong resId: " + resId);
+        }
+        setInputStream(inputStream);
+    }
+
+    private void setInputStream(InputStream inputStream) {
+        if (mExportTestResolver != null) {
+            mTestCase.fail("addInputEntry() is called.");
+        } else if (mInputStream != null) {
+            mTestCase.fail("InputStream is already set");
+        }
+        mInputStream = inputStream;
+    }
+
+    public ContactEntry addInputEntry() {
+        if (!mInitialized) {
+            mTestCase.fail("Not initialized");
+        }
+        if (mInputStream != null) {
+            mTestCase.fail("setInputStream is called");
+        }
+        return mExportTestResolver.addInputContactEntry();
+    }
+
+    public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
+        if (!mInitialized) {
+            mTestCase.fail("Not initialized");
+        }
+        if (mPropertyNodesVerifier == null) {
+            mPropertyNodesVerifier = new PropertyNodesVerifier(mTestCase);
+        }
+        PropertyNodesVerifierElem elem =
+                mPropertyNodesVerifier.addPropertyNodesVerifierElem();
+        elem.addExpectedNodeWithOrder("VERSION", (mIsV30 ? "3.0" : "2.1"));
+
+        return elem;
+    }
+
+    public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithEmptyName() {
+        if (!mInitialized) {
+            mTestCase.fail("Not initialized");
+        }
+        PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem();
+        if (mIsV30) {
+            elem.addExpectedNodeWithOrder("N", "").addExpectedNodeWithOrder("FN", "");
+        } else if (mIsDoCoMo) {
+            elem.addExpectedNodeWithOrder("N", "");
+        }
+        return elem;
+    }
+
+    public LineVerifierElem addLineVerifierElem() {
+        if (!mInitialized) {
+            mTestCase.fail("Not initialized");
+        }
+        if (mLineVerifier == null) {
+            mLineVerifier = new LineVerifier(mTestCase, mVCardType);
+        }
+        return mLineVerifier.addLineVerifierElem();
+    }
+
+    public ContentValuesVerifierElem addContentValuesVerifierElem() {
+        if (!mInitialized) {
+            mTestCase.fail("Not initialized");
+        }
+        if (mContentValuesVerifier == null) {
+            mContentValuesVerifier = new ContentValuesVerifier();
+        }
+
+        return mContentValuesVerifier.addElem(mTestCase);
+    }
+
+    private void verifyOneVCard(final String vcard) {
+        // Log.d("@@@", vcard);
+        final VCardInterpreter builder;
+        if (mContentValuesVerifier != null) {
+            final VNodeBuilder vnodeBuilder = mPropertyNodesVerifier;
+            final VCardEntryConstructor vcardDataBuilder =
+                    new VCardEntryConstructor(mVCardType);
+            vcardDataBuilder.addEntryHandler(mContentValuesVerifier);
+            if (mPropertyNodesVerifier != null) {
+                builder = new VCardInterpreterCollection(Arrays.asList(
+                        mPropertyNodesVerifier, vcardDataBuilder));
+            } else {
+                builder = vnodeBuilder;
+            }
+        } else {
+            if (mPropertyNodesVerifier != null) {
+                builder = mPropertyNodesVerifier;
+            } else {
+                return;
+            }
+        }
+
+        final VCardParser parser =
+                (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
+        InputStream is = null;
+        try {
+            String charset =
+                (VCardConfig.usesShiftJis(mVCardType) ? "SHIFT_JIS" : "UTF-8");
+            is = new ByteArrayInputStream(vcard.getBytes(charset));
+            mTestCase.assertEquals(true, parser.parse(is, null, builder));
+        } catch (IOException e) {
+            mTestCase.fail("Unexpected IOException: " + e.getMessage());
+        } catch (VCardException e) {
+            mTestCase.fail("Unexpected VCardException: " + e.getMessage());
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    public void verify() {
+        if (!mInitialized) {
+            mTestCase.fail("Not initialized.");
+        }
+        if (mVerified) {
+            mTestCase.fail("verify() was called twice.");
+        }
+        if (mInputStream != null) {
+            try {
+                verifyForImportTest();
+            } catch (IOException e) {
+                mTestCase.fail("IOException was thrown: " + e.getMessage());
+            } catch (VCardException e) {
+                mTestCase.fail("VCardException was thrown: " + e.getMessage());
+            }
+        } else if (mExportTestResolver != null){
+            verifyForExportTest();
+        } else {
+            mTestCase.fail("No input is determined");
+        }
+        mVerified = true;
+    }
+
+    private void verifyForImportTest() throws IOException, VCardException {
+        if (mLineVerifier != null) {
+            mTestCase.fail("Not supported now.");
+        }
+        if (mContentValuesVerifier != null) {
+            mContentValuesVerifier.verify(mInputStream, mVCardType);
+        }
+    }
+
+    private void verifyForExportTest() {
+        VCardComposer composer =
+            new VCardComposer(new CustomMockContext(mExportTestResolver), mVCardType);
+        composer.addHandler(mLineVerifier);
+        composer.addHandler(mVCardVerifierInternal);
+        if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
+            mTestCase.fail("init() failed. Reason: " + composer.getErrorReason());
+        }
+        mTestCase.assertFalse(composer.isAfterLast());
+        try {
+            while (!composer.isAfterLast()) {
+                mTestCase.assertTrue(composer.createOneEntry());
+            }
+        } finally {
+            composer.terminate();
+        }
+    }
+}