diff --git a/src/com/android/contacts/ImportVCardActivity.java b/src/com/android/contacts/ImportVCardActivity.java
index 09c4980..e021457 100644
--- a/src/com/android/contacts/ImportVCardActivity.java
+++ b/src/com/android/contacts/ImportVCardActivity.java
@@ -21,23 +21,30 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.DialogInterface.OnCancelListener;
 import android.content.DialogInterface.OnClickListener;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.TextUtils;
 import android.text.style.RelativeSizeSpan;
 import android.util.Log;
 
+import com.android.contacts.ImportVCardService.RequestParameter;
 import com.android.contacts.model.Sources;
 import com.android.contacts.util.AccountSelectionUtil;
 import com.android.vcard.VCardEntryCounter;
@@ -48,14 +55,12 @@
 import com.android.vcard.VCardSourceDetector;
 import com.android.vcard.exception.VCardException;
 import com.android.vcard.exception.VCardNestedException;
-import com.android.vcard.exception.VCardNotSupportedException;
 import com.android.vcard.exception.VCardVersionException;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.nio.channels.Channel;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
@@ -88,15 +93,19 @@
     /* package */ static final String VCARD_URI_ARRAY = "vcard_uri";
     /* package */ static final String ESTIMATED_VCARD_TYPE_ARRAY = "estimated_vcard_type";
     /* package */ static final String ESTIMATED_CHARSET_ARRAY = "estimated_charset";
-    /* package */ static final String USE_V30_ARRAY = "use_v30";
+    /* package */ static final String VCARD_VERSION_ARRAY = "vcard_version";
     /* package */ static final String ENTRY_COUNT_ARRAY = "entry_count";
 
+    /* package */ final static int VCARD_VERSION_AUTO_DETECT = 0;
+    /* package */ final static int VCARD_VERSION_V21 = 1;
+    /* package */ final static int VCARD_VERSION_V30 = 2;
+
     // Run on the UI thread. Must not be null except after onDestroy().
     private Handler mHandler = new Handler();
 
     private AccountSelectionUtil.AccountSelectedListener mAccountSelectionListener;
-    private String mAccountName;
-    private String mAccountType;
+
+    private Account mAccount;
 
     private String mAction;
     private Uri mUri;
@@ -111,6 +120,19 @@
 
     private String mErrorMessage;
 
+    private Messenger mMessenger;
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mMessenger = new Messenger(service);
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            mMessenger = null;
+            finish();
+        }
+    };
+
     private static class VCardFile {
         private final String mName;
         private final String mCanonicalPath;
@@ -180,24 +202,9 @@
         private VCardParser mVCardParser;
         private final Uri[] mSourceUris;
 
-        // Not using Uri[] since we throw this object to Service via Intent.
-        private final String[] mDestUriStrings;
-
-        private final int[] mEstimatedVCardTypes;
-        private final String[] mEstimatedCharsets;
-        private final boolean[] mShouldUseV30;
-        private final int[] mEntryCounts;
-
         public VCardCacheThread(final Uri[] sourceUris) {
             mSourceUris = sourceUris;
             final int length = sourceUris.length;
-
-            mDestUriStrings = new String[length];
-            mEstimatedVCardTypes = new int[length];
-            mEstimatedCharsets = new String[length];
-            mShouldUseV30 = new boolean[length];
-            mEntryCounts = new int[length];
-
             final Context context = ImportVCardActivity.this;
             PowerManager powerManager = (PowerManager)context.getSystemService(
                     Context.POWER_SERVICE);
@@ -219,34 +226,48 @@
             final ContentResolver resolver = context.getContentResolver();
             String errorMessage = null;
             mWakeLock.acquire();
-
+            boolean successful = false;
             try {
                 clearOldCache();
+                bindService(new Intent(ImportVCardActivity.this, 
+                        ImportVCardService.class), mConnection, Context.BIND_AUTO_CREATE);
 
+                final int length = mSourceUris.length;
+                // Uris given from caller applications may not be opened twice: consider when
+                // it is not from local storage (e.g. "file:///...") but from some special
+                // provider (e.g. "content://...").
+                // Thus we have to once copy the content of Uri into local storage, and read
+                // it after it. This copy is also useful fro the view of stability of the import,
+                // as we are able to restore the procedure even when it is aborted during it.
+                // Imagine the case the importer encountered memory-low situation when
+                // reading 10th entry of a vCard file.
+                //
                 // We may be able to read content of each vCard file during copying them
                 // to local storage, but currently vCard code does not allow us to do so.
-                //
-                // Note that Uris given from caller applications may not be opened twice,
-                // so we have to use local data after this copy instead of relying on
-                // the original source Uris.
-                copyVCardToLocal();
-                if (mCanceled) {
-                    return;
+                for (int i = 0; i < length; i++) {
+                    final Uri sourceUri = mSourceUris[i];
+                    final Uri localDataUri = copyToLocal(sourceUri, i);
+                    if (mCanceled) {
+                        break;
+                    }
+                    if (localDataUri == null) {
+                        Log.w(LOG_TAG, "destUri is null");
+                        break;
+                    }
+                    final RequestParameter parameter = constructRequestParameter(localDataUri);
+                    if (mCanceled) {
+                        return;
+                    }
+                    mMessenger.send(Message.obtain(null,
+                            ImportVCardService.IMPORT_REQUEST,
+                            parameter));
+
                 }
-                Log.d("@@@", "Caching done. Count the number of vCard entries.");
-                if (!collectVCardMetaInfo()) {
-                    Log.e(LOG_TAG, "Failed to collect vCard meta information");
-                    runOnUIThread(new DialogDisplayer(
-                            getString(R.string.fail_reason_failed_to_collect_vcard_meta_info)));
-                    return;
-                }
-                if (mCanceled) {
-                    return;
-                }
-                for (int i = 0; i < mEntryCounts.length; i++) {
-                    Log.d("@@@", String.format("length for %s: %d",
-                            mDestUriStrings[i], mEntryCounts[i]));
-                }
+
+                successful = true;
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "RemoteException is thrown when trying to import vCard");
+                runOnUIThread(new DialogDisplayer(getString(R.string.fail_reason_unknown)));
             } catch (OutOfMemoryError e) {
                 Log.e(LOG_TAG, "OutOfMemoryError");
                 // We should take care of this case since Android devices may have
@@ -255,149 +276,54 @@
                 runOnUIThread(new DialogDisplayer(
                         getString(R.string.fail_reason_io_error) +
                         ": " + e.getLocalizedMessage()));
-                return;
             } catch (IOException e) {
                 Log.e(LOG_TAG, e.getMessage());
                 runOnUIThread(new DialogDisplayer(
                         getString(R.string.fail_reason_io_error) +
                         ": " + e.getLocalizedMessage()));
-                return;
             } finally {
-
                 mWakeLock.release();
                 mProgressDialogForCacheVCard.dismiss();
             }
 
-            // TODO(dmiyakawa): do we need runOnUIThread?
-            final Intent intent = new Intent(
-                    ImportVCardActivity.this, ImportVCardService.class);
-            intent.putExtra(VCARD_URI_ARRAY, mDestUriStrings);
-            intent.putExtra(SelectAccountActivity.ACCOUNT_NAME, mAccountName);
-            intent.putExtra(SelectAccountActivity.ACCOUNT_TYPE, mAccountType);
-            intent.putExtra(ESTIMATED_VCARD_TYPE_ARRAY, mEstimatedVCardTypes);
-            intent.putExtra(ESTIMATED_CHARSET_ARRAY, mEstimatedCharsets);
-            intent.putExtra(USE_V30_ARRAY, mShouldUseV30);
-            intent.putExtra(ENTRY_COUNT_ARRAY, mEntryCounts);
-            startService(intent);
-            finish();
-        }
-
-
-        private boolean collectVCardMetaInfo() {
-            final ContentResolver resolver =
-                    ImportVCardActivity.this.getContentResolver();
-            final int length = mDestUriStrings.length;
-            try {
-                for (int i = 0; i < length; i++) {
-                    if (mCanceled) {
-                        return false;
-                    }
-                    final Uri uri = Uri.parse(mDestUriStrings[i]);
-                    boolean shouldUseV30 = false;
-                    InputStream is;
-                    VCardEntryCounter counter;
-                    VCardSourceDetector detector;
-                    VCardInterpreterCollection interpreter;
-
-                    is = resolver.openInputStream(uri);
-                    mVCardParser = new VCardParser_V21();
-                    try {
-                        counter = new VCardEntryCounter();
-                        detector = new VCardSourceDetector();
-                        interpreter =
-                                new VCardInterpreterCollection(
-                                        Arrays.asList(counter, detector));
-                        mVCardParser.parse(is, interpreter);
-                    } catch (VCardVersionException e1) {
-                        try {
-                            is.close();
-                        } catch (IOException e) {
-                        }
-
-                        shouldUseV30 = true;
-                        is = resolver.openInputStream(uri);
-                        mVCardParser = new VCardParser_V30();
-                        try {
-                            counter = new VCardEntryCounter();
-                            detector = new VCardSourceDetector();
-                            interpreter =
-                                    new VCardInterpreterCollection(
-                                            Arrays.asList(counter, detector));
-                            mVCardParser.parse(is, interpreter);
-                        } catch (VCardVersionException e2) {
-                            throw new VCardException("vCard with unspported version.");
-                        }
-                    } finally {
-                        if (is != null) {
-                            try {
-                                is.close();
-                            } catch (IOException e) {
-                            }
-                        }
-                    }
-
-                    mEstimatedVCardTypes[i] = detector.getEstimatedType();
-                    mEstimatedCharsets[i] = detector.getEstimatedCharset();
-                    mShouldUseV30[i] = shouldUseV30;
-                    mEntryCounts[i] = counter.getCount();
-                }
-            } catch (IOException e) {
-                Log.e(LOG_TAG, "IOException was emitted: " + e.getMessage());
-                return false;
-            } catch (VCardNestedException e) {
-                Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive).");
-            } catch (VCardNotSupportedException e) {
-                return false;
-            } catch (VCardException e) {
-                return false;
+            if (successful) {
+                finish();
+            } else {
+                // finish() should be called via DialogDisplayer().
             }
-            return true;
         }
 
-        private void copyVCardToLocal() throws IOException {
+        /**
+         * Copy the content of sourceUri to local storage. 
+         */
+        private Uri copyToLocal(final Uri sourceUri, int i) throws IOException {
             final Context context = ImportVCardActivity.this;
             final ContentResolver resolver = context.getContentResolver();
             ReadableByteChannel inputChannel = null;
             WritableByteChannel outputChannel = null;
+            Uri destUri;
             try {
-                int length = mSourceUris.length;
-                for (int i = 0; i < length; i++) {
-                    if (mCanceled) {
-                        Log.d(LOG_TAG, "Canceled during import");
-                        break;
-                    }
-                    // XXX: better way to copy stream?
+                // XXX: better way to copy stream?
+                {
                     inputChannel = Channels.newChannel(resolver.openInputStream(mSourceUris[i]));
                     final String filename = CACHE_FILE_PREFIX + i + ".vcf";
-                    mDestUriStrings[i] =
-                            context.getFileStreamPath(filename).toURI().toString();
-                    Log.d("@@@", "temporary file: " + filename + ", dest: " + mDestUriStrings[i]);
+                    destUri = Uri.parse(context.getFileStreamPath(filename).toURI().toString());
                     outputChannel =
                             context.openFileOutput(filename, Context.MODE_PRIVATE).getChannel();
-                    {
-                        final ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
-                        while (inputChannel.read(buffer) != -1) {
-                            if (mCanceled) {
-                                Log.d(LOG_TAG, "Canceled during caching " + mSourceUris[i]);
-                                break;
-                            }
-                            buffer.flip();
-                            outputChannel.write(buffer);
-                            buffer.compact();
+                    final ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
+                    while (inputChannel.read(buffer) != -1) {
+                        if (mCanceled) {
+                            Log.d(LOG_TAG, "Canceled during caching " + mSourceUris[i]);
+                            return null;
                         }
                         buffer.flip();
-                        while (buffer.hasRemaining()) {
-                            outputChannel.write(buffer);
-                        }
+                        outputChannel.write(buffer);
+                        buffer.compact();
                     }
-
-                    // Avoid double close() in the "finally" block bellow.
-                    Channel tmp = inputChannel;
-                    inputChannel = null;
-                    tmp.close();
-                    tmp = outputChannel;
-                    outputChannel = null;
-                    tmp.close();
+                    buffer.flip();
+                    while (buffer.hasRemaining()) {
+                        outputChannel.write(buffer);
+                    }
                 }
             } finally {
                 if (inputChannel != null) {
@@ -415,6 +341,76 @@
                     }
                 }
             }
+            return destUri;
+        }
+
+        /**
+         * Reads the Uri once (or twice) and constructs {@link RequestParameter} from
+         * its content.
+         */
+        private RequestParameter constructRequestParameter(final Uri uri) {
+            final ContentResolver resolver =
+                    ImportVCardActivity.this.getContentResolver();
+            VCardEntryCounter counter = null;
+            VCardSourceDetector detector = null;
+            VCardInterpreterCollection interpreter = null;
+            int vcardVersion = VCARD_VERSION_V21;
+            try {
+                boolean shouldUseV30 = false;
+                InputStream is;
+
+                is = resolver.openInputStream(uri);
+                mVCardParser = new VCardParser_V21();
+                try {
+                    counter = new VCardEntryCounter();
+                    detector = new VCardSourceDetector();
+                    interpreter =
+                            new VCardInterpreterCollection(
+                                    Arrays.asList(counter, detector));
+                    mVCardParser.parse(is, interpreter);
+                } catch (VCardVersionException e1) {
+                    try {
+                        is.close();
+                    } catch (IOException e) {
+                    }
+
+                    shouldUseV30 = true;
+                    is = resolver.openInputStream(uri);
+                    mVCardParser = new VCardParser_V30();
+                    try {
+                        counter = new VCardEntryCounter();
+                        detector = new VCardSourceDetector();
+                        interpreter =
+                                new VCardInterpreterCollection(
+                                        Arrays.asList(counter, detector));
+                        mVCardParser.parse(is, interpreter);
+                    } catch (VCardVersionException e2) {
+                        throw new VCardException("vCard with unspported version.");
+                    }
+                } finally {
+                    if (is != null) {
+                        try {
+                            is.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                }
+
+                vcardVersion = shouldUseV30 ? VCARD_VERSION_V30 : VCARD_VERSION_V21;
+            } catch (VCardNestedException e) {
+                Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive).");
+                // Go through without returning null.
+            } catch (VCardException e) {
+                Log.e(LOG_TAG, e.getMessage());
+                return null;
+            } catch (IOException e) {
+                Log.e(LOG_TAG, "IOException was emitted: " + e.getMessage());
+                return null;
+            }
+            return new RequestParameter(mAccount, uri,
+                    detector.getEstimatedType(),
+                    detector.getEstimatedCharset(),
+                    vcardVersion, counter.getCount());
         }
 
         /**
@@ -666,10 +662,8 @@
         importVCard(uriStrings);
     }
 
-    private void importVCard(final String uriString) {
-        String[] uriStrings = new String[1];
-        uriStrings[0] = uriString;
-        importVCard(uriStrings);
+    private void importVCard(final Uri uri) {
+        importVCard(new Uri[] {uri});
     }
 
     private void importVCard(final String[] uriStrings) {
@@ -678,6 +672,10 @@
         for (int i = 0; i < length; i++) {
             uris[i] = Uri.parse(uriStrings[i]);
         }
+        importVCard(uris);
+    }
+
+    private void importVCard(final Uri[] uris) {
         runOnUIThread(new Runnable() {
             public void run() {
                 mVCardCacheThread = new VCardCacheThread(uris);
@@ -745,33 +743,34 @@
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
 
+        String accountName = null;
+        String accountType = null;
         final Intent intent = getIntent();
         if (intent != null) {
-            mAccountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
-            mAccountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
+            accountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
+            accountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
             mAction = intent.getAction();
             mUri = intent.getData();
         } else {
             Log.e(LOG_TAG, "intent does not exist");
         }
 
-        // The caller may not know account information at all, so we show the UI instead.
-        if (TextUtils.isEmpty(mAccountName) || TextUtils.isEmpty(mAccountType)) {
+        if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
+            mAccount = new Account(accountName, accountType);
+        } else {
             final Sources sources = Sources.getInstance(this);
             final List<Account> accountList = sources.getAccounts(true);
             if (accountList.size() == 0) {
-                mAccountName = null;
-                mAccountType = null;
+                mAccount = null;
             } else if (accountList.size() == 1) {
-                final Account account = accountList.get(0);
-                mAccountName = account.name;
-                mAccountType = account.type;
+                mAccount = accountList.get(0);
             } else {
                 startActivityForResult(new Intent(this, SelectAccountActivity.class),
                         SELECT_ACCOUNT);
                 return;
             }
         }
+
         startImport(mAction, mUri);
     }
 
@@ -779,8 +778,9 @@
     public void onActivityResult(int requestCode, int resultCode, Intent intent) {
         if (requestCode == SELECT_ACCOUNT) {
             if (resultCode == RESULT_OK) {
-                mAccountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
-                mAccountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
+                mAccount = new Account(
+                        intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME),
+                        intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE));
                 startImport(mAction, mUri);
             } else {
                 if (resultCode != RESULT_CANCELED) {
@@ -795,7 +795,7 @@
         Log.d(LOG_TAG, "action = " + action + " ; path = " + uri);
 
         if (uri != null) {
-            importVCard(uri.toString());
+            importVCard(uri);
         } else {
             doScanExternalStorageAndImportVCard();
         }
diff --git a/src/com/android/contacts/ImportVCardService.java b/src/com/android/contacts/ImportVCardService.java
index 293255d..f940761 100644
--- a/src/com/android/contacts/ImportVCardService.java
+++ b/src/com/android/contacts/ImportVCardService.java
@@ -23,24 +23,22 @@
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
 import android.provider.ContactsContract.RawContacts;
-import android.text.TextUtils;
 import android.util.Log;
 import android.widget.RemoteViews;
 import android.widget.Toast;
 
-import com.android.vcard.VCardConfig;
 import com.android.vcard.VCardEntry;
 import com.android.vcard.VCardEntryCommitter;
 import com.android.vcard.VCardEntryConstructor;
-import com.android.vcard.VCardEntryCounter;
 import com.android.vcard.VCardEntryHandler;
 import com.android.vcard.VCardInterpreter;
-import com.android.vcard.VCardInterpreterCollection;
 import com.android.vcard.VCardParser;
 import com.android.vcard.VCardParser_V21;
 import com.android.vcard.VCardParser_V30;
@@ -53,7 +51,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
@@ -64,11 +61,379 @@
 public class ImportVCardService extends Service {
     private final static String LOG_TAG = "ImportVCardService";
 
-    private class ProgressNotifier implements VCardEntryHandler {
-        private final int mId;
+    /* package */ static final int IMPORT_REQUEST = 1;
 
-        public ProgressNotifier(int id) {
-            mId = id;
+    private static final int MESSAGE_ID = 1000;
+
+    // TODO: Too many static classes. Create separate files for them.
+
+    /**
+     * Class representing one request for reading vCard (as a Uri representation).
+     */
+    /* package */ static class RequestParameter {
+        public final Account account;
+        /**
+         * Note: One Uri does not mean there's only one vCard entry since one Uri
+         * often has multiple vCard entries. 
+         */
+        public final Uri uri;
+        /**
+         * Can be {@link VCardSourceDetector#PARSE_TYPE_UNKNOWN}.
+         */
+        public final int estimatedVCardType;
+        /**
+         * Can be null, meaning no preferable charset is available.
+         */
+        public final String estimatedCharset;
+        /**
+         * Assumes that one Uri contains only one version, while there's a (tiny) possibility
+         * we may have two types in one vCard.
+         * 
+         * e.g.
+         * BEGIN:VCARD
+         * VERSION:2.1
+         * ...
+         * END:VCARD
+         * BEGIN:VCARD
+         * VERSION:3.0
+         * ...
+         * END:VCARD
+         *
+         * We've never seen this kind of a file, but we may have to cope with it in the future.
+         */
+        public final int vcardVersion;
+        public final int entryCount;
+
+        public RequestParameter(Account account,
+                Uri uri, int estimatedType, String estimatedCharset,
+                int vcardVersion, int entryCount) {
+            this.account = account;
+            this.uri = uri;
+            this.estimatedVCardType = estimatedType;
+            this.estimatedCharset = estimatedCharset;
+            this.vcardVersion = vcardVersion;
+            this.entryCount = entryCount;
+        }
+    }
+
+    public class ImportRequestHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case IMPORT_REQUEST:
+                    RequestParameter parameter = (RequestParameter)msg.obj;
+                    Toast.makeText(ImportVCardService.this,
+                            getString(R.string.vcard_importer_start_message),
+                            Toast.LENGTH_LONG).show();
+                    final boolean needThreadStart;
+                    if (mRequestHandler == null || !mRequestHandler.isRunning()) {
+                        mRequestHandler = new RequestHandler();
+                        mRequestHandler.init(ImportVCardService.this);
+                        needThreadStart = true;
+                    } else {
+                        needThreadStart = false;
+                    }
+                    mRequestHandler.addRequest(parameter);
+                    if (needThreadStart) {
+                        mThread = new Thread(new Runnable() {
+                            public void run() {
+                                mRequestHandler.handleRequests();
+                            }
+                        });
+                        mThread.start();
+                    }
+                    break;
+                default:
+                    Log.e(LOG_TAG, "Unknown request type: " + msg.what);
+                    super.hasMessages(msg.what);
+            }
+        }
+    }
+
+    // TODO(dmiyakawa): better design for testing?
+    /* package */ interface CommitterGenerator {
+        public VCardEntryCommitter generate(ContentResolver resolver);
+    }
+    /* package */ static class DefaultCommitterGenerator implements CommitterGenerator {
+        public VCardEntryCommitter generate(ContentResolver resolver) {
+            return new VCardEntryCommitter(resolver);
+        }
+    }
+
+    /**
+     * For testability, we don't inherit Thread here.
+     */
+    private static class RequestHandler {
+        private ImportVCardService mService;
+        private ContentResolver mResolver;
+        private NotificationManager mNotificationManager;
+        private ProgressNotifier mProgressNotifier;
+
+        private final List<Uri> mFailedUris;
+        private final List<Uri> mCreatedUris;
+
+        private VCardParser mVCardParser;
+
+        /* package */ CommitterGenerator mCommitterGenerator = new DefaultCommitterGenerator();
+
+        /**
+         * Meaning a controller of this object requests the operation should be canceled
+         * or not, which implies {@link #mRunning} should be set to false soon, but
+         * it does not meaning cancel request is able to immediately stop this object,
+         * so we have two variables.
+         */
+        private boolean mCanceled;
+        /**
+         * Meaning this object is actually running.
+         */
+        private boolean mRunning = true;
+        private final Queue<RequestParameter> mPendingRequests =
+                new LinkedList<RequestParameter>();
+
+        public RequestHandler() {
+            // We cannot set Service here since Service is not fully ready at this point.
+            // TODO: refactor this class.
+
+            mFailedUris = new ArrayList<Uri>();
+            mCreatedUris = new ArrayList<Uri>();
+            mProgressNotifier = new ProgressNotifier();            
+        }
+
+        public void init(ImportVCardService service) {
+            // TODO: Based on fragile fact. fix this.
+            mService = service;
+            mResolver = service.getContentResolver();
+            mNotificationManager =
+                (NotificationManager)service.getSystemService(Context.NOTIFICATION_SERVICE);
+            mProgressNotifier.init(mService, mNotificationManager);
+        }
+
+        public void handleRequests() {
+            try {
+                while (!mCanceled) {
+                    final RequestParameter parameter;
+                    synchronized (this) {
+                        if (mPendingRequests.size() == 0) {
+                            mRunning = false;
+                            break;
+                        } else {
+                            parameter = mPendingRequests.poll();
+                        }
+                    }  // synchronized (this)
+                    handleOneRequest(parameter);
+                }
+
+                // Currenty we don't have an appropriate way to let users see all entries
+                // imported in this procedure. Instead, we show them entries only when
+                // there's just one created uri.
+                doFinishNotification(mCreatedUris.size() == 1 ? mCreatedUris.get(0) : null);
+            } finally {
+                // TODO: verify this works fine.
+                mRunning = false;  // Just in case.
+                // mService.stopSelf();
+            }
+        }
+
+        /**
+         * Would be run inside syncronized block.
+         */
+        public boolean handleOneRequest(final RequestParameter parameter) {
+            if (mCanceled) {
+                Log.i(LOG_TAG, "Canceled before actually handling parameter ("
+                        + parameter.uri + ")");
+                return false;
+            }
+            final int[] possibleVCardVersions;
+            if (parameter.vcardVersion == ImportVCardActivity.VCARD_VERSION_AUTO_DETECT) {
+                /**
+                 * Note: this code assumes that a given Uri is able to be opened more than once,
+                 * which may not be true in certain conditions. 
+                 */
+                possibleVCardVersions = new int[] {
+                        ImportVCardActivity.VCARD_VERSION_V21,
+                        ImportVCardActivity.VCARD_VERSION_V30
+                };
+            } else {
+                possibleVCardVersions = new int[] {
+                        parameter.vcardVersion
+                };
+            }
+
+            final Uri uri = parameter.uri;
+            final Account account = parameter.account;
+            final int estimatedVCardType = parameter.estimatedVCardType;
+            final String estimatedCharset = parameter.estimatedCharset;
+
+            final VCardEntryConstructor constructor =
+                new VCardEntryConstructor(estimatedVCardType, account, estimatedCharset);
+            final VCardEntryCommitter committer = mCommitterGenerator.generate(mResolver);
+            constructor.addEntryHandler(committer);
+            constructor.addEntryHandler(mProgressNotifier);
+
+            final boolean successful =
+                readOneVCard(uri, estimatedVCardType, estimatedCharset,
+                        constructor, possibleVCardVersions);
+            if (successful) {
+                List<Uri> uris = committer.getCreatedUris();
+                if (uris != null) {
+                    mCreatedUris.addAll(uris);
+                } else {
+                    // Not critical, but suspicious.
+                    Log.w(LOG_TAG,
+                            "Created Uris is null while the creation itself is successful.");
+                }
+            } else {
+                mFailedUris.add(uri);
+            }
+
+            return successful;
+        }
+
+        /*
+        private void doErrorNotification(int id) {
+            final Notification notification = new Notification();
+            notification.icon = android.R.drawable.stat_sys_download_done;
+            final String title = mService.getString(R.string.reading_vcard_failed_title);
+            final PendingIntent intent =
+                    PendingIntent.getActivity(mService, 0, new Intent(), 0);
+            notification.setLatestEventInfo(mService, title, "", intent);
+            mNotificationManager.notify(MESSAGE_ID, notification);
+        }
+        */
+
+        private void doFinishNotification(Uri createdUri) {
+            final Notification notification = new Notification();
+            notification.icon = android.R.drawable.stat_sys_download_done;
+            final String title = mService.getString(R.string.reading_vcard_finished_title);
+
+            final Intent intent;
+            if (createdUri != null) {
+                final long rawContactId = ContentUris.parseId(createdUri);
+                final Uri contactUri = RawContacts.getContactLookupUri(
+                        mResolver, ContentUris.withAppendedId(
+                                RawContacts.CONTENT_URI, rawContactId));
+                intent = new Intent(Intent.ACTION_VIEW, contactUri);
+            } else {
+                intent = null;
+            }
+
+            final PendingIntent pendingIntent =
+                    PendingIntent.getActivity(mService, 0, intent, 0);
+            notification.setLatestEventInfo(mService, title, "", pendingIntent);
+            mNotificationManager.notify(MESSAGE_ID, notification);
+        }
+        
+        private boolean readOneVCard(Uri uri, int vcardType, String charset,
+                VCardInterpreter interpreter,
+                final int[] possibleVCardVersions) {
+            boolean successful = false;
+            final int length = possibleVCardVersions.length;
+            for (int i = 0; i < length; i++) {
+                InputStream is = null;
+                final int vcardVersion = possibleVCardVersions[i]; 
+                try {
+                    if (i > 0 && (interpreter instanceof VCardEntryConstructor)) {
+                        // Let the object clean up internal temporary objects,
+                        ((VCardEntryConstructor) interpreter).clear();
+                    }
+
+                    is = mResolver.openInputStream(uri);
+
+                    // We need synchronized block here,
+                    // since we need to handle mCanceled and mVCardParser at once.
+                    // In the worst case, a user may call cancel() just before creating
+                    // mVCardParser.
+                    synchronized (this) {
+                        mVCardParser = (vcardVersion == ImportVCardActivity.VCARD_VERSION_V30 ?
+                                new VCardParser_V30(vcardType) :
+                                    new VCardParser_V21(vcardType));
+                        if (mCanceled) {
+                            mVCardParser.cancel();
+                        }
+                    }
+                    mVCardParser.parse(is, interpreter);
+
+                    successful = true;
+                    break;
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "IOException was emitted: " + e.getMessage());
+                } catch (VCardNestedException e) {
+                    // This exception should not be thrown here. We should intsead handle it
+                    // in the preprocessing session in ImportVCardActivity, as we don't try
+                    // to detect the type of given vCard here.
+                    //
+                    // TODO: Handle this case appropriately, which should mean we have to have
+                    // code trying to auto-detect the type of given vCard twice (both in
+                    // ImportVCardActivity and ImportVCardService).
+                    Log.e(LOG_TAG, "Nested Exception is found.");
+                } catch (VCardNotSupportedException e) {
+                    Log.e(LOG_TAG, e.getMessage());
+                } catch (VCardVersionException e) {
+                    if (i == length - 1) {
+                        Log.e(LOG_TAG, "Appropriate version for this vCard is not found.");
+                    } else {
+                        // We'll try the other (v30) version.
+                    }
+                } catch (VCardException e) {
+                    Log.e(LOG_TAG, e.getMessage());
+                } finally {
+                    if (is != null) {
+                        try {
+                            is.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                }
+            }
+
+            return successful;
+        }
+
+        public boolean isRunning() {
+            return mRunning;
+        }
+
+        public boolean isCanceled() {
+            return mCanceled;
+        }
+
+        public void cancel() {
+            mCanceled = true;
+            synchronized (this) {
+                if (mVCardParser != null) {
+                    mVCardParser.cancel();
+                }
+            }
+        }
+
+        public synchronized void addRequest(RequestParameter parameter) {
+            if (mRunning) {
+                mProgressNotifier.addTotalCount(parameter.entryCount);
+                mPendingRequests.add(parameter);
+            } else {
+                Log.w(LOG_TAG, "Request came while the service is not running any more.");
+            }
+        }
+
+        public List<Uri> getCreatedUris() {
+            return mCreatedUris;
+        }
+
+        public List<Uri> getFailedUris() {
+            return mFailedUris;
+        }
+    }
+
+    private static class ProgressNotifier implements VCardEntryHandler {
+        private Context mContext;
+        private NotificationManager mNotificationManager;
+
+        private int mCurrentCount;
+        private int mTotalCount;
+
+        public void init(Context context, NotificationManager notificationManager) {
+            mContext = context;
+            mNotificationManager = notificationManager;
         }
 
         public void onStart() {
@@ -80,7 +445,6 @@
                 return;
             }
 
-            final Context context = ImportVCardService.this;
             // We don't use startEntry() since:
             // - We cannot know name there but here.
             // - There's high probability where name comes soon after the beginning of entry, so
@@ -88,10 +452,14 @@
             final String packageName = "com.android.contacts";
             final RemoteViews remoteViews = new RemoteViews(packageName,
                     R.layout.status_bar_ongoing_event_progress_bar);
-            final String title = getString(R.string.reading_vcard_title);
-            final String text = getString(R.string.progress_notifier_message,
+            final String title = mContext.getString(R.string.reading_vcard_title);
+            String totalCountString;
+            synchronized (this) {
+                totalCountString = String.valueOf(mTotalCount); 
+            }
+            final String text = mContext.getString(R.string.progress_notifier_message,
                     String.valueOf(mCurrentCount),
-                    String.valueOf(mTotalCount),
+                    totalCountString,
                     contactStruct.getDisplayName());
 
             // TODO: uploading image does not work correctly. (looks like a static image).
@@ -99,7 +467,7 @@
             remoteViews.setProgressBar(R.id.progress_bar, mTotalCount, mCurrentCount,
                     mTotalCount == -1);
             final String percentage =
-                    getString(R.string.percentage,
+                    mContext.getString(R.string.percentage,
                             String.valueOf(mCurrentCount * 100/mTotalCount));
             remoteViews.setTextViewText(R.id.progress_text, percentage);
             remoteViews.setImageViewResource(R.id.appIcon, android.R.drawable.stat_sys_download);
@@ -110,359 +478,30 @@
             notification.contentView = remoteViews;
 
             notification.contentIntent =
-                    PendingIntent.getActivity(context, 0,
-                            new Intent(context, ContactsListActivity.class), 0);
-            mNotificationManager.notify(mId, notification);
+                    PendingIntent.getActivity(mContext, 0,
+                            new Intent(mContext, ContactsListActivity.class), 0);
+            mNotificationManager.notify(MESSAGE_ID, notification);
+        }
+
+        public synchronized void addTotalCount(int additionalCount) {
+            mTotalCount += additionalCount;
         }
 
         public void onEnd() {
         }
     }
 
-    private class VCardReadThread extends Thread {
-        private final Context mContext;
-        private final ContentResolver mResolver;
-        private VCardParser mVCardParser;
-        private boolean mCanceled;
-        private final List<Uri> mErrorUris;
-        private final List<Uri> mCreatedUris;
-
-        public VCardReadThread() {
-            mContext = ImportVCardService.this;
-            mResolver = mContext.getContentResolver();
-            mErrorUris = new ArrayList<Uri>();
-            mCreatedUris = new ArrayList<Uri>();
-        }
-
-        @Override
-        public void run() {
-            while (!mCanceled) {
-                mErrorUris.clear();
-                mCreatedUris.clear();
-
-                final Account account;
-                final Uri uri;
-                final int estimatedType;
-                final String estimatedCharset;
-                final boolean useV30;
-                final int entryCount;
-                final int id;
-                final boolean needReview;
-                synchronized (mContext) {
-                    if (mPendingInputs.size() == 0) {
-                        mNowRunning = false;
-                        break;
-                    } else {
-                        final PendingInput pendingInput = mPendingInputs.poll();
-                        account = pendingInput.account;
-                        uri = pendingInput.uri;
-                        estimatedType = pendingInput.estimatedType;
-                        estimatedCharset = pendingInput.estimatedCharset;
-                        useV30 = pendingInput.useV30;
-                        entryCount = pendingInput.entryCount;
-                        id = pendingInput.id;
-                    }
-                }
-                runInternal(account, uri, estimatedType, estimatedCharset,
-                        useV30, entryCount, id);
-                doFinishNotification(id, uri);
-            }
-            Log.i(LOG_TAG, "Successfully imported. Total: " + mTotalCount);
-            stopSelf();
-        }
-
-        private void runInternal(Account account,
-                Uri uri, int estimatedType, String estimatedCharset,
-                boolean useV30, int entryCount,
-                int id) {
-            int totalCount = 0;
-            final ArrayList<VCardSourceDetector> detectorList =
-                new ArrayList<VCardSourceDetector>();
-            if (mCanceled) {
-                return;
-            }
-
-            // First scanning is over. Try to import each vCard, which causes side effects.
-            mTotalCount += entryCount;
-            mCurrentCount = 0;
-
-            if (mCanceled) {
-                Log.w(LOG_TAG, "Canceled during importing (with storing data in database)");
-                // TODO: implement cancel correctly.
-                return;
-            }
-
-            final VCardEntryConstructor constructor =
-                    new VCardEntryConstructor(estimatedType, account, estimatedCharset);
-            final VCardEntryCommitter committer = new VCardEntryCommitter(mResolver);
-            constructor.addEntryHandler(committer);
-            constructor.addEntryHandler(new ProgressNotifier(id));
-
-            if (!readOneVCard(uri, estimatedType, estimatedCharset, constructor)) {
-                Log.e(LOG_TAG, "Failed to read \"" + uri.toString() + "\" " +
-                "while first scan was successful.");
-            }
-                final List<Uri> createdUris = committer.getCreatedUris();
-                if (createdUris != null && createdUris.size() > 0) {
-                    mCreatedUris.addAll(createdUris);
-                } else {
-                    Log.w(LOG_TAG, "Created Uris is null (src = " + uri.toString() + "\"");
-                }
-        }
-
-        private boolean readOneVCard(Uri uri, int vcardType, String charset,
-                VCardInterpreter interpreter) {
-            InputStream is;
-            try {
-                // TODO: use vcardType given from detector and stop trying to read the file twice.
-                is = mResolver.openInputStream(uri);
-
-                // We need synchronized since we need to handle mCanceled and mVCardParser
-                // at once. In the worst case, a user may call cancel() just before recreating
-                // mVCardParser.
-                synchronized (this) {
-                    // TODO: ensure this change works fine.
-                    // mVCardParser = new VCardParser_V21(vcardType, charset);
-                    mVCardParser = new VCardParser_V21(vcardType);
-                    if (mCanceled) {
-                        mVCardParser.cancel();
-                    }
-                }
-
-                try {
-                    mVCardParser.parse(is, interpreter);
-                } catch (VCardVersionException e1) {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                    }
-                    if (interpreter instanceof VCardEntryConstructor) {
-                        // Let the object clean up internal temporal objects,
-                        ((VCardEntryConstructor) interpreter).clear();
-                    }
-                    is = mResolver.openInputStream(uri);
-
-                    synchronized (this) {
-                        // mVCardParser = new VCardParser_V30(vcardType, charset);
-                        mVCardParser = new VCardParser_V30(vcardType);
-                        if (mCanceled) {
-                            mVCardParser.cancel();
-                        }
-                    }
-
-                    try {
-                        mVCardParser.parse(is, interpreter);
-                    } catch (VCardVersionException e2) {
-                        throw new VCardException("vCard with unspported version.");
-                    }
-                } finally {
-                    if (is != null) {
-                        try {
-                            is.close();
-                        } catch (IOException e) {
-                        }
-                    }
-                }
-            } catch (IOException e) {
-                Log.e(LOG_TAG, "IOException was emitted: " + e.getMessage());
-                return false;
-            } catch (VCardNestedException e) {
-                // In the first scan, we may (correctly) encounter this exception.
-                // We assume that we were able to detect the type of vCard before
-                // the exception being thrown.
-                //
-                // In the second scan, we may (inappropriately) encounter it.
-                // We silently ignore it, since
-                // - It is really unusual situation.
-                // - We cannot handle it by definition.
-                // - Users cannot either.
-                // - We should not accept unnecessarily complicated vCard, possibly by wrong manner.
-                Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive).");
-            } catch (VCardNotSupportedException e) {
-                return false;
-            } catch (VCardException e) {
-                return false;
-            }
-            return true;
-        }
-
-        private void doErrorNotification(int id) {
-            final Notification notification = new Notification();
-            notification.icon = android.R.drawable.stat_sys_download_done;
-            final String title = mContext.getString(R.string.reading_vcard_failed_title);
-            final PendingIntent intent =
-                    PendingIntent.getActivity(mContext, 0, new Intent(), 0);
-            notification.setLatestEventInfo(mContext, title, "", intent);
-            mNotificationManager.notify(id, notification);
-        }
-
-        private void doFinishNotification(int id, Uri uri) {
-            final Notification notification = new Notification();
-            notification.icon = android.R.drawable.stat_sys_download_done;
-            final String title = mContext.getString(R.string.reading_vcard_finished_title);
-
-            final Intent intent;
-            final long rawContactId = ContentUris.parseId(mCreatedUris.get(0));
-            final Uri contactUri = RawContacts.getContactLookupUri(
-                    getContentResolver(), ContentUris.withAppendedId(
-                            RawContacts.CONTENT_URI, rawContactId));
-            intent = new Intent(Intent.ACTION_VIEW, contactUri);
-
-            final PendingIntent pendingIntent =
-                    PendingIntent.getActivity(mContext, 0, intent, 0);
-            notification.setLatestEventInfo(mContext, title, "", pendingIntent);
-            mNotificationManager.notify(id, notification);
-        }
-
-        // We need synchronized since we need to handle mCanceled and mVCardParser at once.
-        public synchronized void cancel() {
-            mCanceled = true;
-            if (mVCardParser != null) {
-                mVCardParser.cancel();
-            }
-        }
-
-        public void onCancel(DialogInterface dialog) {
-            cancel();
-        }
-    }
-
-    private static class PendingInput {
-        public final Account account;
-        public final Uri uri;
-        public final int estimatedType;
-        public final String estimatedCharset;
-        public final boolean useV30;
-        public final int entryCount;
-        public final int id;
-
-        public PendingInput(Account account,
-                Uri uri, int estimatedType, String estimatedCharset,
-                boolean useV30, int entryCount,
-                int id) {
-            this.account = account;
-            this.uri = uri;
-            this.estimatedType = estimatedType;
-            this.estimatedCharset = estimatedCharset;
-            this.useV30 = useV30;
-            this.entryCount = entryCount;
-            this.id = id;
-        }
-    }
-
-    // The two classes bellow must be called inside the synchronized block, using this
-    // Activity as a Context.
-    private boolean mNowRunning;
-    private final Queue<PendingInput> mPendingInputs = new LinkedList<PendingInput>();
-
-    private NotificationManager mNotificationManager;
-    private Thread mThread;
-    private int mTotalCount;
-    private int mCurrentCount;
-
-    private Uri[] tryGetUris(Intent intent) {
-        final String[] uriStrings =
-                intent.getStringArrayExtra(ImportVCardActivity.VCARD_URI_ARRAY);
-        if (uriStrings == null || uriStrings.length == 0) {
-            Log.e(LOG_TAG, "Given uri array is empty");
-            return null;
-        }
-
-        final int length = uriStrings.length;
-        final Uri[] uris = new Uri[length];
-        for (int i = 0; i < length; i++) {
-            uris[i] = Uri.parse(uriStrings[i]);
-        }
-
-        return uris;
-    }
-
-    private Account tryGetAccount(Intent intent) {
-        if (intent == null) {
-            Log.w(LOG_TAG, "Intent is null");
-            return null;
-        }
-
-        final String accountName = intent.getStringExtra("account_name");
-        final String accountType = intent.getStringExtra("account_type");
-        if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
-            return new Account(accountName, accountType);
-        } else {
-            Log.w(LOG_TAG, "Account is not set.");
-            return null;
-        }
-    }
+    private RequestHandler mRequestHandler;
+    private Messenger mMessenger = new Messenger(new ImportRequestHandler());
+    private Thread mThread = null;
 
     @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (mNotificationManager == null) {
-            mNotificationManager =
-                    (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
-        }
-
-        // TODO: use this.
-        final int[] estimatedTypeArray =
-            intent.getIntArrayExtra(ImportVCardActivity.ESTIMATED_VCARD_TYPE_ARRAY);
-        final String[] estimatedCharsetArray =
-            intent.getStringArrayExtra(ImportVCardActivity.ESTIMATED_CHARSET_ARRAY);
-        final boolean[] useV30Array =
-            intent.getBooleanArrayExtra(ImportVCardActivity.USE_V30_ARRAY);
-        final int[] entryCountArray =
-            intent.getIntArrayExtra(ImportVCardActivity.ENTRY_COUNT_ARRAY);
-
-        final Account account = tryGetAccount(intent);
-        final Uri[] uris = tryGetUris(intent);
-        if (uris == null) {
-            Log.e(LOG_TAG, "Uris are null.");
-            Toast.makeText(this, getString(R.string.reading_vcard_failed_title),
-                    Toast.LENGTH_LONG).show();
-            stopSelf();
-            return START_NOT_STICKY;
-        }
-
-        int length = uris.length;
-        if (estimatedTypeArray.length < length) {
-            Log.w(LOG_TAG, String.format("estimatedTypeArray.length < length (%d, %d)",
-                    estimatedTypeArray.length, length));
-            length = estimatedTypeArray.length;
-        }
-        if (useV30Array.length < length) {
-            Log.w(LOG_TAG, String.format("useV30Array.length < length (%d, %d)",
-                    useV30Array.length, length));
-            length = useV30Array.length;
-        }
-        if (entryCountArray.length < length) {
-            Log.w(LOG_TAG, String.format("entryCountArray.length < length (%d, %d)",
-                    entryCountArray.length, length));
-            length = entryCountArray.length;
-        }
-
-        synchronized (this) {
-            for (int i = 0; i < length; i++) {
-                mPendingInputs.add(new PendingInput(account,
-                        uris[i], estimatedTypeArray[i], estimatedCharsetArray[i],
-                        useV30Array[i], entryCountArray[i],
-                        startId));
-            }
-            if (!mNowRunning) {
-                Toast.makeText(this, getString(R.string.vcard_importer_start_message),
-                        Toast.LENGTH_LONG).show();
-                // Assume thread is alredy broken.
-                // Even when it still exists, it never scan the PendingInput newly added above.
-                mNowRunning = true;
-                mThread = new VCardReadThread();
-                mThread.start();
-            } else {
-                Toast.makeText(this, getString(R.string.vcard_importer_will_start_message),
-                        Toast.LENGTH_LONG).show();
-            }
-        }
-
-        return START_NOT_STICKY;
+    public int onStartCommand(Intent intent, int flags, int id) {
+        return START_STICKY;
     }
 
     @Override
     public IBinder onBind(Intent intent) {
-        return null;
+        return mMessenger.getBinder();
     }
 }
