diff --git a/common/java/com/android/common/AndroidHttpClient.java b/common/java/com/android/common/AndroidHttpClient.java
deleted file mode 100644
index 4c65eb0..0000000
--- a/common/java/com/android/common/AndroidHttpClient.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.common;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.HttpResponse;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.params.HttpClientParams;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.RequestWrapper;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.protocol.BasicHttpProcessor;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.BasicHttpContext;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-import java.net.URI;
-import java.security.KeyManagementException;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.net.SSLCertificateSocketFactory;
-import android.net.SSLSessionCache;
-import android.os.Looper;
-import android.util.Log;
-
-/**
- * Subclass of the Apache {@link DefaultHttpClient} that is configured with
- * reasonable default settings and registered schemes for Android, and
- * also lets the user add {@link HttpRequestInterceptor} classes.
- * Don't create this directly, use the {@link #newInstance} factory method.
- *
- * <p>This client processes cookies but does not retain them by default.
- * To retain cookies, simply add a cookie store to the HttpContext:</p>
- *
- * <pre>context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);</pre>
- */
-public final class AndroidHttpClient implements HttpClient {
-
-    // Gzip of data shorter than this probably won't be worthwhile
-    public static long DEFAULT_SYNC_MIN_GZIP_BYTES = 256;
-
-    private static final String TAG = "AndroidHttpClient";
-
-
-    /** Interceptor throws an exception if the executing thread is blocked */
-    private static final HttpRequestInterceptor sThreadCheckInterceptor =
-            new HttpRequestInterceptor() {
-        public void process(HttpRequest request, HttpContext context) {
-            // Prevent the HttpRequest from being sent on the main thread
-            if (Looper.myLooper() != null && Looper.myLooper() == Looper.getMainLooper() ) {
-                throw new RuntimeException("This thread forbids HTTP requests");
-            }
-        }
-    };
-
-    /**
-     * Create a new HttpClient with reasonable defaults (which you can update).
-     *
-     * @param userAgent to report in your HTTP requests
-     * @param context to use for caching SSL sessions (may be null for no caching)
-     * @return AndroidHttpClient for you to use for all your requests.
-     */
-    public static AndroidHttpClient newInstance(String userAgent, Context context) {
-        HttpParams params = new BasicHttpParams();
-
-        // Turn off stale checking.  Our connections break all the time anyway,
-        // and it's not worth it to pay the penalty of checking every time.
-        HttpConnectionParams.setStaleCheckingEnabled(params, false);
-
-        // Default connection and socket timeout of 20 seconds.  Tweak to taste.
-        HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
-        HttpConnectionParams.setSoTimeout(params, 20 * 1000);
-        HttpConnectionParams.setSocketBufferSize(params, 8192);
-
-        // Don't handle redirects -- return them to the caller.  Our code
-        // often wants to re-POST after a redirect, which we must do ourselves.
-        HttpClientParams.setRedirecting(params, false);
-
-        // Use a session cache for SSL sockets
-        SSLSessionCache sessionCache = context == null ? null : new SSLSessionCache(context);
-
-        // Set the specified user agent and register standard protocols.
-        HttpProtocolParams.setUserAgent(params, userAgent);
-        SchemeRegistry schemeRegistry = new SchemeRegistry();
-        schemeRegistry.register(new Scheme("http",
-                PlainSocketFactory.getSocketFactory(), 80));
-        schemeRegistry.register(new Scheme("https",
-                SSLCertificateSocketFactory.getHttpSocketFactory(30 * 1000, sessionCache), 443));
-
-        ClientConnectionManager manager =
-                new ThreadSafeClientConnManager(params, schemeRegistry);
-
-        // We use a factory method to modify superclass initialization
-        // parameters without the funny call-a-static-method dance.
-        return new AndroidHttpClient(manager, params);
-    }
-
-    /**
-     * Create a new HttpClient with reasonable defaults (which you can update).
-     * @param userAgent to report in your HTTP requests.
-     * @return AndroidHttpClient for you to use for all your requests.
-     */
-    public static AndroidHttpClient newInstance(String userAgent) {
-        return newInstance(userAgent, null /* session cache */);
-    }
-
-    private final HttpClient delegate;
-
-    private RuntimeException mLeakedException = new IllegalStateException(
-            "AndroidHttpClient created and never closed");
-
-    private AndroidHttpClient(ClientConnectionManager ccm, HttpParams params) {
-        this.delegate = new DefaultHttpClient(ccm, params) {
-            @Override
-            protected BasicHttpProcessor createHttpProcessor() {
-                // Add interceptor to prevent making requests from main thread.
-                BasicHttpProcessor processor = super.createHttpProcessor();
-                processor.addRequestInterceptor(sThreadCheckInterceptor);
-                processor.addRequestInterceptor(new CurlLogger());
-
-                return processor;
-            }
-
-            @Override
-            protected HttpContext createHttpContext() {
-                // Same as DefaultHttpClient.createHttpContext() minus the
-                // cookie store.
-                HttpContext context = new BasicHttpContext();
-                context.setAttribute(
-                        ClientContext.AUTHSCHEME_REGISTRY,
-                        getAuthSchemes());
-                context.setAttribute(
-                        ClientContext.COOKIESPEC_REGISTRY,
-                        getCookieSpecs());
-                context.setAttribute(
-                        ClientContext.CREDS_PROVIDER,
-                        getCredentialsProvider());
-                return context;
-            }
-        };
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        super.finalize();
-        if (mLeakedException != null) {
-            Log.e(TAG, "Leak found", mLeakedException);
-            mLeakedException = null;
-        }
-    }
-
-    /**
-     * Modifies a request to indicate to the server that we would like a
-     * gzipped response.  (Uses the "Accept-Encoding" HTTP header.)
-     * @param request the request to modify
-     * @see #getUngzippedContent
-     */
-    public static void modifyRequestToAcceptGzipResponse(HttpRequest request) {
-        request.addHeader("Accept-Encoding", "gzip");
-    }
-
-    /**
-     * Gets the input stream from a response entity.  If the entity is gzipped
-     * then this will get a stream over the uncompressed data.
-     *
-     * @param entity the entity whose content should be read
-     * @return the input stream to read from
-     * @throws IOException
-     */
-    public static InputStream getUngzippedContent(HttpEntity entity)
-            throws IOException {
-        InputStream responseStream = entity.getContent();
-        if (responseStream == null) return responseStream;
-        Header header = entity.getContentEncoding();
-        if (header == null) return responseStream;
-        String contentEncoding = header.getValue();
-        if (contentEncoding == null) return responseStream;
-        if (contentEncoding.contains("gzip")) responseStream
-                = new GZIPInputStream(responseStream);
-        return responseStream;
-    }
-
-    /**
-     * Release resources associated with this client.  You must call this,
-     * or significant resources (sockets and memory) may be leaked.
-     */
-    public void close() {
-        if (mLeakedException != null) {
-            getConnectionManager().shutdown();
-            mLeakedException = null;
-        }
-    }
-
-    public HttpParams getParams() {
-        return delegate.getParams();
-    }
-
-    public ClientConnectionManager getConnectionManager() {
-        return delegate.getConnectionManager();
-    }
-
-    public HttpResponse execute(HttpUriRequest request) throws IOException {
-        return delegate.execute(request);
-    }
-
-    public HttpResponse execute(HttpUriRequest request, HttpContext context)
-            throws IOException {
-        return delegate.execute(request, context);
-    }
-
-    public HttpResponse execute(HttpHost target, HttpRequest request)
-            throws IOException {
-        return delegate.execute(target, request);
-    }
-
-    public HttpResponse execute(HttpHost target, HttpRequest request,
-            HttpContext context) throws IOException {
-        return delegate.execute(target, request, context);
-    }
-
-    public <T> T execute(HttpUriRequest request, 
-            ResponseHandler<? extends T> responseHandler)
-            throws IOException, ClientProtocolException {
-        return delegate.execute(request, responseHandler);
-    }
-
-    public <T> T execute(HttpUriRequest request,
-            ResponseHandler<? extends T> responseHandler, HttpContext context)
-            throws IOException, ClientProtocolException {
-        return delegate.execute(request, responseHandler, context);
-    }
-
-    public <T> T execute(HttpHost target, HttpRequest request,
-            ResponseHandler<? extends T> responseHandler) throws IOException,
-            ClientProtocolException {
-        return delegate.execute(target, request, responseHandler);
-    }
-
-    public <T> T execute(HttpHost target, HttpRequest request,
-            ResponseHandler<? extends T> responseHandler, HttpContext context)
-            throws IOException, ClientProtocolException {
-        return delegate.execute(target, request, responseHandler, context);
-    }
-
-    /**
-     * Compress data to send to server.
-     * Creates a Http Entity holding the gzipped data.
-     * The data will not be compressed if it is too short.
-     * @param data The bytes to compress
-     * @return Entity holding the data
-     */
-    public static AbstractHttpEntity getCompressedEntity(byte data[], ContentResolver resolver)
-            throws IOException {
-        AbstractHttpEntity entity;
-        if (data.length < getMinGzipSize(resolver)) {
-            entity = new ByteArrayEntity(data);
-        } else {
-            ByteArrayOutputStream arr = new ByteArrayOutputStream();
-            OutputStream zipper = new GZIPOutputStream(arr);
-            zipper.write(data);
-            zipper.close();
-            entity = new ByteArrayEntity(arr.toByteArray());
-            entity.setContentEncoding("gzip");
-        }
-        return entity;
-    }
-
-    /**
-     * Retrieves the minimum size for compressing data.
-     * Shorter data will not be compressed.
-     */
-    public static long getMinGzipSize(ContentResolver resolver) {
-        return DEFAULT_SYNC_MIN_GZIP_BYTES;  // For now, this is just a constant.
-    }
-
-    /* cURL logging support. */
-
-    /**
-     * Logging tag and level.
-     */
-    private static class LoggingConfiguration {
-
-        private final String tag;
-        private final int level;
-
-        private LoggingConfiguration(String tag, int level) {
-            this.tag = tag;
-            this.level = level;
-        }
-
-        /**
-         * Returns true if logging is turned on for this configuration.
-         */
-        private boolean isLoggable() {
-            return Log.isLoggable(tag, level);
-        }
-
-        /**
-         * Prints a message using this configuration.
-         */
-        private void println(String message) {
-            Log.println(level, tag, message);
-        }
-    }
-
-    /** cURL logging configuration. */
-    private volatile LoggingConfiguration curlConfiguration;
-
-    /**
-     * Enables cURL request logging for this client.
-     *
-     * @param name to log messages with
-     * @param level at which to log messages (see {@link android.util.Log})
-     */
-    public void enableCurlLogging(String name, int level) {
-        if (name == null) {
-            throw new NullPointerException("name");
-        }
-        if (level < Log.VERBOSE || level > Log.ASSERT) {
-            throw new IllegalArgumentException("Level is out of range ["
-                + Log.VERBOSE + ".." + Log.ASSERT + "]");    
-        }
-
-        curlConfiguration = new LoggingConfiguration(name, level);
-    }
-
-    /**
-     * Disables cURL logging for this client.
-     */
-    public void disableCurlLogging() {
-        curlConfiguration = null;
-    }
-
-    /**
-     * Logs cURL commands equivalent to requests.
-     */
-    private class CurlLogger implements HttpRequestInterceptor {
-        public void process(HttpRequest request, HttpContext context)
-                throws HttpException, IOException {
-            LoggingConfiguration configuration = curlConfiguration;
-            if (configuration != null
-                    && configuration.isLoggable()
-                    && request instanceof HttpUriRequest) {
-                // Never print auth token -- we used to check ro.secure=0 to
-                // enable that, but can't do that in unbundled code.
-                configuration.println(toCurl((HttpUriRequest) request, false));
-            }
-        }
-    }
-
-    /**
-     * Generates a cURL command equivalent to the given request.
-     */
-    private static String toCurl(HttpUriRequest request, boolean logAuthToken) throws IOException {
-        StringBuilder builder = new StringBuilder();
-
-        builder.append("curl ");
-
-        for (Header header: request.getAllHeaders()) {
-            if (!logAuthToken
-                    && (header.getName().equals("Authorization") ||
-                        header.getName().equals("Cookie"))) {
-                continue;
-            }
-            builder.append("--header \"");
-            builder.append(header.toString().trim());
-            builder.append("\" ");
-        }
-
-        URI uri = request.getURI();
-
-        // If this is a wrapped request, use the URI from the original
-        // request instead. getURI() on the wrapper seems to return a
-        // relative URI. We want an absolute URI.
-        if (request instanceof RequestWrapper) {
-            HttpRequest original = ((RequestWrapper) request).getOriginal();
-            if (original instanceof HttpUriRequest) {
-                uri = ((HttpUriRequest) original).getURI();
-            }
-        }
-
-        builder.append("\"");
-        builder.append(uri);
-        builder.append("\"");
-
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntityEnclosingRequest entityRequest =
-                    (HttpEntityEnclosingRequest) request;
-            HttpEntity entity = entityRequest.getEntity();
-            if (entity != null && entity.isRepeatable()) {
-                if (entity.getContentLength() < 1024) {
-                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
-                    entity.writeTo(stream);
-                    String entityString = stream.toString();
-
-                    // TODO: Check the content type, too.
-                    builder.append(" --data-ascii \"")
-                            .append(entityString)
-                            .append("\"");
-                } else {
-                    builder.append(" [TOO MUCH DATA TO INCLUDE]");
-                }
-            }
-        }
-
-        return builder.toString();
-    }
-}
diff --git a/common/java/com/android/common/DNParser.java b/common/java/com/android/common/DNParser.java
deleted file mode 100644
index 32d57c0..0000000
--- a/common/java/com/android/common/DNParser.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package com.android.common;
-
-import android.util.Log;
-
-import java.io.IOException;
-
-import javax.security.auth.x500.X500Principal;
-
-/**
- * A simple distinguished name(DN) parser.
- *
- * <p>This class is based on org.apache.harmony.security.x509.DNParser.  It's customized to remove
- * external references which are unnecessary for our requirements.
- *
- * <p>This class is only meant for extracting a string value from a DN.  e.g. it doesn't support
- * values in the hex-string style.
- *
- * <p>This class is used by {@link DomainNameValidator} only.  However, in order to make this
- * class visible from unit tests, it's made public.
- */
-public final class DNParser {
-    private static final String TAG = "DNParser";
-
-    /** DN to be parsed. */
-    private final String dn;
-
-    // length of distinguished name string
-    private final int length;
-
-    private int pos, beg, end;
-
-    // tmp vars to store positions of the currently parsed item
-    private int cur;
-
-    // distinguished name chars
-    private char[] chars;
-
-    /**
-     * Exception message thrown when we failed to parse DN, which shouldn't happen because we
-     * only handle DNs that {@link X500Principal#getName} returns, which shouldn't be malformed.
-     */
-    private static final String ERROR_PARSE_ERROR = "Failed to parse DN";
-
-    /**
-     * Constructor.
-     *
-     * @param principal - {@link X500Principal} to be parsed
-     */
-    public DNParser(X500Principal principal) {
-        this.dn = principal.getName(X500Principal.RFC2253);
-        this.length = dn.length();
-    }
-
-    // gets next attribute type: (ALPHA 1*keychar) / oid
-    private String nextAT() throws IOException {
-
-        // skip preceding space chars, they can present after
-        // comma or semicolon (compatibility with RFC 1779)
-        for (; pos < length && chars[pos] == ' '; pos++) {
-        }
-        if (pos == length) {
-            return null; // reached the end of DN
-        }
-
-        // mark the beginning of attribute type
-        beg = pos;
-
-        // attribute type chars
-        pos++;
-        for (; pos < length && chars[pos] != '=' && chars[pos] != ' '; pos++) {
-            // we don't follow exact BNF syntax here:
-            // accept any char except space and '='
-        }
-        if (pos >= length) {
-            // unexpected end of DN
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        // mark the end of attribute type
-        end = pos;
-
-        // skip trailing space chars between attribute type and '='
-        // (compatibility with RFC 1779)
-        if (chars[pos] == ' ') {
-            for (; pos < length && chars[pos] != '=' && chars[pos] == ' '; pos++) {
-            }
-
-            if (chars[pos] != '=' || pos == length) {
-                // unexpected end of DN
-                throw new IOException(ERROR_PARSE_ERROR);
-            }
-        }
-
-        pos++; //skip '=' char
-
-        // skip space chars between '=' and attribute value
-        // (compatibility with RFC 1779)
-        for (; pos < length && chars[pos] == ' '; pos++) {
-        }
-
-        // in case of oid attribute type skip its prefix: "oid." or "OID."
-        // (compatibility with RFC 1779)
-        if ((end - beg > 4) && (chars[beg + 3] == '.')
-                && (chars[beg] == 'O' || chars[beg] == 'o')
-                && (chars[beg + 1] == 'I' || chars[beg + 1] == 'i')
-                && (chars[beg + 2] == 'D' || chars[beg + 2] == 'd')) {
-            beg += 4;
-        }
-
-        return new String(chars, beg, end - beg);
-    }
-
-    // gets quoted attribute value: QUOTATION *( quotechar / pair ) QUOTATION
-    private String quotedAV() throws IOException {
-
-        pos++;
-        beg = pos;
-        end = beg;
-        while (true) {
-
-            if (pos == length) {
-                // unexpected end of DN
-                throw new IOException(ERROR_PARSE_ERROR);
-            }
-
-            if (chars[pos] == '"') {
-                // enclosing quotation was found
-                pos++;
-                break;
-            } else if (chars[pos] == '\\') {
-                chars[end] = getEscaped();
-            } else {
-                // shift char: required for string with escaped chars
-                chars[end] = chars[pos];
-            }
-            pos++;
-            end++;
-        }
-
-        // skip trailing space chars before comma or semicolon.
-        // (compatibility with RFC 1779)
-        for (; pos < length && chars[pos] == ' '; pos++) {
-        }
-
-        return new String(chars, beg, end - beg);
-    }
-
-    // gets hex string attribute value: "#" hexstring
-    private String hexAV() throws IOException {
-
-        if (pos + 4 >= length) {
-            // encoded byte array  must be not less then 4 c
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        beg = pos; // store '#' position
-        pos++;
-        while (true) {
-
-            // check for end of attribute value
-            // looks for space and component separators
-            if (pos == length || chars[pos] == '+' || chars[pos] == ','
-                    || chars[pos] == ';') {
-                end = pos;
-                break;
-            }
-
-            if (chars[pos] == ' ') {
-                end = pos;
-                pos++;
-                // skip trailing space chars before comma or semicolon.
-                // (compatibility with RFC 1779)
-                for (; pos < length && chars[pos] == ' '; pos++) {
-                }
-                break;
-            } else if (chars[pos] >= 'A' && chars[pos] <= 'F') {
-                chars[pos] += 32; //to low case
-            }
-
-            pos++;
-        }
-
-        // verify length of hex string
-        // encoded byte array  must be not less then 4 and must be even number
-        int hexLen = end - beg; // skip first '#' char
-        if (hexLen < 5 || (hexLen & 1) == 0) {
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        // get byte encoding from string representation
-        byte[] encoded = new byte[hexLen / 2];
-        for (int i = 0, p = beg + 1; i < encoded.length; p += 2, i++) {
-            encoded[i] = (byte) getByte(p);
-        }
-
-        return new String(chars, beg, hexLen);
-    }
-
-    // gets string attribute value: *( stringchar / pair )
-    private String escapedAV() throws IOException {
-
-        beg = pos;
-        end = pos;
-        while (true) {
-
-            if (pos >= length) {
-                // the end of DN has been found
-                return new String(chars, beg, end - beg);
-            }
-
-            switch (chars[pos]) {
-            case '+':
-            case ',':
-            case ';':
-                // separator char has beed found
-                return new String(chars, beg, end - beg);
-            case '\\':
-                // escaped char
-                chars[end++] = getEscaped();
-                pos++;
-                break;
-            case ' ':
-                // need to figure out whether space defines
-                // the end of attribute value or not
-                cur = end;
-
-                pos++;
-                chars[end++] = ' ';
-
-                for (; pos < length && chars[pos] == ' '; pos++) {
-                    chars[end++] = ' ';
-                }
-                if (pos == length || chars[pos] == ',' || chars[pos] == '+'
-                        || chars[pos] == ';') {
-                    // separator char or the end of DN has beed found
-                    return new String(chars, beg, cur - beg);
-                }
-                break;
-            default:
-                chars[end++] = chars[pos];
-                pos++;
-            }
-        }
-    }
-
-    // returns escaped char
-    private char getEscaped() throws IOException {
-
-        pos++;
-        if (pos == length) {
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        switch (chars[pos]) {
-        case '"':
-        case '\\':
-        case ',':
-        case '=':
-        case '+':
-        case '<':
-        case '>':
-        case '#':
-        case ';':
-        case ' ':
-        case '*':
-        case '%':
-        case '_':
-            //FIXME: escaping is allowed only for leading or trailing space char
-            return chars[pos];
-        default:
-            // RFC doesn't explicitly say that escaped hex pair is
-            // interpreted as UTF-8 char. It only contains an example of such DN.
-            return getUTF8();
-        }
-    }
-
-    // decodes UTF-8 char
-    // see http://www.unicode.org for UTF-8 bit distribution table
-    private char getUTF8() throws IOException {
-
-        int res = getByte(pos);
-        pos++; //FIXME tmp
-
-        if (res < 128) { // one byte: 0-7F
-            return (char) res;
-        } else if (res >= 192 && res <= 247) {
-
-            int count;
-            if (res <= 223) { // two bytes: C0-DF
-                count = 1;
-                res = res & 0x1F;
-            } else if (res <= 239) { // three bytes: E0-EF
-                count = 2;
-                res = res & 0x0F;
-            } else { // four bytes: F0-F7
-                count = 3;
-                res = res & 0x07;
-            }
-
-            int b;
-            for (int i = 0; i < count; i++) {
-                pos++;
-                if (pos == length || chars[pos] != '\\') {
-                    return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
-                }
-                pos++;
-
-                b = getByte(pos);
-                pos++; //FIXME tmp
-                if ((b & 0xC0) != 0x80) {
-                    return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
-                }
-
-                res = (res << 6) + (b & 0x3F);
-            }
-            return (char) res;
-        } else {
-            return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
-        }
-    }
-
-    // Returns byte representation of a char pair
-    // The char pair is composed of DN char in
-    // specified 'position' and the next char
-    // According to BNF syntax:
-    // hexchar    = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
-    //                    / "a" / "b" / "c" / "d" / "e" / "f"
-    private int getByte(int position) throws IOException {
-
-        if ((position + 1) >= length) {
-            // to avoid ArrayIndexOutOfBoundsException
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        int b1, b2;
-
-        b1 = chars[position];
-        if (b1 >= '0' && b1 <= '9') {
-            b1 = b1 - '0';
-        } else if (b1 >= 'a' && b1 <= 'f') {
-            b1 = b1 - 87; // 87 = 'a' - 10
-        } else if (b1 >= 'A' && b1 <= 'F') {
-            b1 = b1 - 55; // 55 = 'A' - 10
-        } else {
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        b2 = chars[position + 1];
-        if (b2 >= '0' && b2 <= '9') {
-            b2 = b2 - '0';
-        } else if (b2 >= 'a' && b2 <= 'f') {
-            b2 = b2 - 87; // 87 = 'a' - 10
-        } else if (b2 >= 'A' && b2 <= 'F') {
-            b2 = b2 - 55; // 55 = 'A' - 10
-        } else {
-            throw new IOException(ERROR_PARSE_ERROR);
-        }
-
-        return (b1 << 4) + b2;
-    }
-
-    /**
-     * Parses the DN and returns the attribute value for an attribute type.
-     *
-     * @param attributeType attribute type to look for (e.g. "ca")
-     * @return value of the attribute that first found, or null if none found
-     */
-    public String find(String attributeType) {
-        try {
-            // Initialize internal state.
-            pos = 0;
-            beg = 0;
-            end = 0;
-            cur = 0;
-            chars = dn.toCharArray();
-
-            String attType = nextAT();
-            if (attType == null) {
-                return null;
-            }
-            while (true) {
-                String attValue = "";
-
-                if (pos == length) {
-                    return null;
-                }
-
-                switch (chars[pos]) {
-                case '"':
-                    attValue = quotedAV();
-                    break;
-                case '#':
-                    attValue = hexAV();
-                    break;
-                case '+':
-                case ',':
-                case ';': // compatibility with RFC 1779: semicolon can separate RDNs
-                    //empty attribute value
-                    break;
-                default:
-                    attValue = escapedAV();
-                }
-
-                if (attributeType.equalsIgnoreCase(attType)) {
-                    return attValue;
-                }
-
-                if (pos >= length) {
-                    return null;
-                }
-
-                if (chars[pos] == ',' || chars[pos] == ';') {
-                } else if (chars[pos] != '+') {
-                    throw new IOException(ERROR_PARSE_ERROR);
-                }
-
-                pos++;
-                attType = nextAT();
-                if (attType == null) {
-                    throw new IOException(ERROR_PARSE_ERROR);
-                }
-            }
-        } catch (IOException e) {
-            // Parse error shouldn't happen, because we only handle DNs that
-            // X500Principal.getName() returns, which shouldn't be malformed.
-            Log.e(TAG, "Failed to parse DN: " + dn);
-            return null;
-        }
-    }
-}
diff --git a/common/java/com/android/common/DomainNameValidator.java b/common/java/com/android/common/DomainNameValidator.java
deleted file mode 100644
index 25dc007..0000000
--- a/common/java/com/android/common/DomainNameValidator.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.common;
-
-import android.util.Config;
-import android.util.Log;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import javax.security.auth.x500.X500Principal;
-
-public class DomainNameValidator {
-    private final static String TAG = "DomainNameValidator";
-
-    private static final boolean DEBUG = false;
-    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private static Pattern QUICK_IP_PATTERN;
-    static {
-        try {
-            QUICK_IP_PATTERN = Pattern.compile("^[a-f0-9\\.:]+$");
-        } catch (PatternSyntaxException e) {}
-    }
-
-    private static final int ALT_DNS_NAME = 2;
-    private static final int ALT_IPA_NAME = 7;
-
-    /**
-     * Checks the site certificate against the domain name of the site being visited
-     * @param certificate The certificate to check
-     * @param thisDomain The domain name of the site being visited
-     * @return True iff if there is a domain match as specified by RFC2818
-     */
-    public static boolean match(X509Certificate certificate, String thisDomain) {
-        if (certificate == null || thisDomain == null || thisDomain.length() == 0) {
-            return false;
-        }
-
-        thisDomain = thisDomain.toLowerCase();
-        if (!isIpAddress(thisDomain)) {
-            return matchDns(certificate, thisDomain);
-        } else {
-            return matchIpAddress(certificate, thisDomain);
-        }
-    }
-
-    /**
-     * @return True iff the domain name is specified as an IP address
-     */
-    private static boolean isIpAddress(String domain) {
-        boolean rval = (domain != null && domain.length() != 0);
-        if (rval) {
-            try {
-                // do a quick-dirty IP match first to avoid DNS lookup
-                rval = QUICK_IP_PATTERN.matcher(domain).matches();
-                if (rval) {
-                    rval = domain.equals(
-                        InetAddress.getByName(domain).getHostAddress());
-                }
-            } catch (UnknownHostException e) {
-                String errorMessage = e.getMessage();
-                if (errorMessage == null) {
-                  errorMessage = "unknown host exception";
-                }
-
-                if (LOG_ENABLED) {
-                    Log.v(TAG, "DomainNameValidator.isIpAddress(): " + errorMessage);
-                }
-
-                rval = false;
-            }
-        }
-
-        return rval;
-    }
-
-    /**
-     * Checks the site certificate against the IP domain name of the site being visited
-     * @param certificate The certificate to check
-     * @param thisDomain The DNS domain name of the site being visited
-     * @return True iff if there is a domain match as specified by RFC2818
-     */
-    private static boolean matchIpAddress(X509Certificate certificate, String thisDomain) {
-        if (LOG_ENABLED) {
-            Log.v(TAG, "DomainNameValidator.matchIpAddress(): this domain: " + thisDomain);
-        }
-
-        try {
-            Collection subjectAltNames = certificate.getSubjectAlternativeNames();
-            if (subjectAltNames != null) {
-                Iterator i = subjectAltNames.iterator();
-                while (i.hasNext()) {
-                    List altNameEntry = (List)(i.next());
-                    if (altNameEntry != null && 2 <= altNameEntry.size()) {
-                        Integer altNameType = (Integer)(altNameEntry.get(0));
-                        if (altNameType != null) {
-                            if (altNameType.intValue() == ALT_IPA_NAME) {
-                                String altName = (String)(altNameEntry.get(1));
-                                if (altName != null) {
-                                    if (LOG_ENABLED) {
-                                        Log.v(TAG, "alternative IP: " + altName);
-                                    }
-                                    if (thisDomain.equalsIgnoreCase(altName)) {
-                                        return true;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (CertificateParsingException e) {}
-
-        return false;
-    }
-
-    /**
-     * Checks the site certificate against the DNS domain name of the site being visited
-     * @param certificate The certificate to check
-     * @param thisDomain The DNS domain name of the site being visited
-     * @return True iff if there is a domain match as specified by RFC2818
-     */
-    private static boolean matchDns(X509Certificate certificate, String thisDomain) {
-        boolean hasDns = false;
-        try {
-            Collection subjectAltNames = certificate.getSubjectAlternativeNames();
-            if (subjectAltNames != null) {
-                Iterator i = subjectAltNames.iterator();
-                while (i.hasNext()) {
-                    List altNameEntry = (List)(i.next());
-                    if (altNameEntry != null && 2 <= altNameEntry.size()) {
-                        Integer altNameType = (Integer)(altNameEntry.get(0));
-                        if (altNameType != null) {
-                            if (altNameType.intValue() == ALT_DNS_NAME) {
-                                hasDns = true;
-                                String altName = (String)(altNameEntry.get(1));
-                                if (altName != null) {
-                                    if (matchDns(thisDomain, altName)) {
-                                        return true;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (CertificateParsingException e) {
-            String errorMessage = e.getMessage();
-            if (errorMessage == null) {
-                errorMessage = "failed to parse certificate";
-            }
-
-            Log.w(TAG, "DomainNameValidator.matchDns(): " + errorMessage);
-            return false;
-        }
-
-        if (!hasDns) {
-            final String cn = new DNParser(certificate.getSubjectX500Principal())
-                    .find("cn");
-            if (LOG_ENABLED) {
-                Log.v(TAG, "Validating subject: DN:"
-                        + certificate.getSubjectX500Principal().getName(X500Principal.CANONICAL)
-                        + "  CN:" + cn);
-            }
-            if (cn != null) {
-                return matchDns(thisDomain, cn);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * @param thisDomain The domain name of the site being visited
-     * @param thatDomain The domain name from the certificate
-     * @return True iff thisDomain matches thatDomain as specified by RFC2818
-     */
-    // not private for testing
-    public static boolean matchDns(String thisDomain, String thatDomain) {
-        if (LOG_ENABLED) {
-            Log.v(TAG, "DomainNameValidator.matchDns():" +
-                      " this domain: " + thisDomain +
-                      " that domain: " + thatDomain);
-        }
-
-        if (thisDomain == null || thisDomain.length() == 0 ||
-            thatDomain == null || thatDomain.length() == 0) {
-            return false;
-        }
-
-        thatDomain = thatDomain.toLowerCase();
-
-        // (a) domain name strings are equal, ignoring case: X matches X
-        boolean rval = thisDomain.equals(thatDomain);
-        if (!rval) {
-            String[] thisDomainTokens = thisDomain.split("\\.");
-            String[] thatDomainTokens = thatDomain.split("\\.");
-
-            int thisDomainTokensNum = thisDomainTokens.length;
-            int thatDomainTokensNum = thatDomainTokens.length;
-
-            // (b) OR thatHost is a '.'-suffix of thisHost: Z.Y.X matches X
-            if (thisDomainTokensNum >= thatDomainTokensNum) {
-                for (int i = thatDomainTokensNum - 1; i >= 0; --i) {
-                    rval = thisDomainTokens[i].equals(thatDomainTokens[i]);
-                    if (!rval) {
-                        // (c) OR we have a special *-match:
-                        // *.Y.X matches Z.Y.X but *.X doesn't match Z.Y.X
-                        rval = (i == 0 && thisDomainTokensNum == thatDomainTokensNum);
-                        if (rval) {
-                            rval = thatDomainTokens[0].equals("*");
-                            if (!rval) {
-                                // (d) OR we have a *-component match:
-                                // f*.com matches foo.com but not bar.com
-                                rval = domainTokenMatch(
-                                    thisDomainTokens[0], thatDomainTokens[0]);
-                            }
-                        }
-                        break;
-                    }
-                }
-            } else {
-              // (e) OR thatHost has a '*.'-prefix of thisHost:
-              // *.Y.X matches Y.X
-              rval = thatDomain.equals("*." + thisDomain);
-            }
-        }
-
-        return rval;
-    }
-
-    /**
-     * @param thisDomainToken The domain token from the current domain name
-     * @param thatDomainToken The domain token from the certificate
-     * @return True iff thisDomainToken matches thatDomainToken, using the
-     * wildcard match as specified by RFC2818-3.1. For example, f*.com must
-     * match foo.com but not bar.com
-     */
-    private static boolean domainTokenMatch(String thisDomainToken, String thatDomainToken) {
-        if (thisDomainToken != null && thatDomainToken != null) {
-            int starIndex = thatDomainToken.indexOf('*');
-            if (starIndex >= 0) {
-                if (thatDomainToken.length() - 1 <= thisDomainToken.length()) {
-                    String prefix = thatDomainToken.substring(0,  starIndex);
-                    String suffix = thatDomainToken.substring(starIndex + 1);
-
-                    return thisDomainToken.startsWith(prefix) && thisDomainToken.endsWith(suffix);
-                }
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/common/java/com/android/common/FastXmlSerializer.java b/common/java/com/android/common/FastXmlSerializer.java
deleted file mode 100644
index 0d33941..0000000
--- a/common/java/com/android/common/FastXmlSerializer.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2006 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.common;
-
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-
-/**
- * This is a quick and dirty implementation of XmlSerializer that isn't horribly
- * painfully slow like the normal one.  It only does what is needed for the
- * specific XML files being written with it.
- */
-public class FastXmlSerializer implements XmlSerializer {
-    private static final String ESCAPE_TABLE[] = new String[] {
-        null,     null,     null,     null,     null,     null,     null,     null,  // 0-7
-        null,     null,     null,     null,     null,     null,     null,     null,  // 8-15
-        null,     null,     null,     null,     null,     null,     null,     null,  // 16-23
-        null,     null,     null,     null,     null,     null,     null,     null,  // 24-31
-        null,     null,     "&quot;", null,     null,     null,     "&amp;",  null,  // 32-39
-        null,     null,     null,     null,     null,     null,     null,     null,  // 40-47
-        null,     null,     null,     null,     null,     null,     null,     null,  // 48-55
-        null,     null,     null,     null,     "&lt;",   null,     "&gt;",   null,  // 56-63
-    };
-
-    private static final int BUFFER_LEN = 8192;
-
-    private final char[] mText = new char[BUFFER_LEN];
-    private int mPos;
-
-    private Writer mWriter;
-
-    private OutputStream mOutputStream;
-    private CharsetEncoder mCharset;
-    private ByteBuffer mBytes = ByteBuffer.allocate(BUFFER_LEN);
-
-    private boolean mInTag;
-
-    private void append(char c) throws IOException {
-        int pos = mPos;
-        if (pos >= (BUFFER_LEN-1)) {
-            flush();
-            pos = mPos;
-        }
-        mText[pos] = c;
-        mPos = pos+1;
-    }
-
-    private void append(String str, int i, final int length) throws IOException {
-        if (length > BUFFER_LEN) {
-            final int end = i + length;
-            while (i < end) {
-                int next = i + BUFFER_LEN;
-                append(str, i, next<end ? BUFFER_LEN : (end-i));
-                i = next;
-            }
-            return;
-        }
-        int pos = mPos;
-        if ((pos+length) > BUFFER_LEN) {
-            flush();
-            pos = mPos;
-        }
-        str.getChars(i, i+length, mText, pos);
-        mPos = pos + length;
-    }
-
-    private void append(char[] buf, int i, final int length) throws IOException {
-        if (length > BUFFER_LEN) {
-            final int end = i + length;
-            while (i < end) {
-                int next = i + BUFFER_LEN;
-                append(buf, i, next<end ? BUFFER_LEN : (end-i));
-                i = next;
-            }
-            return;
-        }
-        int pos = mPos;
-        if ((pos+length) > BUFFER_LEN) {
-            flush();
-            pos = mPos;
-        }
-        System.arraycopy(buf, i, mText, pos, length);
-        mPos = pos + length;
-    }
-
-    private void append(String str) throws IOException {
-        append(str, 0, str.length());
-    }
-
-    private void escapeAndAppendString(final String string) throws IOException {
-        final int N = string.length();
-        final char NE = (char)ESCAPE_TABLE.length;
-        final String[] escapes = ESCAPE_TABLE;
-        int lastPos = 0;
-        int pos;
-        for (pos=0; pos<N; pos++) {
-            char c = string.charAt(pos);
-            if (c >= NE) continue;
-            String escape = escapes[c];
-            if (escape == null) continue;
-            if (lastPos < pos) append(string, lastPos, pos-lastPos);
-            lastPos = pos + 1;
-            append(escape);
-        }
-        if (lastPos < pos) append(string, lastPos, pos-lastPos);
-    }
-
-    private void escapeAndAppendString(char[] buf, int start, int len) throws IOException {
-        final char NE = (char)ESCAPE_TABLE.length;
-        final String[] escapes = ESCAPE_TABLE;
-        int end = start+len;
-        int lastPos = start;
-        int pos;
-        for (pos=start; pos<end; pos++) {
-            char c = buf[pos];
-            if (c >= NE) continue;
-            String escape = escapes[c];
-            if (escape == null) continue;
-            if (lastPos < pos) append(buf, lastPos, pos-lastPos);
-            lastPos = pos + 1;
-            append(escape);
-        }
-        if (lastPos < pos) append(buf, lastPos, pos-lastPos);
-    }
-
-    public XmlSerializer attribute(String namespace, String name, String value) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        append(' ');
-        if (namespace != null) {
-            append(namespace);
-            append(':');
-        }
-        append(name);
-        append("=\"");
-
-        escapeAndAppendString(value);
-        append('"');
-        return this;
-    }
-
-    public void cdsect(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void comment(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void docdecl(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void endDocument() throws IOException, IllegalArgumentException, IllegalStateException {
-        flush();
-    }
-
-    public XmlSerializer endTag(String namespace, String name) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        if (mInTag) {
-            append(" />\n");
-        } else {
-            append("</");
-            if (namespace != null) {
-                append(namespace);
-                append(':');
-            }
-            append(name);
-            append(">\n");
-        }
-        mInTag = false;
-        return this;
-    }
-
-    public void entityRef(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    private void flushBytes() throws IOException {
-        int position;
-        if ((position = mBytes.position()) > 0) {
-            mBytes.flip();
-            mOutputStream.write(mBytes.array(), 0, position);
-            mBytes.clear();
-        }
-    }
-
-    public void flush() throws IOException {
-        //Log.i("PackageManager", "flush mPos=" + mPos);
-        if (mPos > 0) {
-            if (mOutputStream != null) {
-                CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos);
-                CoderResult result = mCharset.encode(charBuffer, mBytes, true);
-                while (true) {
-                    if (result.isError()) {
-                        throw new IOException(result.toString());
-                    } else if (result.isOverflow()) {
-                        flushBytes();
-                        result = mCharset.encode(charBuffer, mBytes, true);
-                        continue;
-                    }
-                    break;
-                }
-                flushBytes();
-                mOutputStream.flush();
-            } else {
-                mWriter.write(mText, 0, mPos);
-                mWriter.flush();
-            }
-            mPos = 0;
-        }
-    }
-
-    public int getDepth() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean getFeature(String name) {
-        throw new UnsupportedOperationException();
-    }
-
-    public String getName() {
-        throw new UnsupportedOperationException();
-    }
-
-    public String getNamespace() {
-        throw new UnsupportedOperationException();
-    }
-
-    public String getPrefix(String namespace, boolean generatePrefix)
-            throws IllegalArgumentException {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getProperty(String name) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void ignorableWhitespace(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void processingInstruction(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setFeature(String name, boolean state) throws IllegalArgumentException,
-            IllegalStateException {
-        if (name.equals("http://xmlpull.org/v1/doc/features.html#indent-output")) {
-            return;
-        }
-        throw new UnsupportedOperationException();
-    }
-
-    public void setOutput(OutputStream os, String encoding) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        if (os == null)
-            throw new IllegalArgumentException();
-        if (true) {
-            try {
-                mCharset = Charset.forName(encoding).newEncoder();
-            } catch (IllegalCharsetNameException e) {
-                throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
-                        encoding).initCause(e));
-            } catch (UnsupportedCharsetException e) {
-                throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
-                        encoding).initCause(e));
-            }
-            mOutputStream = os;
-        } else {
-            setOutput(
-                encoding == null
-                    ? new OutputStreamWriter(os)
-                    : new OutputStreamWriter(os, encoding));
-        }
-    }
-
-    public void setOutput(Writer writer) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        mWriter = writer;
-    }
-
-    public void setPrefix(String prefix, String namespace) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setProperty(String name, Object value) throws IllegalArgumentException,
-            IllegalStateException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void startDocument(String encoding, Boolean standalone) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        append("<?xml version='1.0' encoding='utf-8' standalone='"
-                + (standalone ? "yes" : "no") + "' ?>\n");
-    }
-
-    public XmlSerializer startTag(String namespace, String name) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        if (mInTag) {
-            append(">\n");
-        }
-        append('<');
-        if (namespace != null) {
-            append(namespace);
-            append(':');
-        }
-        append(name);
-        mInTag = true;
-        return this;
-    }
-
-    public XmlSerializer text(char[] buf, int start, int len) throws IOException,
-            IllegalArgumentException, IllegalStateException {
-        if (mInTag) {
-            append(">");
-            mInTag = false;
-        }
-        escapeAndAppendString(buf, start, len);
-        return this;
-    }
-
-    public XmlSerializer text(String text) throws IOException, IllegalArgumentException,
-            IllegalStateException {
-        if (mInTag) {
-            append(">");
-            mInTag = false;
-        }
-        escapeAndAppendString(text);
-        return this;
-    }
-
-}
diff --git a/common/java/com/android/common/HttpDateTime.java b/common/java/com/android/common/HttpDateTime.java
deleted file mode 100644
index f4052cc..0000000
--- a/common/java/com/android/common/HttpDateTime.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.common;
-
-import android.text.format.Time;
-
-import java.util.Calendar;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-/** {@hide} */
-public final class HttpDateTime {
-
-    /*
-     * Regular expression for parsing HTTP-date.
-     *
-     * Wdy, DD Mon YYYY HH:MM:SS GMT
-     * RFC 822, updated by RFC 1123
-     *
-     * Weekday, DD-Mon-YY HH:MM:SS GMT
-     * RFC 850, obsoleted by RFC 1036
-     *
-     * Wdy Mon DD HH:MM:SS YYYY
-     * ANSI C's asctime() format
-     *
-     * with following variations
-     *
-     * Wdy, DD-Mon-YYYY HH:MM:SS GMT
-     * Wdy, (SP)D Mon YYYY HH:MM:SS GMT
-     * Wdy,DD Mon YYYY HH:MM:SS GMT
-     * Wdy, DD-Mon-YY HH:MM:SS GMT
-     * Wdy, DD Mon YYYY HH:MM:SS -HHMM
-     * Wdy, DD Mon YYYY HH:MM:SS
-     * Wdy Mon (SP)D HH:MM:SS YYYY
-     * Wdy Mon DD HH:MM:SS YYYY GMT
-     * 
-     * HH can be H if the first digit is zero.
-     * 
-     * Mon can be the full name of the month.
-     */
-    private static final String HTTP_DATE_RFC_REGEXP =
-            "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]"
-            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])";
-
-    private static final String HTTP_DATE_ANSIC_REGEXP =
-            "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]"
-            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})";
-
-    /**
-     * The compiled version of the HTTP-date regular expressions.
-     */
-    private static final Pattern HTTP_DATE_RFC_PATTERN =
-            Pattern.compile(HTTP_DATE_RFC_REGEXP);
-    private static final Pattern HTTP_DATE_ANSIC_PATTERN =
-            Pattern.compile(HTTP_DATE_ANSIC_REGEXP);
-
-    private static class TimeOfDay {
-        TimeOfDay(int h, int m, int s) {
-            this.hour = h;
-            this.minute = m;
-            this.second = s;
-        }
-        
-        int hour;
-        int minute;
-        int second;
-    }
-
-    public static Long parse(String timeString)
-            throws IllegalArgumentException {
-
-        int date = 1;
-        int month = Calendar.JANUARY;
-        int year = 1970;
-        TimeOfDay timeOfDay;
-
-        Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString);
-        if (rfcMatcher.find()) {
-            date = getDate(rfcMatcher.group(1));
-            month = getMonth(rfcMatcher.group(2));
-            year = getYear(rfcMatcher.group(3));
-            timeOfDay = getTime(rfcMatcher.group(4));
-        } else {
-            Matcher ansicMatcher = HTTP_DATE_ANSIC_PATTERN.matcher(timeString);
-            if (ansicMatcher.find()) {
-                month = getMonth(ansicMatcher.group(1));
-                date = getDate(ansicMatcher.group(2));
-                timeOfDay = getTime(ansicMatcher.group(3));
-                year = getYear(ansicMatcher.group(4));
-            } else {
-                throw new IllegalArgumentException();
-            }
-        }
-
-        // FIXME: Y2038 BUG!
-        if (year >= 2038) {
-            year = 2038;
-            month = Calendar.JANUARY;
-            date = 1;
-        }
-
-        Time time = new Time(Time.TIMEZONE_UTC);
-        time.set(timeOfDay.second, timeOfDay.minute, timeOfDay.hour, date,
-                month, year);
-        return time.toMillis(false /* use isDst */);
-    }
-
-    private static int getDate(String dateString) {
-        if (dateString.length() == 2) {
-            return (dateString.charAt(0) - '0') * 10
-                    + (dateString.charAt(1) - '0');
-        } else {
-            return (dateString.charAt(0) - '0');
-        }
-    }
-
-    /*
-     * jan = 9 + 0 + 13 = 22
-     * feb = 5 + 4 + 1 = 10
-     * mar = 12 + 0 + 17 = 29
-     * apr = 0 + 15 + 17 = 32
-     * may = 12 + 0 + 24 = 36
-     * jun = 9 + 20 + 13 = 42
-     * jul = 9 + 20 + 11 = 40
-     * aug = 0 + 20 + 6 = 26
-     * sep = 18 + 4 + 15 = 37
-     * oct = 14 + 2 + 19 = 35
-     * nov = 13 + 14 + 21 = 48
-     * dec = 3 + 4 + 2 = 9
-     */
-    private static int getMonth(String monthString) {
-        int hash = Character.toLowerCase(monthString.charAt(0)) +
-                Character.toLowerCase(monthString.charAt(1)) +
-                Character.toLowerCase(monthString.charAt(2)) - 3 * 'a';
-        switch (hash) {
-            case 22:
-                return Calendar.JANUARY;
-            case 10:
-                return Calendar.FEBRUARY;
-            case 29:
-                return Calendar.MARCH;
-            case 32:
-                return Calendar.APRIL;
-            case 36:
-                return Calendar.MAY;
-            case 42:
-                return Calendar.JUNE;
-            case 40:
-                return Calendar.JULY;
-            case 26:
-                return Calendar.AUGUST;
-            case 37:
-                return Calendar.SEPTEMBER;
-            case 35:
-                return Calendar.OCTOBER;
-            case 48:
-                return Calendar.NOVEMBER;
-            case 9:
-                return Calendar.DECEMBER;
-            default:
-                throw new IllegalArgumentException();
-        }
-    }
-
-    private static int getYear(String yearString) {
-        if (yearString.length() == 2) {
-            int year = (yearString.charAt(0) - '0') * 10
-                    + (yearString.charAt(1) - '0');
-            if (year >= 70) {
-                return year + 1900;
-            } else {
-                return year + 2000;
-            }
-        } else if (yearString.length() == 3) {
-            // According to RFC 2822, three digit years should be added to 1900.
-            int year = (yearString.charAt(0) - '0') * 100
-                    + (yearString.charAt(1) - '0') * 10
-                    + (yearString.charAt(2) - '0');
-            return year + 1900;
-        } else if (yearString.length() == 4) {
-             return (yearString.charAt(0) - '0') * 1000
-                    + (yearString.charAt(1) - '0') * 100
-                    + (yearString.charAt(2) - '0') * 10
-                    + (yearString.charAt(3) - '0');
-        } else {
-             return 1970;
-        }
-    }
-
-    private static TimeOfDay getTime(String timeString) {
-        // HH might be H
-        int i = 0;
-        int hour = timeString.charAt(i++) - '0';
-        if (timeString.charAt(i) != ':')
-            hour = hour * 10 + (timeString.charAt(i++) - '0');
-        // Skip ':'
-        i++;
-        
-        int minute = (timeString.charAt(i++) - '0') * 10
-                    + (timeString.charAt(i++) - '0');
-        // Skip ':'
-        i++;
-        
-        int second = (timeString.charAt(i++) - '0') * 10
-                  + (timeString.charAt(i++) - '0');
-
-        return new TimeOfDay(hour, minute, second);        
-    }
-}
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index 0c7ca83..0a48fe7 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -17,6 +17,7 @@
 package com.android.common;
 
 import android.content.SharedPreferences;
+import android.net.http.HttpDateTime;
 import android.text.format.Time;
 
 import java.util.Map;
diff --git a/common/java/com/android/common/Patterns.java b/common/java/com/android/common/Patterns.java
deleted file mode 100644
index 3b3b038..0000000
--- a/common/java/com/android/common/Patterns.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.common;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Commonly used regular expression patterns.
- */
-public class Patterns {
-    /**
-     *  Regular expression to match all IANA top-level domains.
-     *  List accurate as of 2010/02/05.  List taken from:
-     *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
-     */
-    public static final String TOP_LEVEL_DOMAIN_STR =
-        "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
-        + "|(biz|b[abdefghijmnorstvwyz])"
-        + "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
-        + "|d[ejkmoz]"
-        + "|(edu|e[cegrstu])"
-        + "|f[ijkmor]"
-        + "|(gov|g[abdefghilmnpqrstuwy])"
-        + "|h[kmnrtu]"
-        + "|(info|int|i[delmnoqrst])"
-        + "|(jobs|j[emop])"
-        + "|k[eghimnprwyz]"
-        + "|l[abcikrstuvy]"
-        + "|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
-        + "|(name|net|n[acefgilopruz])"
-        + "|(org|om)"
-        + "|(pro|p[aefghklmnrstwy])"
-        + "|qa"
-        + "|r[eosuw]"
-        + "|s[abcdeghijklmnortuvyz]"
-        + "|(tel|travel|t[cdfghjklmnoprtvwz])"
-        + "|u[agksyz]"
-        + "|v[aceginu]"
-        + "|w[fs]"
-        + "|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
-        + "|y[etu]"
-        + "|z[amw])";
-
-    /**
-     *  Regular expression pattern to match all IANA top-level domains.
-     */
-    public static final Pattern TOP_LEVEL_DOMAIN =
-        Pattern.compile(TOP_LEVEL_DOMAIN_STR);
-
-    /**
-     *  Regular expression to match all IANA top-level domains for WEB_URL.
-     *  List accurate as of 2010/02/05.  List taken from:
-     *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
-     */
-    public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
-        "(?:"
-        + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
-        + "|(?:biz|b[abdefghijmnorstvwyz])"
-        + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
-        + "|d[ejkmoz]"
-        + "|(?:edu|e[cegrstu])"
-        + "|f[ijkmor]"
-        + "|(?:gov|g[abdefghilmnpqrstuwy])"
-        + "|h[kmnrtu]"
-        + "|(?:info|int|i[delmnoqrst])"
-        + "|(?:jobs|j[emop])"
-        + "|k[eghimnprwyz]"
-        + "|l[abcikrstuvy]"
-        + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
-        + "|(?:name|net|n[acefgilopruz])"
-        + "|(?:org|om)"
-        + "|(?:pro|p[aefghklmnrstwy])"
-        + "|qa"
-        + "|r[eosuw]"
-        + "|s[abcdeghijklmnortuvyz]"
-        + "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
-        + "|u[agksyz]"
-        + "|v[aceginu]"
-        + "|w[fs]"
-        + "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
-        + "|y[etu]"
-        + "|z[amw]))";
-
-    /**
-     * Good characters for Internationalized Resource Identifiers (IRI).
-     * This comprises most common used Unicode characters allowed in IRI
-     * as detailed in RFC 3987.
-     * Specifically, those two byte Unicode characters are not included.
-     */
-    public static final String GOOD_IRI_CHAR =
-        "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
-
-    /**
-     *  Regular expression pattern to match most part of RFC 3987
-     *  Internationalized URLs, aka IRIs.  Commonly used Unicode characters are
-     *  added.
-     */
-    public static final Pattern WEB_URL = Pattern.compile(
-        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
-        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
-        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
-        + "((?:(?:[" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]{0,64}\\.)+"   // named host
-        + TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL
-        + "|(?:(?:25[0-5]|2[0-4]" // or ip address
-        + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
-        + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
-        + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
-        + "|[1-9][0-9]|[0-9])))"
-        + "(?:\\:\\d{1,5})?)" // plus option port number
-        + "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
-        + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
-        + "(?:\\b|$)"); // and finally, a word boundary or end of
-                        // input.  This is to stop foo.sure from
-                        // matching as foo.su
-
-    public static final Pattern IP_ADDRESS
-        = Pattern.compile(
-            "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
-            + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
-            + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
-            + "|[1-9][0-9]|[0-9]))");
-
-    public static final Pattern DOMAIN_NAME
-        = Pattern.compile(
-            "(((([" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]*)*[" + GOOD_IRI_CHAR + "]\\.)+"
-            + TOP_LEVEL_DOMAIN + ")|"
-            + IP_ADDRESS + ")");
-
-    public static final Pattern EMAIL_ADDRESS
-        = Pattern.compile(
-            "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
-            "\\@" +
-            "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
-            "(" +
-                "\\." +
-                "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
-            ")+"
-        );
-
-    /**
-     * This pattern is intended for searching for things that look like they
-     * might be phone numbers in arbitrary text, not for validating whether
-     * something is in fact a phone number.  It will miss many things that
-     * are legitimate phone numbers.
-     * 
-     * <p> The pattern matches the following:
-     * <ul>
-     * <li>Optionally, a + sign followed immediately by one or more digits. Spaces, dots, or dashes
-     * may follow.
-     * <li>Optionally, sets of digits in parentheses, separated by spaces, dots, or dashes.
-     * <li>A string starting and ending with a digit, containing digits, spaces, dots, and/or dashes.
-     * </ul>
-     */
-    public static final Pattern PHONE
-        = Pattern.compile(                                  // sdd = space, dot, or dash
-                "(\\+[0-9]+[\\- \\.]*)?"                    // +<digits><sdd>*
-                + "(\\([0-9]+\\)[\\- \\.]*)?"               // (<digits>)<sdd>*
-                + "([0-9][0-9\\- \\.][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit> 
-
-    /**
-     *  Convenience method to take all of the non-null matching groups in a
-     *  regex Matcher and return them as a concatenated string.
-     *
-     *  @param matcher      The Matcher object from which grouped text will
-     *                      be extracted
-     *
-     *  @return             A String comprising all of the non-null matched
-     *                      groups concatenated together
-     */
-    public static final String concatGroups(Matcher matcher) {
-        StringBuilder b = new StringBuilder();
-        final int numGroups = matcher.groupCount();
-
-        for (int i = 1; i <= numGroups; i++) {
-            String s = matcher.group(i);
-
-            System.err.println("Group(" + i + ") : " + s);
-
-            if (s != null) {
-                b.append(s);
-            }
-        }
-
-        return b.toString();
-    }
-
-    /**
-     * Convenience method to return only the digits and plus signs
-     * in the matching string.
-     *
-     * @param matcher      The Matcher object from which digits and plus will
-     *                     be extracted
-     *
-     * @return             A String comprising all of the digits and plus in
-     *                     the match
-     */
-    public static final String digitsAndPlusOnly(Matcher matcher) {
-        StringBuilder buffer = new StringBuilder();
-        String matchingRegion = matcher.group();
-
-        for (int i = 0, size = matchingRegion.length(); i < size; i++) {
-            char character = matchingRegion.charAt(i);
-
-            if (character == '+' || Character.isDigit(character)) {
-                buffer.append(character);
-            }
-        }
-        return buffer.toString();
-    }
-
-    /**
-     * Do not create this static utility class.
-     */
-    private Patterns() {}
-}
diff --git a/common/java/com/android/common/XmlUtils.java b/common/java/com/android/common/XmlUtils.java
deleted file mode 100644
index dd57e49..0000000
--- a/common/java/com/android/common/XmlUtils.java
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * Copyright (C) 2006 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.common;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import android.util.Xml;
-
-/** {@hide} */
-public class XmlUtils
-{
-
-    public static void skipCurrentTag(XmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        int outerDepth = parser.getDepth();
-        int type;
-        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-               && (type != XmlPullParser.END_TAG
-                       || parser.getDepth() > outerDepth)) {
-        }
-    }
-
-    public static final int
-    convertValueToList(CharSequence value, String[] options, int defaultValue)
-    {
-        if (null != value) {
-            for (int i = 0; i < options.length; i++) {
-                if (value.equals(options[i]))
-                    return i;
-            }
-        }
-
-        return defaultValue;
-    }
-
-    public static final boolean
-    convertValueToBoolean(CharSequence value, boolean defaultValue)
-    {
-        boolean result = false;
-
-        if (null == value)
-            return defaultValue;
-
-        if (value.equals("1")
-        ||  value.equals("true")
-        ||  value.equals("TRUE"))
-            result = true;
-
-        return result;
-    }
-
-    public static final int
-    convertValueToInt(CharSequence charSeq, int defaultValue)
-    {
-        if (null == charSeq)
-            return defaultValue;
-
-        String nm = charSeq.toString();
-
-        // XXX This code is copied from Integer.decode() so we don't
-        // have to instantiate an Integer!
-
-        int value;
-        int sign = 1;
-        int index = 0;
-        int len = nm.length();
-        int base = 10;
-
-        if ('-' == nm.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == nm.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char    c = nm.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                base = 8;
-            }
-        }
-        else if ('#' == nm.charAt(index))
-        {
-            index++;
-            base = 16;
-        }
-
-        return Integer.parseInt(nm.substring(index), base) * sign;
-    }
-
-    public static final int
-    convertValueToUnsignedInt(String value, int defaultValue)
-    {
-        if (null == value)
-            return defaultValue;
-
-        return parseUnsignedIntAttribute(value);
-    }
-
-    public static final int
-    parseUnsignedIntAttribute(CharSequence charSeq)
-    {
-        String  value = charSeq.toString();
-
-        long    bits;
-        int     index = 0;
-        int     len = value.length();
-        int     base = 10;
-
-        if ('0' == value.charAt(index)) {
-            //  Quick check for zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char    c = value.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {     //  check for hex
-                index += 2;
-                base = 16;
-            } else {                        //  check for octal
-                index++;
-                base = 8;
-            }
-        } else if ('#' == value.charAt(index)) {
-            index++;
-            base = 16;
-        }
-
-        return (int) Long.parseLong(value.substring(index), base);
-    }
-
-    /**
-     * Flatten a Map into an output stream as XML.  The map can later be
-     * read back with readMapXml().
-     *
-     * @param val The map to be flattened.
-     * @param out Where to write the XML data.
-     *
-     * @see #writeMapXml(Map, String, XmlSerializer)
-     * @see #writeListXml
-     * @see #writeValueXml
-     * @see #readMapXml
-     */
-    public static final void writeMapXml(Map val, OutputStream out)
-            throws XmlPullParserException, java.io.IOException {
-        XmlSerializer serializer = new FastXmlSerializer();
-        serializer.setOutput(out, "utf-8");
-        serializer.startDocument(null, true);
-        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-        writeMapXml(val, null, serializer);
-        serializer.endDocument();
-    }
-
-    /**
-     * Flatten a List into an output stream as XML.  The list can later be
-     * read back with readListXml().
-     *
-     * @param val The list to be flattened.
-     * @param out Where to write the XML data.
-     *
-     * @see #writeListXml(List, String, XmlSerializer)
-     * @see #writeMapXml
-     * @see #writeValueXml
-     * @see #readListXml
-     */
-    public static final void writeListXml(List val, OutputStream out)
-    throws XmlPullParserException, java.io.IOException
-    {
-        XmlSerializer serializer = Xml.newSerializer();
-        serializer.setOutput(out, "utf-8");
-        serializer.startDocument(null, true);
-        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-        writeListXml(val, null, serializer);
-        serializer.endDocument();
-    }
-
-    /**
-     * Flatten a Map into an XmlSerializer.  The map can later be read back
-     * with readThisMapXml().
-     *
-     * @param val The map to be flattened.
-     * @param name Name attribute to include with this list's tag, or null for
-     *             none.
-     * @param out XmlSerializer to write the map into.
-     *
-     * @see #writeMapXml(Map, OutputStream)
-     * @see #writeListXml
-     * @see #writeValueXml
-     * @see #readMapXml
-     */
-    public static final void writeMapXml(Map val, String name, XmlSerializer out)
-    throws XmlPullParserException, java.io.IOException
-    {
-        if (val == null) {
-            out.startTag(null, "null");
-            out.endTag(null, "null");
-            return;
-        }
-
-        Set s = val.entrySet();
-        Iterator i = s.iterator();
-
-        out.startTag(null, "map");
-        if (name != null) {
-            out.attribute(null, "name", name);
-        }
-
-        while (i.hasNext()) {
-            Map.Entry e = (Map.Entry)i.next();
-            writeValueXml(e.getValue(), (String)e.getKey(), out);
-        }
-
-        out.endTag(null, "map");
-    }
-
-    /**
-     * Flatten a List into an XmlSerializer.  The list can later be read back
-     * with readThisListXml().
-     *
-     * @param val The list to be flattened.
-     * @param name Name attribute to include with this list's tag, or null for
-     *             none.
-     * @param out XmlSerializer to write the list into.
-     *
-     * @see #writeListXml(List, OutputStream)
-     * @see #writeMapXml
-     * @see #writeValueXml
-     * @see #readListXml
-     */
-    public static final void writeListXml(List val, String name, XmlSerializer out)
-    throws XmlPullParserException, java.io.IOException
-    {
-        if (val == null) {
-            out.startTag(null, "null");
-            out.endTag(null, "null");
-            return;
-        }
-
-        out.startTag(null, "list");
-        if (name != null) {
-            out.attribute(null, "name", name);
-        }
-
-        int N = val.size();
-        int i=0;
-        while (i < N) {
-            writeValueXml(val.get(i), null, out);
-            i++;
-        }
-
-        out.endTag(null, "list");
-    }
-
-    /**
-     * Flatten a byte[] into an XmlSerializer.  The list can later be read back
-     * with readThisByteArrayXml().
-     *
-     * @param val The byte array to be flattened.
-     * @param name Name attribute to include with this array's tag, or null for
-     *             none.
-     * @param out XmlSerializer to write the array into.
-     *
-     * @see #writeMapXml
-     * @see #writeValueXml
-     */
-    public static final void writeByteArrayXml(byte[] val, String name,
-            XmlSerializer out)
-            throws XmlPullParserException, java.io.IOException {
-
-        if (val == null) {
-            out.startTag(null, "null");
-            out.endTag(null, "null");
-            return;
-        }
-
-        out.startTag(null, "byte-array");
-        if (name != null) {
-            out.attribute(null, "name", name);
-        }
-
-        final int N = val.length;
-        out.attribute(null, "num", Integer.toString(N));
-
-        StringBuilder sb = new StringBuilder(val.length*2);
-        for (int i=0; i<N; i++) {
-            int b = val[i];
-            int h = b>>4;
-            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
-            h = b&0xff;
-            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
-        }
-
-        out.text(sb.toString());
-
-        out.endTag(null, "byte-array");
-    }
-
-    /**
-     * Flatten an int[] into an XmlSerializer.  The list can later be read back
-     * with readThisIntArrayXml().
-     *
-     * @param val The int array to be flattened.
-     * @param name Name attribute to include with this array's tag, or null for
-     *             none.
-     * @param out XmlSerializer to write the array into.
-     *
-     * @see #writeMapXml
-     * @see #writeValueXml
-     * @see #readThisIntArrayXml
-     */
-    public static final void writeIntArrayXml(int[] val, String name,
-            XmlSerializer out)
-            throws XmlPullParserException, java.io.IOException {
-
-        if (val == null) {
-            out.startTag(null, "null");
-            out.endTag(null, "null");
-            return;
-        }
-
-        out.startTag(null, "int-array");
-        if (name != null) {
-            out.attribute(null, "name", name);
-        }
-
-        final int N = val.length;
-        out.attribute(null, "num", Integer.toString(N));
-
-        for (int i=0; i<N; i++) {
-            out.startTag(null, "item");
-            out.attribute(null, "value", Integer.toString(val[i]));
-            out.endTag(null, "item");
-        }
-
-        out.endTag(null, "int-array");
-    }
-
-    /**
-     * Flatten an object's value into an XmlSerializer.  The value can later
-     * be read back with readThisValueXml().
-     *
-     * Currently supported value types are: null, String, Integer, Long,
-     * Float, Double Boolean, Map, List.
-     *
-     * @param v The object to be flattened.
-     * @param name Name attribute to include with this value's tag, or null
-     *             for none.
-     * @param out XmlSerializer to write the object into.
-     *
-     * @see #writeMapXml
-     * @see #writeListXml
-     * @see #readValueXml
-     */
-    public static final void writeValueXml(Object v, String name, XmlSerializer out)
-    throws XmlPullParserException, java.io.IOException
-    {
-        String typeStr;
-        if (v == null) {
-            out.startTag(null, "null");
-            if (name != null) {
-                out.attribute(null, "name", name);
-            }
-            out.endTag(null, "null");
-            return;
-        } else if (v instanceof String) {
-            out.startTag(null, "string");
-            if (name != null) {
-                out.attribute(null, "name", name);
-            }
-            out.text(v.toString());
-            out.endTag(null, "string");
-            return;
-        } else if (v instanceof Integer) {
-            typeStr = "int";
-        } else if (v instanceof Long) {
-            typeStr = "long";
-        } else if (v instanceof Float) {
-            typeStr = "float";
-        } else if (v instanceof Double) {
-            typeStr = "double";
-        } else if (v instanceof Boolean) {
-            typeStr = "boolean";
-        } else if (v instanceof byte[]) {
-            writeByteArrayXml((byte[])v, name, out);
-            return;
-        } else if (v instanceof int[]) {
-            writeIntArrayXml((int[])v, name, out);
-            return;
-        } else if (v instanceof Map) {
-            writeMapXml((Map)v, name, out);
-            return;
-        } else if (v instanceof List) {
-            writeListXml((List)v, name, out);
-            return;
-        } else if (v instanceof CharSequence) {
-            // XXX This is to allow us to at least write something if
-            // we encounter styled text...  but it means we will drop all
-            // of the styling information. :(
-            out.startTag(null, "string");
-            if (name != null) {
-                out.attribute(null, "name", name);
-            }
-            out.text(v.toString());
-            out.endTag(null, "string");
-            return;
-        } else {
-            throw new RuntimeException("writeValueXml: unable to write value " + v);
-        }
-
-        out.startTag(null, typeStr);
-        if (name != null) {
-            out.attribute(null, "name", name);
-        }
-        out.attribute(null, "value", v.toString());
-        out.endTag(null, typeStr);
-    }
-
-    /**
-     * Read a HashMap from an InputStream containing XML.  The stream can
-     * previously have been written by writeMapXml().
-     *
-     * @param in The InputStream from which to read.
-     *
-     * @return HashMap The resulting map.
-     *
-     * @see #readListXml
-     * @see #readValueXml
-     * @see #readThisMapXml
-     * #see #writeMapXml
-     */
-    public static final HashMap readMapXml(InputStream in)
-    throws XmlPullParserException, java.io.IOException
-    {
-        XmlPullParser   parser = Xml.newPullParser();
-        parser.setInput(in, null);
-        return (HashMap)readValueXml(parser, new String[1]);
-    }
-
-    /**
-     * Read an ArrayList from an InputStream containing XML.  The stream can
-     * previously have been written by writeListXml().
-     *
-     * @param in The InputStream from which to read.
-     *
-     * @return HashMap The resulting list.
-     *
-     * @see #readMapXml
-     * @see #readValueXml
-     * @see #readThisListXml
-     * @see #writeListXml
-     */
-    public static final ArrayList readListXml(InputStream in)
-    throws XmlPullParserException, java.io.IOException
-    {
-        XmlPullParser   parser = Xml.newPullParser();
-        parser.setInput(in, null);
-        return (ArrayList)readValueXml(parser, new String[1]);
-    }
-
-    /**
-     * Read a HashMap object from an XmlPullParser.  The XML data could
-     * previously have been generated by writeMapXml().  The XmlPullParser
-     * must be positioned <em>after</em> the tag that begins the map.
-     *
-     * @param parser The XmlPullParser from which to read the map data.
-     * @param endTag Name of the tag that will end the map, usually "map".
-     * @param name An array of one string, used to return the name attribute
-     *             of the map's tag.
-     *
-     * @return HashMap The newly generated map.
-     *
-     * @see #readMapXml
-     */
-    public static final HashMap readThisMapXml(XmlPullParser parser, String endTag, String[] name)
-    throws XmlPullParserException, java.io.IOException
-    {
-        HashMap map = new HashMap();
-
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == parser.START_TAG) {
-                Object val = readThisValueXml(parser, name);
-                if (name[0] != null) {
-                    //System.out.println("Adding to map: " + name + " -> " + val);
-                    map.put(name[0], val);
-                } else {
-                    throw new XmlPullParserException(
-                        "Map value without name attribute: " + parser.getName());
-                }
-            } else if (eventType == parser.END_TAG) {
-                if (parser.getName().equals(endTag)) {
-                    return map;
-                }
-                throw new XmlPullParserException(
-                    "Expected " + endTag + " end tag at: " + parser.getName());
-            }
-            eventType = parser.next();
-        } while (eventType != parser.END_DOCUMENT);
-
-        throw new XmlPullParserException(
-            "Document ended before " + endTag + " end tag");
-    }
-
-    /**
-     * Read an ArrayList object from an XmlPullParser.  The XML data could
-     * previously have been generated by writeListXml().  The XmlPullParser
-     * must be positioned <em>after</em> the tag that begins the list.
-     *
-     * @param parser The XmlPullParser from which to read the list data.
-     * @param endTag Name of the tag that will end the list, usually "list".
-     * @param name An array of one string, used to return the name attribute
-     *             of the list's tag.
-     *
-     * @return HashMap The newly generated list.
-     *
-     * @see #readListXml
-     */
-    public static final ArrayList readThisListXml(XmlPullParser parser, String endTag, String[] name)
-    throws XmlPullParserException, java.io.IOException
-    {
-        ArrayList list = new ArrayList();
-
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == parser.START_TAG) {
-                Object val = readThisValueXml(parser, name);
-                list.add(val);
-                //System.out.println("Adding to list: " + val);
-            } else if (eventType == parser.END_TAG) {
-                if (parser.getName().equals(endTag)) {
-                    return list;
-                }
-                throw new XmlPullParserException(
-                    "Expected " + endTag + " end tag at: " + parser.getName());
-            }
-            eventType = parser.next();
-        } while (eventType != parser.END_DOCUMENT);
-
-        throw new XmlPullParserException(
-            "Document ended before " + endTag + " end tag");
-    }
-
-    /**
-     * Read an int[] object from an XmlPullParser.  The XML data could
-     * previously have been generated by writeIntArrayXml().  The XmlPullParser
-     * must be positioned <em>after</em> the tag that begins the list.
-     *
-     * @param parser The XmlPullParser from which to read the list data.
-     * @param endTag Name of the tag that will end the list, usually "list".
-     * @param name An array of one string, used to return the name attribute
-     *             of the list's tag.
-     *
-     * @return Returns a newly generated int[].
-     *
-     * @see #readListXml
-     */
-    public static final int[] readThisIntArrayXml(XmlPullParser parser,
-            String endTag, String[] name)
-            throws XmlPullParserException, java.io.IOException {
-
-        int num;
-        try {
-            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
-        } catch (NullPointerException e) {
-            throw new XmlPullParserException(
-                    "Need num attribute in byte-array");
-        } catch (NumberFormatException e) {
-            throw new XmlPullParserException(
-                    "Not a number in num attribute in byte-array");
-        }
-
-        int[] array = new int[num];
-        int i = 0;
-
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == parser.START_TAG) {
-                if (parser.getName().equals("item")) {
-                    try {
-                        array[i] = Integer.parseInt(
-                                parser.getAttributeValue(null, "value"));
-                    } catch (NullPointerException e) {
-                        throw new XmlPullParserException(
-                                "Need value attribute in item");
-                    } catch (NumberFormatException e) {
-                        throw new XmlPullParserException(
-                                "Not a number in value attribute in item");
-                    }
-                } else {
-                    throw new XmlPullParserException(
-                            "Expected item tag at: " + parser.getName());
-                }
-            } else if (eventType == parser.END_TAG) {
-                if (parser.getName().equals(endTag)) {
-                    return array;
-                } else if (parser.getName().equals("item")) {
-                    i++;
-                } else {
-                    throw new XmlPullParserException(
-                        "Expected " + endTag + " end tag at: "
-                        + parser.getName());
-                }
-            }
-            eventType = parser.next();
-        } while (eventType != parser.END_DOCUMENT);
-
-        throw new XmlPullParserException(
-            "Document ended before " + endTag + " end tag");
-    }
-
-    /**
-     * Read a flattened object from an XmlPullParser.  The XML data could
-     * previously have been written with writeMapXml(), writeListXml(), or
-     * writeValueXml().  The XmlPullParser must be positioned <em>at</em> the
-     * tag that defines the value.
-     *
-     * @param parser The XmlPullParser from which to read the object.
-     * @param name An array of one string, used to return the name attribute
-     *             of the value's tag.
-     *
-     * @return Object The newly generated value object.
-     *
-     * @see #readMapXml
-     * @see #readListXml
-     * @see #writeValueXml
-     */
-    public static final Object readValueXml(XmlPullParser parser, String[] name)
-    throws XmlPullParserException, java.io.IOException
-    {
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == parser.START_TAG) {
-                return readThisValueXml(parser, name);
-            } else if (eventType == parser.END_TAG) {
-                throw new XmlPullParserException(
-                    "Unexpected end tag at: " + parser.getName());
-            } else if (eventType == parser.TEXT) {
-                throw new XmlPullParserException(
-                    "Unexpected text: " + parser.getText());
-            }
-            eventType = parser.next();
-        } while (eventType != parser.END_DOCUMENT);
-
-        throw new XmlPullParserException(
-            "Unexpected end of document");
-    }
-
-    private static final Object readThisValueXml(XmlPullParser parser, String[] name)
-    throws XmlPullParserException, java.io.IOException
-    {
-        final String valueName = parser.getAttributeValue(null, "name");
-        final String tagName = parser.getName();
-
-        //System.out.println("Reading this value tag: " + tagName + ", name=" + valueName);
-
-        Object res;
-
-        if (tagName.equals("null")) {
-            res = null;
-        } else if (tagName.equals("string")) {
-            String value = "";
-            int eventType;
-            while ((eventType = parser.next()) != parser.END_DOCUMENT) {
-                if (eventType == parser.END_TAG) {
-                    if (parser.getName().equals("string")) {
-                        name[0] = valueName;
-                        //System.out.println("Returning value for " + valueName + ": " + value);
-                        return value;
-                    }
-                    throw new XmlPullParserException(
-                        "Unexpected end tag in <string>: " + parser.getName());
-                } else if (eventType == parser.TEXT) {
-                    value += parser.getText();
-                } else if (eventType == parser.START_TAG) {
-                    throw new XmlPullParserException(
-                        "Unexpected start tag in <string>: " + parser.getName());
-                }
-            }
-            throw new XmlPullParserException(
-                "Unexpected end of document in <string>");
-        } else if (tagName.equals("int")) {
-            res = Integer.parseInt(parser.getAttributeValue(null, "value"));
-        } else if (tagName.equals("long")) {
-            res = Long.valueOf(parser.getAttributeValue(null, "value"));
-        } else if (tagName.equals("float")) {
-            res = new Float(parser.getAttributeValue(null, "value"));
-        } else if (tagName.equals("double")) {
-            res = new Double(parser.getAttributeValue(null, "value"));
-        } else if (tagName.equals("boolean")) {
-            res = Boolean.valueOf(parser.getAttributeValue(null, "value"));
-        } else if (tagName.equals("int-array")) {
-            parser.next();
-            res = readThisIntArrayXml(parser, "int-array", name);
-            name[0] = valueName;
-            //System.out.println("Returning value for " + valueName + ": " + res);
-            return res;
-        } else if (tagName.equals("map")) {
-            parser.next();
-            res = readThisMapXml(parser, "map", name);
-            name[0] = valueName;
-            //System.out.println("Returning value for " + valueName + ": " + res);
-            return res;
-        } else if (tagName.equals("list")) {
-            parser.next();
-            res = readThisListXml(parser, "list", name);
-            name[0] = valueName;
-            //System.out.println("Returning value for " + valueName + ": " + res);
-            return res;
-        } else {
-            throw new XmlPullParserException(
-                "Unknown tag: " + tagName);
-        }
-
-        // Skip through to end tag.
-        int eventType;
-        while ((eventType = parser.next()) != parser.END_DOCUMENT) {
-            if (eventType == parser.END_TAG) {
-                if (parser.getName().equals(tagName)) {
-                    name[0] = valueName;
-                    //System.out.println("Returning value for " + valueName + ": " + res);
-                    return res;
-                }
-                throw new XmlPullParserException(
-                    "Unexpected end tag in <" + tagName + ">: " + parser.getName());
-            } else if (eventType == parser.TEXT) {
-                throw new XmlPullParserException(
-                "Unexpected text in <" + tagName + ">: " + parser.getName());
-            } else if (eventType == parser.START_TAG) {
-                throw new XmlPullParserException(
-                    "Unexpected start tag in <" + tagName + ">: " + parser.getName());
-            }
-        }
-        throw new XmlPullParserException(
-            "Unexpected end of document in <" + tagName + ">");
-    }
-
-    public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
-    {
-        int type;
-        while ((type=parser.next()) != parser.START_TAG
-                   && type != parser.END_DOCUMENT) {
-            ;
-        }
-
-        if (type != parser.START_TAG) {
-            throw new XmlPullParserException("No start tag found");
-        }
-
-        if (!parser.getName().equals(firstElementName)) {
-            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
-                    ", expected " + firstElementName);
-        }
-    }
-
-    public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
-    {
-        int type;
-        while ((type=parser.next()) != parser.START_TAG
-                   && type != parser.END_DOCUMENT) {
-            ;
-        }
-    }
-}
diff --git a/common/java/com/android/common/speech/Recognition.java b/common/java/com/android/common/speech/Recognition.java
index 6f164a9..a79a19b 100644
--- a/common/java/com/android/common/speech/Recognition.java
+++ b/common/java/com/android/common/speech/Recognition.java
@@ -19,18 +19,42 @@
 /**
  * Utilities for voice recognition implementations.
  *
- * @see android.app.RecognitionService
+ * @see android.speech.RecognitionService
+ * @see android.speech.RecognizerIntent
  */
 public class Recognition {
-
+    
     /**
-     * The extra key used in an intent to the speech recognizer for voice search. Not
-     * generally to be used by developers. The system search dialog uses this, for example,
-     * to set a calling package for identification by a voice search API. If this extra
-     * is set by anyone but the system process, it should be overridden by the voice search
-     * implementation.
+     * The key to the extra in the Bundle returned by
+     * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS
+     * which is an ArrayList of CharSequences which are hints that can be shown to
+     * the user for voice actions currently supported by voice search for the user's current
+     * language preference for voice search (i.e., the one defined in the extra
+     * android.speech.RecognizerIntent#EXTRA_LANGUAGE_PREFERENCE).
+     *
+     * If this is paired with EXTRA_HINT_CONTEXT, should return a set of hints that are
+     * appropriate for the provided context.
+     *
+     * The CharSequences are SpannedStrings and will contain segments wrapped in
+     * <annotation action="true"></annotation>. This is to indicate the section of the text
+     * which represents the voice action, to be highlighted in the UI if so desired.
      */
-    public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+    public static final String EXTRA_HINT_STRINGS = "android.speech.extra.HINT_STRINGS";
+    
+    /**
+     * The key to an extra to be included in the request intent for
+     * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS.
+     * Should be an int of one of the values defined below. If an
+     * unknown int value is provided, it should be ignored.
+     */
+    public static final String EXTRA_HINT_CONTEXT = "android.speech.extra.HINT_CONTEXT";
+    
+    /**
+     * A set of values for EXTRA_HINT_CONTEXT.
+     */
+    public static final int HINT_CONTEXT_UNKNOWN = 0;
+    public static final int HINT_CONTEXT_VOICE_SEARCH_HELP = 1;
+    public static final int HINT_CONTEXT_CAR_HOME = 2;
 
     private Recognition() { }   // don't instantiate
 }
diff --git a/common/tests/res/raw/alt_ip_only.crt b/common/tests/res/raw/alt_ip_only.crt
deleted file mode 100644
index 3ac9f5a..0000000
--- a/common/tests/res/raw/alt_ip_only.crt
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICsjCCAZqgAwIBAgIJALrC37YAXFIeMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV
-BAYTAkpQMCAXDTEwMDExMjIxMzk0NloYDzIwNjQxMDE1MjEzOTQ2WjANMQswCQYD
-VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr8s/4Abpby
-IYks5YCJE2nbWH7kj6XbwnRzsVP9RVC33bPoQ1M+2ZY24HqkigjQS/HEXR0s0bYh
-dewNUnTj1uGyGs6cYzsbu7x114vmVYqjxUo3hKjwfYiPeF6f3IE1vpLI7I2G32gq
-Zwm9c1/vXNHIdWQxCpFcuPA8P3YGfoApFX4pQPFplBUNAQqnjdmA68cbxxMC+1F3
-mX42D7iIEVwyVpah5HjyxjIZQlf3X7QBj0bCmkL+ibIHTALrkNNwNM6i4xzYLz/5
-14GkN9ncHY87eSOk6r53ptER6mQMhCe9qPRjSHnpWTTyj6IXTaYe+dDQw657B80w
-cSHL7Ed25zUCAwEAAaMTMBEwDwYDVR0RBAgwBocEwKgKATANBgkqhkiG9w0BAQUF
-AAOCAQEAgrwrtOWZT3fbi1AafpGaAiOBWSJqYqRhtQy0AfiZBxv1U0XaYqmZmpnq
-DVAqr0NkljowD28NBrxIFO5gBNum2ZOPDl2/5vjFn+IirUCJ9u9wS7zYkTCW2lQR
-xE7Ic3mfWv7wUbKDfjlWqP1IDHUxwkrBTAl+HnwOPiaKKk1ttwcrgS8AHlqASe03
-mlwnvJ+Stk54IneRaegL0L93sNAy63RZqnPCTxGz7eHcFwX8Jdr4sbxTxQqV6pIc
-WPjHQcWfpkFzAF5wyOq0kveVfx0g5xPhOVDd+U+q7WastbXICpCoHp9FxISmZVik
-sAyifp8agkYdzaSh55fFmKXlFnRsQw==
------END CERTIFICATE-----
diff --git a/common/tests/res/raw/subject_alt_only.crt b/common/tests/res/raw/subject_alt_only.crt
deleted file mode 100644
index d5808fb..0000000
--- a/common/tests/res/raw/subject_alt_only.crt
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICvTCCAaWgAwIBAgIJALbA0TZk2YmNMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV
-BAYTAkpQMCAXDTEwMDExMjIwNTg1NFoYDzIwNjQxMDE1MjA1ODU0WjANMQswCQYD
-VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMEg6acVC9V4
-xNGoLNVLPbqBc8IvMvcsc88dF6MW3d9VagX3aeWU8c79tI/KOV/1AOakH7WYxw/w
-yD8aOX7+9BK1Hu0qKKKbSM+ycqaMthXd6xytrNDsIx5WiGUz8zTko0Gk3orIR7p7
-rPcNzB/zwtESkscqPv85aEn7S/yClNkzLfEzm3CtaYOc0tfhBMyzi/ipXzGMxUmx
-PvOLr3v/Oz5pZEQw7Kxlm4+tAtn7bJlHziQ1UW4WPIy+T3hySBEpODFiqZi7Ok3X
-Zjxdii62fgo5B2Ee7q5Amo0mUIwcQTDjJ2CLAqzYnSh3tpiPJGjEIjmRyCoMQ1bx
-7D+y7nSPIq8CAwEAAaMeMBwwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29tMA0G
-CSqGSIb3DQEBBQUAA4IBAQBsGEh+nHc0l9FJTzWqvG3qs7i6XoJZdtThCDx4HjKJ
-8GMrJtreNN4JvIxn7KC+alVbnILjzCRO+c3rsnpxKBi5cp2imjuw5Kf/x2Seimb9
-UvZbaJvBVOzy4Q1IGef9bLy3wZzy2/WfBFyvPTAkgkRaX7LN2jnYOYVhNoNFrwqe
-EWxkA6fzrpyseUEFeGFFjGxRSRCDcQ25Eq6d9rkC1x21zNtt4QwZBO0wHrTy155M
-JPRynf9244Pn0Sr/wsnmdsTRFIFYynrc51hQ7DkwbUxpcaewkZzilru/SwZ3+pPT
-9JSqm5hJ1pg5WDlPkW7c/1VA0/141N52Q8MIU+2ZpuOj
------END CERTIFICATE-----
diff --git a/common/tests/res/raw/subject_only.crt b/common/tests/res/raw/subject_only.crt
deleted file mode 100644
index 11b34e7..0000000
--- a/common/tests/res/raw/subject_only.crt
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC0TCCAbmgAwIBAgIJANCQbJPPw31SMA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV
-BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjA1ODE4
-WhgPMjA2NDEwMTUyMDU4MThaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu
-ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDsdUJk
-4KxADA3vlDHxNbyC27Ozw4yiSVzPTHUct471YmdDRW3orO2P5a5hRnUGV70gjH9X
-MU4oeOdWYAgXB9pxfLyr6621k1+uNrmaZtzp0ECH9twcwxNJJFDZsN7o9vt7V6Ej
-NN9weeqDr/aeQXo07a12vyVfR6jWO8jHB0e4aemwZNoYjNvM69fivQTse2ZoRVfj
-eSHhjRTX6I8ry4a31Hwt+fT1QiWWNN6o7+WOtpJAhX3eg4smhSD1svi2kOT8tdUe
-NS4hWlmXmumU9G4tI8PBurcLNTm7PB2lUlbn/IV18WavqKE/Uy/1WgAx+a1EJNdp
-i07AG1PsqaONKkf1AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAJrNsuL7fZZNC8gL
-BdePJ7DYW2e7mXANU3bCBe2BZqmXKQxKwibZnEsqA+yMLqcSd8uxISlyHY2tw9wT
-4wB9KPIttfNLbwn/rk+MbOTHpvyF60d9WhJJVUkPBl8D4VuPSl+VnlA54kU9dtZN
-+ZYdxYbNtSsI/Flz9SCoOV79W9GhN+uYJhv6RwyIMIHeMpZpyX1xSUVx5dZlmerQ
-WAUvghDH3fFRt2ZdnA4OXoKkTAaM3Pv7PUMsnah8bux6MQi0AuLMWFWOI1H34koH
-rs2oQLwOLnuifH52ey9+tJguabo+brlYYigAuWWFEzJfBzikDkIwnE/L7wlrypIk
-taXDWI4=
------END CERTIFICATE-----
diff --git a/common/tests/res/raw/subject_with_alt_names.crt b/common/tests/res/raw/subject_with_alt_names.crt
deleted file mode 100644
index 6963c7e..0000000
--- a/common/tests/res/raw/subject_with_alt_names.crt
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDBDCCAeygAwIBAgIJALv14qjcuhw9MA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV
-BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjA1OTM4
-WhgPMjA2NDEwMTUyMDU5MzhaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu
-ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCiTVgU
-kBO9KNYZZLmiPR0eBrk8u61CLnm35BGKW8EFpDaINLbbIFIQvqOMekURON/N+xFY
-D8roo7aFZVuHWAUqFcOJ4e6NmviK5qocLihtzAexsw4f4AzZxM3A8kcLlWLyAt7e
-EVLxhcMHogY7GaF6q+33Z8p+zp6x3tj07mwyPrriCLse2PeRsRunZl/fp/VvRlr6
-YbC7CbRrhnIv5nqohs8BsbBiiFpxQftsMQmiXhY2LUzqY2RXUIOw24fHjoQkHTL2
-4z5nUM3b6ueQe+CBnobUS6fzK/36Nct4dRpev9i/ORdRLuIDKJ+QR16G1V/BJYBR
-dAK+3iXvg6z8vP1XAgMBAAGjMTAvMC0GA1UdEQQmMCSCEHd3dzIuZXhhbXBsZS5j
-b22CEHd3dzMuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAJQNf38uXm3h
-0vsF+Yd6/HqM48Su7tWnTDAfTXnQZZkzjzITq3JXzquMXICktAVN2cLnT9zPfRAE
-8V8A3BNO5zXiR5W3o/mJP5HQ3/WxpzBGM2N+YmDCJyBoQrIVaAZaXAZUaBBvn5A+
-kEVfGWquwIFuvA67xegbJOCRLD4eUzRdNsn5+NFiakWO1tkFqEzqyQ0PNPviRjgu
-z9NxdPvd1JQOhydkucsPKJzlEBbGyL5QL/Jkot3Qy+FOeuNzgQUfAGtQgzRrsZDK
-hrTVypLSoRXuTB2aWilu4p6aNh84xTdyqo2avtNr2MiQMZIcdamBq8LdBIAShFXI
-h5G2eVGXH/Y=
------END CERTIFICATE-----
diff --git a/common/tests/res/raw/subject_with_wild_alt_name.crt b/common/tests/res/raw/subject_with_wild_alt_name.crt
deleted file mode 100644
index 19b1174..0000000
--- a/common/tests/res/raw/subject_with_wild_alt_name.crt
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC8DCCAdigAwIBAgIJAL/oWJ64VAdXMA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV
-BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjEwMDAx
-WhgPMjA2NDEwMTUyMTAwMDFaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu
-ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbx1QB
-92iea7VybLYICA4MX4LWipYrRsgXUXQrcIQ3YLTQ9rH0VwScrHL4O4JDxgXCQnR+
-4VOzD42q1KXHJAqzqGUYCNPyvZEzkGCnQ4FBIUEmxZd5SNEefJVH3Z6GizYJomTh
-p78yDcoqymD9umxRC2cWFu8GscfFGMVyhsqLlOofu7UWOs22mkXPo43jDx+VOAoV
-n48YP3P57a2Eo0gcd4zVL00y62VegqBO/1LW38aTS7teiCBFc1TkNYa5I40yN9lP
-rB9ICHYQWyzf/7OxU9iauEK2w6DmSsQoLs9JzEhgeNZddkcc77ciSUCo2Hx0VpOJ
-BFyf2rbryJeAk+FDAgMBAAGjHTAbMBkGA1UdEQQSMBCCDiouZXhhbXBsZTIuY29t
-MA0GCSqGSIb3DQEBBQUAA4IBAQA2a14pRL+4laJ8sscQlucaDB/oSdb0cwhk4IkE
-kKl/ZKr6rKwPZ81sJRgzvI4imLbUAKt4AJHdpI9cIQUq1gw9bzil7LKwmFtFSPmC
-MYb1iadaYrvp7RE4yXrWCcSbU0hup9JQLHTrHLlqLtRuU48NHMvWYThBcS9Q/hQp
-nJ/JxYy3am99MHALWLAfuRxQXhE4C5utDmBwI2KD6A8SA30s+CnuegmkYScuSqBu
-Y3R0HZvKzNIU3pwAm69HCJoG+/9MZEIDJb0WJc5UygxDT45XE9zQMQe4dBOTaNXT
-+ntgaB62kE10HzrzpqXAgoAWxWK4RzFcUpBWw9qYq9xOCewJ
------END CERTIFICATE-----
diff --git a/common/tests/res/raw/wild_alt_name_only.crt b/common/tests/res/raw/wild_alt_name_only.crt
deleted file mode 100644
index fafdebf..0000000
--- a/common/tests/res/raw/wild_alt_name_only.crt
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICuzCCAaOgAwIBAgIJAP82tgcvmAGxMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV
-BAYTAkpQMCAXDTEwMDExMjIxMDAyN1oYDzIwNjQxMDE1MjEwMDI3WjANMQswCQYD
-VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs528EQbcB1
-x4BwxthQBZrgDJzoO7KPV3dhGYoeP8EnRjapZm+T/sj9P/O4HvfxjnB+fsjYSdmE
-WWUtnFrP7wtG9DUC748Ea2PMV8WFhOG58dqBNIko5XzkHB7SxkNZD5S/0KQYMGLr
-rchDsDlmsEf2Qb6qiqpNEU70aSkExZJcH+B9nWdeBpsVFu7wtezwSWEc2NUa2bhW
-gcXQ/aafwHZ4o2PyGwy0sgS/UifqO9tEllC2tPleSNJOmYsVudv5Bz4Q0GG38BSz
-Pc0IcOoln0ZWpXbGr03V2vlXWCwzaFAl3I1T3O7YVqDiaSWoP+d0tHZzmw8aJLXd
-B+KaUUGxRPsCAwEAAaMcMBowGAYDVR0RBBEwD4INKi5leGFtcGxlLmNvbTANBgkq
-hkiG9w0BAQUFAAOCAQEAJbVan4QgJ0cvpJnK9UWIVJNC+UbP87RC5go2fQiTnmGv
-prOrIuMqz1+vGcpIheLTLctJRHPoadXq0+UbQEIaU3pQbY6C4nNdfl+hcvmJeqrt
-kOCcvmIamO68iNvTSeszuHuu4O38PefrW2Xd0nn7bjFZrzBzHFhTudmnqNliP3ue
-KKQpqkUt5lCytnH8V/u/UCWdvVx5LnUa2XFGVLi3ongBIojW5fvF+yxn9ADqxdrI
-va++ow5r1VxQXFJc0ZPzsDo+6TlktoDHaRQJGMqQomqHWT4i7F5UZgf6BHGfEUPU
-qep+GsF3QRHSBtpObWkVDZNFvky3a1iZ2q25+hFIqQ==
------END CERTIFICATE-----
diff --git a/common/tests/src/com/android/common/DNParserTest.java b/common/tests/src/com/android/common/DNParserTest.java
deleted file mode 100644
index 34b140a..0000000
--- a/common/tests/src/com/android/common/DNParserTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.common;
-
-import javax.security.auth.x500.X500Principal;
-
-import junit.framework.TestCase;
-
-public class DNParserTest extends TestCase {
-    public void testFind() {
-        checkFind("", "cn", null);
-        checkFind("ou=xxx", "cn", null);
-        checkFind("ou=xxx,cn=xxx", "cn", "xxx");
-        checkFind("ou=xxx+cn=yyy,cn=zzz+cn=abc", "cn", "yyy");
-        checkFind("2.5.4.3=a,ou=xxx", "cn", "a"); // OID
-        checkFind("cn=a,cn=b", "cn", "a");
-        checkFind("ou=Cc,ou=Bb,ou=Aa", "ou", "Cc");
-        checkFind("cn=imap.gmail.com", "cn", "imap.gmail.com");
-
-        // Quoted string (see http://www.ietf.org/rfc/rfc2253.txt)
-        checkFind("o=\"\\\" a ,=<>#;\"", "o", "\" a ,=<>#;");
-        checkFind("o=abc\\,def", "o", "abc,def");
-
-        // UTF-8 (example in rfc 2253)
-        checkFind("cn=Lu\\C4\\8Di\\C4\\87", "cn", "\u004c\u0075\u010d\u0069\u0107");
-
-        // whitespaces
-        checkFind("ou=a, o=  a  b  ,cn=x", "o", "a  b");
-        checkFind("o=\"  a  b  \" ,cn=x", "o", "  a  b  ");
-    }
-
-    private void checkFind(String dn, String attrType, String expected) {
-        String actual = new DNParser(new X500Principal(dn)).find(attrType);
-        assertEquals("dn:" + dn + "  attr:" + attrType, expected, actual);
-    }
-}
diff --git a/common/tests/src/com/android/common/DomainNameValidatorTest.java b/common/tests/src/com/android/common/DomainNameValidatorTest.java
deleted file mode 100644
index b825be4..0000000
--- a/common/tests/src/com/android/common/DomainNameValidatorTest.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.common;
-
-import com.android.common.tests.R;
-
-import android.test.AndroidTestCase;
-
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import javax.security.auth.x500.X500Principal;
-
-public class DomainNameValidatorTest extends AndroidTestCase {
-    private static final int ALT_UNKNOWN = 0;
-    private static final int ALT_DNS_NAME = 2;
-    private static final int ALT_IPA_NAME = 7;
-
-    /**
-     * Tests {@link DomainNameValidator#match}, using a simple {@link X509Certificate}
-     * implementation.
-     */
-    public void testMatch() {
-        checkMatch("11", new StubX509Certificate("cn=imap.g.com"), "imap.g.com", true);
-        checkMatch("12", new StubX509Certificate("cn=imap2.g.com"), "imap.g.com", false);
-        checkMatch("13", new StubX509Certificate("cn=sub.imap.g.com"), "imap.g.com", false);
-
-        // If a subjectAltName extension of type dNSName is present, that MUST
-        // be used as the identity
-        checkMatch("21", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com")
-                , "imap.g.com", false);
-        checkMatch("22", new StubX509Certificate("cn=imap.g.com") // This cn should be ignored
-                .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com")
-                , "imap.g.com", false);
-        checkMatch("23", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
-                , "imap.g.com", true);
-
-        // With wildcards
-        checkMatch("24", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "*.g.com")
-                , "imap.g.com", true);
-
-        // host name is ip address
-        checkMatch("31", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
-                , "1.2.3.4", true);
-        checkMatch("32", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
-                , "1.2.3.5", false);
-        checkMatch("32", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "192.168.100.1")
-                , "192.168.100.1", true);
-
-        // Has unknown subject alternative names
-        checkMatch("41", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
-                .addSubjectAlternativeName(ALT_UNKNOWN,  "random string 2")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
-                , "imap.g.com", true);
-
-        checkMatch("42", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
-                , "2.33.44.55", true);
-
-        checkMatch("43", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
-                , "g.com", false);
-
-        checkMatch("44", new StubX509Certificate("")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
-                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
-                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
-                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
-                , "2.33.44.1", false);
-    }
-
-    private void checkMatch(String message, X509Certificate certificate, String thisDomain,
-            boolean expected) {
-        Boolean actual = DomainNameValidator.match(certificate, thisDomain);
-        assertEquals(message, (Object) expected, (Object) actual);
-    }
-
-    /**
-     * Tests {@link DomainNameValidator#matchDns}
-     */
-    public void testMatchDns() {
-        checkMatchDns("11", "a.b.c.d", "a.b.c.d", true);
-        checkMatchDns("12", "a.b.c.d", "*.b.c.d", true);
-        checkMatchDns("13", "b.c.d", "*.b.c.d", true);
-        checkMatchDns("14", "b.c.d", "b*.c.d", true);
-
-        checkMatchDns("15", "a.b.c.d", "*.*.c.d", false);
-        checkMatchDns("16", "a.b.c.d", "*.c.d", false);
-
-        checkMatchDns("21", "imap.google.com", "imap.google.com", true);
-        checkMatchDns("22", "imap2.google.com", "imap.google.com", false);
-        checkMatchDns("23", "imap.google.com", "*.google.com", true);
-        checkMatchDns("24", "imap2.google.com", "*.google.com", true);
-        checkMatchDns("25", "imap.google.com", "*.googl.com", false);
-        checkMatchDns("26", "imap2.google2.com", "*.google3.com", false);
-        checkMatchDns("27", "imap.google.com", "ima*.google.com", true);
-        checkMatchDns("28", "imap.google.com", "imap*.google.com", true);
-        checkMatchDns("29", "imap.google.com", "*.imap.google.com", true);
-
-        checkMatchDns("41", "imap.google.com", "a*.google.com", false);
-        checkMatchDns("42", "imap.google.com", "ix*.google.com", false);
-
-        checkMatchDns("51", "imap.google.com", "iMap.Google.Com", true);
-    }
-
-    private void checkMatchDns(String message, String thisDomain, String thatDomain,
-            boolean expected) {
-        boolean actual = DomainNameValidator.matchDns(thisDomain, thatDomain);
-        assertEquals(message, expected, actual);
-    }
-
-    /**
-     * Test {@link DomainNameValidator#match} with actual certificates.
-     */
-    public void testWithActualCert() throws Exception {
-        // subject_only
-        //
-        // subject: C=JP, CN=www.example.com
-        // subject alt names: n/a
-        checkWithActualCert("11", R.raw.subject_only, "www.example.com", true);
-        checkWithActualCert("12", R.raw.subject_only, "www2.example.com", false);
-
-        // subject_alt_only
-        //
-        // subject: C=JP (no CN)
-        // subject alt names: DNS:www.example.com
-        checkWithActualCert("21", R.raw.subject_alt_only, "www.example.com", true);
-        checkWithActualCert("22", R.raw.subject_alt_only, "www2.example.com", false);
-
-        // subject_with_alt_names
-        //
-        // subject: C=JP, CN=www.example.com
-        // subject alt names: DNS:www2.example.com, DNS:www3.example.com
-        // * Subject should be ignored, because it has subject alt names.
-        checkWithActualCert("31", R.raw.subject_with_alt_names, "www.example.com", false);
-        checkWithActualCert("32", R.raw.subject_with_alt_names, "www2.example.com", true);
-        checkWithActualCert("33", R.raw.subject_with_alt_names, "www3.example.com", true);
-        checkWithActualCert("34", R.raw.subject_with_alt_names, "www4.example.com", false);
-
-        // subject_with_wild_alt_name
-        //
-        // subject: C=JP, CN=www.example.com
-        // subject alt names: DNS:*.example2.com
-        // * Subject should be ignored, because it has subject alt names.
-        checkWithActualCert("41", R.raw.subject_with_wild_alt_name, "www.example.com", false);
-        checkWithActualCert("42", R.raw.subject_with_wild_alt_name, "www2.example.com", false);
-        checkWithActualCert("43", R.raw.subject_with_wild_alt_name, "www.example2.com", true);
-        checkWithActualCert("44", R.raw.subject_with_wild_alt_name, "abc.example2.com", true);
-        checkWithActualCert("45", R.raw.subject_with_wild_alt_name, "www.example3.com", false);
-
-        // wild_alt_name_only
-        //
-        // subject: C=JP
-        // subject alt names: DNS:*.example.com
-        checkWithActualCert("51", R.raw.wild_alt_name_only, "www.example.com", true);
-        checkWithActualCert("52", R.raw.wild_alt_name_only, "www2.example.com", true);
-        checkWithActualCert("53", R.raw.wild_alt_name_only, "www.example2.com", false);
-
-        // wild_alt_name_only
-        //
-        // subject: C=JP
-        // subject alt names: IP Address:192.168.10.1
-        checkWithActualCert("61", R.raw.alt_ip_only, "192.168.10.1", true);
-        checkWithActualCert("61", R.raw.alt_ip_only, "192.168.10.2", false);
-    }
-
-    private void checkWithActualCert(String message, int resId, String domain,
-            boolean expected) throws Exception {
-        CertificateFactory factory = CertificateFactory.getInstance("X509");
-        InputStream certStream = getContext().getResources().openRawResource(resId);
-        X509Certificate certificate = (X509Certificate) factory.generateCertificate(certStream);
-
-        checkMatch(message, certificate, domain, expected);
-    }
-
-    /**
-     * Minimal {@link X509Certificate} implementation for {@link DomainNameValidator}.
-     */
-    private static class StubX509Certificate extends X509Certificate {
-        private final X500Principal subjectX500Principal;
-        private Collection<List<?>> subjectAlternativeNames;
-
-        public StubX509Certificate(String subjectDn) {
-            subjectX500Principal = new X500Principal(subjectDn);
-            subjectAlternativeNames = null;
-        }
-
-        public StubX509Certificate addSubjectAlternativeName(int type, String name) {
-            if (subjectAlternativeNames == null) {
-                subjectAlternativeNames = new ArrayList<List<?>>();
-            }
-            LinkedList<Object> entry = new LinkedList<Object>();
-            entry.add(type);
-            entry.add(name);
-            subjectAlternativeNames.add(entry);
-            return this;
-        }
-
-        @Override
-        public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
-            return subjectAlternativeNames;
-        }
-
-        @Override
-        public X500Principal getSubjectX500Principal() {
-            return subjectX500Principal;
-        }
-
-        @Override
-        public void checkValidity() throws CertificateExpiredException,
-                CertificateNotYetValidException {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public void checkValidity(Date date) throws CertificateExpiredException,
-                CertificateNotYetValidException {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public int getBasicConstraints() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public Principal getIssuerDN() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public boolean[] getIssuerUniqueID() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public boolean[] getKeyUsage() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public Date getNotAfter() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public Date getNotBefore() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public BigInteger getSerialNumber() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public String getSigAlgName() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public String getSigAlgOID() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public byte[] getSigAlgParams() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public byte[] getSignature() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public Principal getSubjectDN() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public boolean[] getSubjectUniqueID() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public byte[] getTBSCertificate() throws CertificateEncodingException {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public int getVersion() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public byte[] getEncoded() throws CertificateEncodingException {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public PublicKey getPublicKey() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public String toString() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
-                InvalidKeyException, NoSuchProviderException, SignatureException {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        @Override
-        public void verify(PublicKey key, String sigProvider) throws CertificateException,
-                NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
-                SignatureException {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        public Set<String> getCriticalExtensionOIDs() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        public byte[] getExtensionValue(String oid) {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        public Set<String> getNonCriticalExtensionOIDs() {
-            throw new RuntimeException("Method not implemented");
-        }
-
-        public boolean hasUnsupportedCriticalExtension() {
-            throw new RuntimeException("Method not implemented");
-        }
-    }
-}
diff --git a/common/tests/src/com/android/common/PatternsTest.java b/common/tests/src/com/android/common/PatternsTest.java
deleted file mode 100644
index 9e2ad58..0000000
--- a/common/tests/src/com/android/common/PatternsTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.common;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class PatternsTest extends TestCase {
-
-    @SmallTest
-    public void testTldPattern() throws Exception {
-        boolean t;
-
-        t = Patterns.TOP_LEVEL_DOMAIN.matcher("com").matches();
-        assertTrue("Missed valid TLD", t);
-
-        // One of the new top level domain.
-        t = Patterns.TOP_LEVEL_DOMAIN.matcher("me").matches();
-        assertTrue("Missed valid TLD", t);
-
-        // One of the new top level test domain.
-        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn--0zwm56d").matches();
-        assertTrue("Missed valid TLD", t);
-
-        t = Patterns.TOP_LEVEL_DOMAIN.matcher("mem").matches();
-        assertFalse("Matched invalid TLD!", t);
-
-        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn").matches();
-        assertFalse("Matched invalid TLD!", t);
-
-        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xer").matches();
-        assertFalse("Matched invalid TLD!", t);
-    }
-
-    @SmallTest
-    public void testUrlPattern() throws Exception {
-        boolean t;
-
-        t = Patterns.WEB_URL.matcher("http://www.google.com").matches();
-        assertTrue("Valid URL", t);
-
-        // Google in one of the new top level domain.
-        t = Patterns.WEB_URL.matcher("http://www.google.me").matches();
-        assertTrue("Valid URL", t);
-        t = Patterns.WEB_URL.matcher("google.me").matches();
-        assertTrue("Valid URL", t);
-
-        // Test url in Chinese: http://xn--fsqu00a.xn--0zwm56d
-        t = Patterns.WEB_URL.matcher("http://xn--fsqu00a.xn--0zwm56d").matches();
-        assertTrue("Valid URL", t);
-        t = Patterns.WEB_URL.matcher("xn--fsqu00a.xn--0zwm56d").matches();
-        assertTrue("Valid URL", t);
-
-        // Internationalized URL.
-        t = Patterns.WEB_URL.matcher("http://\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
-        assertTrue("Valid URL", t);
-        t = Patterns.WEB_URL.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
-        assertTrue("Valid URL", t);
-
-        t = Patterns.WEB_URL.matcher("ftp://www.example.com").matches();
-        assertFalse("Matched invalid protocol", t);
-
-        t = Patterns.WEB_URL.matcher("http://www.example.com:8080").matches();
-        assertTrue("Didn't match valid URL with port", t);
-
-        t = Patterns.WEB_URL.matcher("http://www.example.com:8080/?foo=bar").matches();
-        assertTrue("Didn't match valid URL with port and query args", t);
-
-        t = Patterns.WEB_URL.matcher("http://www.example.com:8080/~user/?foo=bar").matches();
-        assertTrue("Didn't match valid URL with ~", t);
-    }
-
-    @SmallTest
-    public void testIpPattern() throws Exception {
-        boolean t;
-
-        t = Patterns.IP_ADDRESS.matcher("172.29.86.3").matches();
-        assertTrue("Valid IP", t);
-
-        t = Patterns.IP_ADDRESS.matcher("1234.4321.9.9").matches();
-        assertFalse("Invalid IP", t);
-    }
-
-    @SmallTest
-    public void testDomainPattern() throws Exception {
-        boolean t;
-
-        t = Patterns.DOMAIN_NAME.matcher("mail.example.com").matches();
-        assertTrue("Valid domain", t);
-
-        t = Patterns.WEB_URL.matcher("google.me").matches();
-        assertTrue("Valid domain", t);
-
-        // Internationalized domains.
-        t = Patterns.DOMAIN_NAME.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
-        assertTrue("Valid domain", t);
-
-        t = Patterns.DOMAIN_NAME.matcher("__+&42.xer").matches();
-        assertFalse("Invalid domain", t);
-    }
-
-    @SmallTest
-    public void testPhonePattern() throws Exception {
-        boolean t;
-
-        t = Patterns.PHONE.matcher("(919) 555-1212").matches();
-        assertTrue("Valid phone", t);
-
-        t = Patterns.PHONE.matcher("2334 9323/54321").matches();
-        assertFalse("Invalid phone", t);
-
-        String[] tests = {
-                "Me: 16505551212 this\n",
-                "Me: 6505551212 this\n",
-                "Me: 5551212 this\n",
-
-                "Me: 1-650-555-1212 this\n",
-                "Me: (650) 555-1212 this\n",
-                "Me: +1 (650) 555-1212 this\n",
-                "Me: +1-650-555-1212 this\n",
-                "Me: 650-555-1212 this\n",
-                "Me: 555-1212 this\n",
-
-                "Me: 1.650.555.1212 this\n",
-                "Me: (650) 555.1212 this\n",
-                "Me: +1 (650) 555.1212 this\n",
-                "Me: +1.650.555.1212 this\n",
-                "Me: 650.555.1212 this\n",
-                "Me: 555.1212 this\n",
-
-                "Me: 1 650 555 1212 this\n",
-                "Me: (650) 555 1212 this\n",
-                "Me: +1 (650) 555 1212 this\n",
-                "Me: +1 650 555 1212 this\n",
-                "Me: 650 555 1212 this\n",
-                "Me: 555 1212 this\n",
-        };
-
-        for (String test : tests) {
-            Matcher m = Patterns.PHONE.matcher(test);
-
-            assertTrue("Valid phone " + test, m.find());
-        }
-    }
-}
diff --git a/mms-common/Android.mk b/mms-common/Android.mk
index de994c0..57f1ccc 100644
--- a/mms-common/Android.mk
+++ b/mms-common/Android.mk
@@ -20,6 +20,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := mms-common
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # Include this library in the build server's output directory
diff --git a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
index 0237bc2..87e4758 100644
--- a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
+++ b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
@@ -32,8 +32,8 @@
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.Log;
+import android.util.Patterns;
 
-import com.android.common.Patterns;
 import android.database.sqlite.SqliteWrapper;
 
 /**
