diff --git a/common/java/com/android/common/ArrayListCursor.java b/common/java/com/android/common/ArrayListCursor.java
new file mode 100644
index 0000000..cc1fe27
--- /dev/null
+++ b/common/java/com/android/common/ArrayListCursor.java
@@ -0,0 +1,172 @@
+/*
+ * 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 android.database.AbstractCursor;
+import android.database.CursorWindow;
+
+import java.lang.System;
+import java.util.ArrayList;
+
+/**
+ * A convenience class that presents a two-dimensional ArrayList
+ * as a Cursor.
+ * @deprecated This is has been replaced by MatrixCursor.
+*/
+public class ArrayListCursor extends AbstractCursor {
+    private String[] mColumnNames;
+    private ArrayList<Object>[] mRows;
+
+    @SuppressWarnings({"unchecked"})
+    public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
+        int colCount = columnNames.length;
+        boolean foundID = false;
+        // Add an _id column if not in columnNames
+        for (int i = 0; i < colCount; ++i) {
+            if (columnNames[i].compareToIgnoreCase("_id") == 0) {
+                mColumnNames = columnNames;
+                foundID = true;
+                break;
+            }
+        }
+
+        if (!foundID) {
+            mColumnNames = new String[colCount + 1];
+            System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
+            mColumnNames[colCount] = "_id";
+        }
+
+        int rowCount = rows.size();
+        mRows = new ArrayList[rowCount];
+
+        for (int i = 0; i < rowCount; ++i) {
+            mRows[i] = rows.get(i);
+            if (!foundID) {
+                mRows[i].add(i);
+            }
+        }
+    }
+
+    @Override
+    public void fillWindow(int position, CursorWindow window) {
+        if (position < 0 || position > getCount()) {
+            return;
+        }
+
+        window.acquireReference();
+        try {
+            int oldpos = mPos;
+            mPos = position - 1;
+            window.clear();
+            window.setStartPosition(position);
+            int columnNum = getColumnCount();
+            window.setNumColumns(columnNum);
+            while (moveToNext() && window.allocRow()) {
+                for (int i = 0; i < columnNum; i++) {
+                    final Object data = mRows[mPos].get(i);
+                    if (data != null) {
+                        if (data instanceof byte[]) {
+                            byte[] field = (byte[]) data;
+                            if (!window.putBlob(field, mPos, i)) {
+                                window.freeLastRow();
+                                break;
+                            }
+                        } else {
+                            String field = data.toString();
+                            if (!window.putString(field, mPos, i)) {
+                                window.freeLastRow();
+                                break;
+                            }
+                        }
+                    } else {
+                        if (!window.putNull(mPos, i)) {
+                            window.freeLastRow();
+                            break;
+                        }
+                    }
+                }
+            }
+
+            mPos = oldpos;
+        } catch (IllegalStateException e){
+            // simply ignore it
+        } finally {
+            window.releaseReference();
+        }
+    }
+
+    @Override
+    public int getCount() {
+        return mRows.length;
+    }
+
+    @Override
+    public boolean deleteRow() {
+        return false;
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mColumnNames;
+    }
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        return (byte[]) mRows[mPos].get(columnIndex);
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        Object cell = mRows[mPos].get(columnIndex);
+        return (cell == null) ? null : cell.toString();
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.shortValue();
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.intValue();
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.longValue();
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.floatValue();
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.doubleValue();
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        return mRows[mPos].get(columnIndex) == null;
+    }
+}
diff --git a/common/java/com/android/common/FastXmlSerializer.java b/common/java/com/android/common/FastXmlSerializer.java
new file mode 100644
index 0000000..0d33941
--- /dev/null
+++ b/common/java/com/android/common/FastXmlSerializer.java
@@ -0,0 +1,365 @@
+/*
+ * 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/NetworkConnectivityListener.java b/common/java/com/android/common/NetworkConnectivityListener.java
new file mode 100644
index 0000000..b49b80d
--- /dev/null
+++ b/common/java/com/android/common/NetworkConnectivityListener.java
@@ -0,0 +1,224 @@
+/*
+ * 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 android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * A wrapper for a broadcast receiver that provides network connectivity
+ * state information, independent of network type (mobile, Wi-Fi, etc.).
+ * @deprecated Code tempted to use this class should simply listen for connectivity intents
+ * (or poll ConnectivityManager) directly.
+ * {@hide}
+ */
+public class NetworkConnectivityListener {
+    private static final String TAG = "NetworkConnectivityListener";
+    private static final boolean DBG = false;
+
+    private Context mContext;
+    private HashMap<Handler, Integer> mHandlers = new HashMap<Handler, Integer>();
+    private State mState;
+    private boolean mListening;
+    private String mReason;
+    private boolean mIsFailover;
+
+    /** Network connectivity information */
+    private NetworkInfo mNetworkInfo;
+
+    /**
+     * In case of a Disconnect, the connectivity manager may have
+     * already established, or may be attempting to establish, connectivity
+     * with another network. If so, {@code mOtherNetworkInfo} will be non-null.
+     */
+    private NetworkInfo mOtherNetworkInfo;
+
+    private ConnectivityBroadcastReceiver mReceiver;
+
+    private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+
+            if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
+                mListening == false) {
+                Log.w(TAG, "onReceived() called with " + mState.toString() + " and " + intent);
+                return;
+            }
+
+            boolean noConnectivity =
+                intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+
+            if (noConnectivity) {
+                mState = State.NOT_CONNECTED;
+            } else {
+                mState = State.CONNECTED;
+            }
+
+            mNetworkInfo = (NetworkInfo)
+                intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
+            mOtherNetworkInfo = (NetworkInfo)
+                intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
+
+            mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
+            mIsFailover =
+                intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
+
+            if (DBG) {
+                Log.d(TAG, "onReceive(): mNetworkInfo=" + mNetworkInfo +  " mOtherNetworkInfo = "
+                        + (mOtherNetworkInfo == null ? "[none]" : mOtherNetworkInfo +
+                        " noConn=" + noConnectivity) + " mState=" + mState.toString());
+            }
+
+            // Notifiy any handlers.
+            Iterator<Handler> it = mHandlers.keySet().iterator();
+            while (it.hasNext()) {
+                Handler target = it.next();
+                Message message = Message.obtain(target, mHandlers.get(target));
+                target.sendMessage(message);
+            }
+        }
+    };
+
+    public enum State {
+        UNKNOWN,
+
+        /** This state is returned if there is connectivity to any network **/
+        CONNECTED,
+        /**
+         * This state is returned if there is no connectivity to any network. This is set
+         * to true under two circumstances:
+         * <ul>
+         * <li>When connectivity is lost to one network, and there is no other available
+         * network to attempt to switch to.</li>
+         * <li>When connectivity is lost to one network, and the attempt to switch to
+         * another network fails.</li>
+         */
+        NOT_CONNECTED
+    }
+
+    /**
+     * Create a new NetworkConnectivityListener.
+     */
+    public NetworkConnectivityListener() {
+        mState = State.UNKNOWN;
+        mReceiver = new ConnectivityBroadcastReceiver();
+    }
+
+    /**
+     * This method starts listening for network connectivity state changes.
+     * @param context
+     */
+    public synchronized void startListening(Context context) {
+        if (!mListening) {
+            mContext = context;
+
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+            context.registerReceiver(mReceiver, filter);
+            mListening = true;
+        }
+    }
+
+    /**
+     * This method stops this class from listening for network changes.
+     */
+    public synchronized void stopListening() {
+        if (mListening) {
+            mContext.unregisterReceiver(mReceiver);
+            mContext = null;
+            mNetworkInfo = null;
+            mOtherNetworkInfo = null;
+            mIsFailover = false;
+            mReason = null;
+            mListening = false;
+        }
+    }
+
+    /**
+     * This methods registers a Handler to be called back onto with the specified what code when
+     * the network connectivity state changes.
+     *
+     * @param target The target handler.
+     * @param what The what code to be used when posting a message to the handler.
+     */
+    public void registerHandler(Handler target, int what) {
+        mHandlers.put(target, what);
+    }
+
+    /**
+     * This methods unregisters the specified Handler.
+     * @param target
+     */
+    public void unregisterHandler(Handler target) {
+        mHandlers.remove(target);
+    }
+
+    public State getState() {
+        return mState;
+    }
+
+    /**
+     * Return the NetworkInfo associated with the most recent connectivity event.
+     * @return {@code NetworkInfo} for the network that had the most recent connectivity event.
+     */
+    public NetworkInfo getNetworkInfo() {
+        return mNetworkInfo;
+    }
+
+    /**
+     * If the most recent connectivity event was a DISCONNECT, return
+     * any information supplied in the broadcast about an alternate
+     * network that might be available. If this returns a non-null
+     * value, then another broadcast should follow shortly indicating
+     * whether connection to the other network succeeded.
+     *
+     * @return NetworkInfo
+     */
+    public NetworkInfo getOtherNetworkInfo() {
+        return mOtherNetworkInfo;
+    }
+
+    /**
+     * Returns true if the most recent event was for an attempt to switch over to
+     * a new network following loss of connectivity on another network.
+     * @return {@code true} if this was a failover attempt, {@code false} otherwise.
+     */
+    public boolean isFailover() {
+        return mIsFailover;
+    }
+
+    /**
+     * An optional reason for the connectivity state change may have been supplied.
+     * This returns it.
+     * @return the reason for the state change, if available, or {@code null}
+     * otherwise.
+     */
+    public String getReason() {
+        return mReason;
+    }
+}
diff --git a/common/java/com/android/common/XmlUtils.java b/common/java/com/android/common/XmlUtils.java
new file mode 100644
index 0000000..dd57e49
--- /dev/null
+++ b/common/java/com/android/common/XmlUtils.java
@@ -0,0 +1,796 @@
+/*
+ * 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) {
+            ;
+        }
+    }
+}
