diff --git a/common/java/com/android/common/Base64.java b/common/java/com/android/common/Base64.java
deleted file mode 100644
index d65e24e..0000000
--- a/common/java/com/android/common/Base64.java
+++ /dev/null
@@ -1,705 +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;
-
-/**
- * Utilities for encoding and decoding the Base64 encoding.  See RFCs
- * 2045 and 3548.
- */
-public class Base64 {
-    /**
-     * Default values for encoder/decoder flags.
-     */
-    public static final int DEFAULT = 0;
-
-    /**
-     * Encoder flag bit to indicate you want the padding '='
-     * characters at the end (if any) to be omitted.
-     */
-    public static final int NO_PADDING = 1;
-
-    /**
-     * Encoder flag bit to indicate you want all line terminators to
-     * be omitted (ie, the output will be on one long line).
-     */
-    public static final int NO_WRAP = 2;
-
-    /**
-     * Encoder flag bit to indicate you want lines to be ended with
-     * CRLF instead of just LF.
-     */
-    public static final int CRLF = 4;
-
-    /**
-     * Encoder/decoder flag bit to indicate using the "web safe"
-     * variant of Base64 (see RFC 3548 section 4) where '-' and '_'
-     * are used in place of '+' and '/'.
-     */
-    public static final int WEB_SAFE = 8;
-
-    /**
-     * Flag to pass to Base64OutputStream to indicate that it should
-     * not close the output stream it is wrapping when it itself is
-     * closed.
-     */
-    public static final int NO_CLOSE = 16;
-
-    //  --------------------------------------------------------
-    //  decoding
-    //  --------------------------------------------------------
-
-    /**
-     * Lookup table for turning bytes into their position in the
-     * Base64 alphabet.
-     */
-    private static final int DECODE[] = {
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
-        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    };
-
-    /**
-     * Decode lookup table for the "web safe" variant (RFC 3548
-     * sec. 4) where - and _ replace + and /.
-     */
-    private static final int DECODE_WEBSAFE[] = {
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
-        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
-        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    };
-
-    /** Non-data values in the DECODE arrays. */
-    private static final int SKIP = -1;
-    private static final int EQUALS = -2;
-
-    /**
-     * Decode the Base64-encoded data in input and return the data in
-     * a new byte array.
-     *
-     * The padding '=' characters at the end are considered optional, but
-     * if any are present, there must be the correct number of them.
-     *
-     * @param input the input String to decode, which is converted to
-     *               bytes using the default charset
-     * @param flags  controls certain features of the decoded output.
-     *               Pass {@code DEFAULT} to decode standard Base64.
-     *
-     * @throws IllegalArgumentException if the input contains
-     * incorrect padding
-     */
-    public static byte[] decode(String str, int flags) {
-        return decode(str.getBytes(), flags);
-    }
-
-    /**
-     * Decode the Base64-encoded data in input and return the data in
-     * a new byte array.
-     *
-     * The padding '=' characters at the end are considered optional, but
-     * if any are present, there must be the correct number of them.
-     *
-     * @param input the input array to decode
-     * @param flags  controls certain features of the decoded output.
-     *               Pass {@code DEFAULT} to decode standard Base64.
-     *
-     * @throws IllegalArgumentException if the input contains
-     * incorrect padding
-     */
-    public static byte[] decode(byte[] input, int flags) {
-        return decode(input, 0, input.length, flags);
-    }
-
-    /**
-     * Decode the Base64-encoded data in input and return the data in
-     * a new byte array.
-     *
-     * The padding '=' characters at the end are considered optional, but
-     * if any are present, there must be the correct number of them.
-     *
-     * @param input  the data to decode
-     * @param offset the position within the input array at which to start
-     * @param len    the number of bytes of input to decode
-     * @param flags  controls certain features of the decoded output.
-     *               Pass {@code DEFAULT} to decode standard Base64.
-     *
-     * @throws IllegalArgumentException if the input contains
-     * incorrect padding
-     */
-    public static byte[] decode(byte[] input, int offset, int len, int flags) {
-        // Allocate space for the most data the input could represent.
-        // (It could contain less if it contains whitespace, etc.)
-        DecoderState state = new DecoderState(flags, new byte[len*3/4]);
-
-        if (!decodeInternal(input, offset, len, state, true)) {
-            throw new IllegalArgumentException("bad base-64");
-        }
-
-        // Maybe we got lucky and allocated exactly enough output space.
-        if (state.op == state.output.length) {
-            return state.output;
-        }
-
-        // Need to shorten the array, so allocate a new one of the
-        // right size and copy.
-        byte[] temp = new byte[state.op];
-        System.arraycopy(state.output, 0, temp, 0, state.op);
-        return temp;
-    }
-
-    /* package */ static class DecoderState {
-        public byte[] output;
-        public int op;
-
-        public int state;   // state number (0 to 6)
-        public int value;
-
-        final public int[] alphabet;
-
-        public DecoderState(int flags, byte[] output) {
-            this.output = output;
-
-            alphabet = ((flags & WEB_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
-            state = 0;
-            value = 0;
-        }
-    }
-
-    /**
-     * Decode another block of input data.
-     *
-     * @param dstate a DecoderState object whose (caller-provided)
-     *        output array is big enough to hold all the decoded data.
-     *        On return, dstate.op will be set to the length of the
-     *        decoded data.
-     * @param finish true if this is the final call to decodeInternal
-     *        with the given DecoderState object.  Will finalize the
-     *        decoder state and include any final bytes in the output.
-     *
-     * @return true if the state machine is still healthy.  false if
-     *         bad base-64 data has been detected in the input stream.
-     */
-
-    /* package */ static boolean decodeInternal(
-        byte[] input, int offset, int len, final DecoderState dstate, boolean finish) {
-        if (dstate.state == 6) return false;
-
-        int state = dstate.state;
-        int value = dstate.value;
-        final int[] decode = dstate.alphabet;
-        final byte[] output = dstate.output;
-        int op = 0;
-
-        int p = offset;
-        len += offset;
-
-        while (p < len) {
-
-            // Try the fast path:  we're starting a new tuple and the
-            // next four bytes of the input stream are all data
-            // bytes.  This corresponds to going through states
-            // 0-1-2-3-0.  We expect to use this method for most of
-            // the data.
-            //
-            // If any of the next four bytes of input are non-data
-            // (whitespace, etc.), value will end up negative.  (All
-            // the non-data values in decode are small negative
-            // numbers, so shifting any of them up and or'ing them
-            // together will result in a value with its top bit set.)
-            //
-            // You can remove this whole block and the output should
-            // be the same, just slower.
-            if (state == 0 && p+4 <= len &&
-                (value = ((decode[input[p] & 0xff] << 18) |
-                          (decode[input[p+1] & 0xff] << 12) |
-                          (decode[input[p+2] & 0xff] << 6) |
-                          (decode[input[p+3] & 0xff]))) >= 0) {
-                output[op+2] = (byte) value;
-                output[op+1] = (byte) (value >> 8);
-                output[op] = (byte) (value >> 16);
-                op += 3;
-                p += 4;
-                continue;
-            }
-
-            // The fast path isn't available -- either we've read a
-            // partial tuple, or the next four input bytes aren't all
-            // data, or whatever.  Fall back to the slower state
-            // machine implementation.
-            //
-            // States 0-3 are reading through the next input tuple.
-            // State 4 is having read one '=' and expecting exactly
-            // one more.
-            // State 5 is expecting no more data or padding characters
-            // in the input.
-            // State 6 is the error state; an error has been detected
-            // in the input and no future input can "fix" it.
-
-            int d = decode[input[p++] & 0xff];
-
-            switch (state) {
-                case 0:
-                    if (d >= 0) {
-                        value = d;
-                        ++state;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 1:
-                    if (d >= 0) {
-                        value = (value << 6) | d;
-                        ++state;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 2:
-                    if (d >= 0) {
-                        value = (value << 6) | d;
-                        ++state;
-                    } else if (d == EQUALS) {
-                        // Emit the last (partial) output tuple;
-                        // expect exactly one more padding character.
-                        output[op++] = (byte) (value >> 4);
-                        state = 4;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 3:
-                    if (d >= 0) {
-                        // Emit the output triple and return to state 0.
-                        value = (value << 6) | d;
-                        output[op+2] = (byte) value;
-                        output[op+1] = (byte) (value >> 8);
-                        output[op] = (byte) (value >> 16);
-                        op += 3;
-                        state = 0;
-                    } else if (d == EQUALS) {
-                        // Emit the last (partial) output tuple;
-                        // expect no further data or padding characters.
-                        output[op+1] = (byte) (value >> 2);
-                        output[op] = (byte) (value >> 10);
-                        op += 2;
-                        state = 5;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 4:
-                    if (d == EQUALS) {
-                        ++state;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 5:
-                    if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-            }
-        }
-
-        if (!finish) {
-            // We're out of input, but a future call could provide
-            // more.  Return the output we've produced on this call
-            // and save the current state of the state machine.
-            dstate.state = state;
-            dstate.value = value;
-            dstate.op = op;
-            return true;
-        }
-
-        // Done reading input.  Now figure out where we are left in
-        // the state machine and finish up.
-
-        switch (state) {
-            case 0:
-                // Output length is a multiple of three.  Fine.
-                break;
-            case 1:
-                // Read one extra input byte, which isn't enough to
-                // make another output byte.  Illegal.
-                dstate.state = 6;
-                return false;
-            case 2:
-                // Read two extra input bytes, enough to emit 1 more
-                // output byte.  Fine.
-                output[op++] = (byte) (value >> 4);
-                break;
-            case 3:
-                // Read three extra input bytes, enough to emit 2 more
-                // output bytes.  Fine.
-                output[op+1] = (byte) (value >> 2);
-                output[op] = (byte) (value >> 10);
-                op += 2;
-                break;
-            case 4:
-                // Read one padding '=' when we expected 2.  Illegal.
-                dstate.state = 6;
-                return false;
-            case 5:
-                // Read all the padding '='s we expected and no more.
-                // Fine.
-                break;
-        }
-
-        dstate.op = op;
-        return true;
-    }
-
-    //  --------------------------------------------------------
-    //  encoding
-    //  --------------------------------------------------------
-
-    /**
-     * Emit a new line every this many output tuples.  Corresponds to
-     * a 76-character line length (the maximum allowable according to
-     * RFC 2045).
-     */
-    private static final int LINE_GROUPS = 19;
-
-    /**
-     * Lookup table for turning Base64 alphabet positions (6 bits)
-     * into output bytes.
-     */
-    private static final byte ENCODE[] = {
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
-        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
-        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
-        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
-        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
-        'w', 'x', 'y', 'z', '0', '1', '2', '3',
-        '4', '5', '6', '7', '8', '9', '+', '/',
-    };
-
-    /**
-     * Lookup table for turning Base64 alphabet positions (6 bits)
-     * into output bytes.
-     */
-    private static final byte ENCODE_WEBSAFE[] = {
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
-        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
-        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
-        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
-        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
-        'w', 'x', 'y', 'z', '0', '1', '2', '3',
-        '4', '5', '6', '7', '8', '9', '-', '_',
-    };
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * String with the result.
-     *
-     * @param input  the data to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static String encodeToString(byte[] input, int flags) {
-        return new String(encode(input, flags));
-    }
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * String with the result.
-     *
-     * @param input  the data to encode
-     * @param offset the position within the input array at which to
-     *               start
-     * @param len    the number of bytes of input to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static String encodeToString(byte[] input, int offset, int len, int flags) {
-        return new String(encode(input, offset, len, flags));
-    }
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * byte[] with the result.
-     *
-     * @param input  the data to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static byte[] encode(byte[] input, int flags) {
-        return encode(input, 0, input.length, flags);
-    }
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * byte[] with the result.
-     *
-     * @param input  the data to encode
-     * @param offset the position within the input array at which to
-     *               start
-     * @param len    the number of bytes of input to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static byte[] encode(byte[] input, int offset, int len, int flags) {
-        EncoderState state = new EncoderState(flags, null);
-
-        // Compute the exact length of the array we will produce.
-        int output_len = len / 3 * 4;
-
-        // Account for the tail of the data and the padding bytes, if any.
-        if (state.do_padding) {
-            if (len % 3 > 0) {
-                output_len += 4;
-            }
-        } else {
-            switch (len % 3) {
-                case 0: break;
-                case 1: output_len += 2; break;
-                case 2: output_len += 3; break;
-            }
-        }
-
-        // Account for the newlines, if any.
-        if (state.do_newline && len > 0) {
-            output_len += (((len-1) / (3 * LINE_GROUPS)) + 1) * (state.do_cr ? 2 : 1);
-        }
-
-        state.output = new byte[output_len];
-        encodeInternal(input, offset, len, state, true);
-
-        assert state.op == output_len;
-
-        return state.output;
-    }
-
-    /* package */ static class EncoderState {
-        public byte[] output;
-        public int op;
-
-        final public byte[] tail;
-        public int tailLen;
-        public int count;
-
-        final public boolean do_padding;
-        final public boolean do_newline;
-        final public boolean do_cr;
-        final public byte[] alphabet;
-
-        public EncoderState(int flags, byte[] output) {
-            this.output = output;
-
-            do_padding = (flags & NO_PADDING) == 0;
-            do_newline = (flags & NO_WRAP) == 0;
-            do_cr = (flags & CRLF) != 0;
-            alphabet = ((flags & WEB_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
-
-            tail = new byte[2];
-            tailLen = 0;
-
-            count = do_newline ? LINE_GROUPS : -1;
-        }
-    }
-
-    /**
-     * Encode another block of input data.
-     *
-     * @param estate an EncoderState object whose (caller-provided)
-     *        output array is big enough to hold all the encoded data.
-     *        On return, estate.op will be set to the length of the
-     *        encoded data.
-     * @param finish true if this is the final call to encodeInternal
-     *        with the given EncoderState object.  Will finalize the
-     *        encoder state and include any final bytes in the output.
-     */
-    static void encodeInternal(byte[] input, int offset, int len,
-                               final EncoderState estate, boolean finish) {
-        final boolean do_cr = estate.do_cr;
-        final boolean do_newline = estate.do_newline;
-        final boolean do_padding = estate.do_padding;
-        final byte[] output = estate.output;
-
-        int op = 0;
-
-        int p = offset;
-        len += offset;
-        int v = -1;
-        int count = estate.count;
-
-        // First we need to concatenate the tail of the previous call
-        // with any input bytes available now and see if we can empty
-        // the tail.
-
-        switch (estate.tailLen) {
-            case 0:
-                // There was no tail.
-                break;
-
-            case 1:
-                if (p+2 <= len) {
-                    // A 1-byte tail with at least 2 bytes of
-                    // input available now.
-                    v = ((estate.tail[0] & 0xff) << 16) |
-                        ((input[p++] & 0xff) << 8) |
-                        (input[p++] & 0xff);
-                    estate.tailLen = 0;
-                };
-                break;
-
-            case 2:
-                if (p+1 <= len) {
-                    // A 2-byte tail with at least 1 byte of input.
-                    v = ((estate.tail[0] & 0xff) << 16) |
-                        ((estate.tail[1] & 0xff) << 8) |
-                        (input[p++] & 0xff);
-                    estate.tailLen = 0;
-                }
-                break;
-        }
-
-        if (v != -1) {
-            output[op++] = estate.alphabet[(v >> 18) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 12) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-            output[op++] = estate.alphabet[v & 0x3f];
-            if (--count == 0) {
-                if (do_cr) output[op++] = '\r';
-                output[op++] = '\n';
-                count = LINE_GROUPS;
-            }
-        }
-
-        // At this point either there is no tail, or there are fewer
-        // than 3 bytes of input available.
-
-        // The main loop, turning 3 input bytes into 4 output bytes on
-        // each iteration.
-        while (p+3 <= len) {
-            v = ((input[p++] & 0xff) << 16) |
-                ((input[p++] & 0xff) << 8) |
-                (input[p++] & 0xff);
-            output[op++] = estate.alphabet[(v >> 18) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 12) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-            output[op++] = estate.alphabet[v & 0x3f];
-            if (--count == 0) {
-                if (do_cr) output[op++] = '\r';
-                output[op++] = '\n';
-                count = LINE_GROUPS;
-            }
-        }
-
-        if (finish) {
-            // Finish up the tail of the input.  Note that we need to
-            // consume any bytes in estate.tail before any bytes
-            // remaining in input; there should be at most two bytes
-            // total.
-
-            if (p-estate.tailLen == len-1) {
-                int t = 0;
-                v = ((estate.tailLen > 0 ? estate.tail[t++] : input[p++]) & 0xff) << 4;
-                estate.tailLen -= t;
-                output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-                output[op++] = estate.alphabet[v & 0x3f];
-                if (do_padding) {
-                    output[op++] = '=';
-                    output[op++] = '=';
-                }
-                if (do_newline) {
-                    if (do_cr) output[op++] = '\r';
-                    output[op++] = '\n';
-                }
-            } else if (p-estate.tailLen == len-2) {
-                int t = 0;
-                v = (((estate.tailLen > 1 ? estate.tail[t++] : input[p++]) & 0xff) << 10) |
-                    (((estate.tailLen > 0 ? estate.tail[t++] : input[p++]) & 0xff) << 2);
-                estate.tailLen -= t;
-                output[op++] = estate.alphabet[(v >> 12) & 0x3f];
-                output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-                output[op++] = estate.alphabet[v & 0x3f];
-                if (do_padding) {
-                    output[op++] = '=';
-                }
-                if (do_newline) {
-                    if (do_cr) output[op++] = '\r';
-                    output[op++] = '\n';
-                }
-            } else if (do_newline && op > 0 && count != LINE_GROUPS) {
-                if (do_cr) output[op++] = '\r';
-                output[op++] = '\n';
-            }
-
-            assert estate.tailLen == 0;
-            assert p == len;
-        } else {
-            // Save the leftovers in tail to be consumed on the next
-            // call to encodeInternal.
-
-            if (p == len-1) {
-                estate.tail[estate.tailLen++] = input[p];
-            } else if (p == len-2) {
-                estate.tail[estate.tailLen++] = input[p];
-                estate.tail[estate.tailLen++] = input[p+1];
-            }
-        }
-
-        estate.op = op;
-        estate.count = count;
-    }
-
-    private Base64() { }   // don't instantiate
-}
diff --git a/common/java/com/android/common/Base64InputStream.java b/common/java/com/android/common/Base64InputStream.java
deleted file mode 100644
index 1969bc4..0000000
--- a/common/java/com/android/common/Base64InputStream.java
+++ /dev/null
@@ -1,169 +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 java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * An OutputStream that does either Base64 encoding or decoding on the
- * data written to it, writing the resulting data to another
- * OutputStream.
- */
-public class Base64InputStream extends FilterInputStream {
-    private final boolean encode;
-    private final Base64.EncoderState estate;
-    private final Base64.DecoderState dstate;
-
-    private static byte[] EMPTY = new byte[0];
-
-    private static final int BUFFER_SIZE = 2048;
-    private boolean eof;
-    private byte[] inputBuffer;
-    private byte[] outputBuffer;
-    private int outputStart;
-    private int outputEnd;
-
-    /**
-     * An InputStream that performs Base64 decoding on the data read
-     * from the wrapped stream.
-     *
-     * @param in the InputStream to read the source data from
-     * @param flags bit flags for controlling the decoder; see the
-     *        constants in {@link Base64}
-     */
-    public Base64InputStream(InputStream out, int flags) {
-        this(out, flags, false);
-    }
-
-    /**
-     * Performs Base64 encoding or decoding on the data read from the
-     * wrapped InputStream.
-     *
-     * @param in the InputStream to read the source data from
-     * @param flags bit flags for controlling the decoder; see the
-     *        constants in {@link Base64}
-     * @param encode true to encode, false to decode
-     */
-    public Base64InputStream(InputStream out, int flags, boolean encode) {
-        super(out);
-        this.encode = encode;
-        eof = false;
-        inputBuffer = new byte[BUFFER_SIZE];
-        if (encode) {
-            // len*8/5+10 is an overestimate of the most bytes the
-            // encoder can produce for len bytes of input.
-            outputBuffer = new byte[BUFFER_SIZE * 8/5 + 10];
-            estate = new Base64.EncoderState(flags, outputBuffer);
-            dstate = null;
-        } else {
-            // len*3/4+10 is an overestimate of the most bytes the
-            // decoder can produce for len bytes of input.
-            outputBuffer = new byte[BUFFER_SIZE * 3/4 + 10];
-            estate = null;
-            dstate = new Base64.DecoderState(flags, outputBuffer);
-        }
-        outputStart = 0;
-        outputEnd = 0;
-    }
-
-    public boolean markSupported() {
-        return false;
-    }
-
-    public void mark(int readlimit) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void reset() {
-        throw new UnsupportedOperationException();
-    }
-
-    public void close() throws IOException {
-        in.close();
-        inputBuffer = null;
-    }
-
-    public int available() {
-        return outputEnd - outputStart;
-    }
-
-    public long skip(long n) throws IOException {
-        if (outputStart >= outputEnd) {
-            refill();
-        }
-        if (outputStart >= outputEnd) {
-            return 0;
-        }
-        long bytes = Math.min(n, outputEnd-outputStart);
-        outputStart += bytes;
-        return bytes;
-    }
-
-    public int read() throws IOException {
-        if (outputStart >= outputEnd) {
-            refill();
-        }
-        if (outputStart >= outputEnd) {
-            return -1;
-        } else {
-            return outputBuffer[outputStart++];
-        }
-    }
-
-    public int read(byte[] b, int off, int len) throws IOException {
-        if (outputStart >= outputEnd) {
-            refill();
-        }
-        if (outputStart >= outputEnd) {
-            return -1;
-        }
-        int bytes = Math.min(len, outputEnd-outputStart);
-        System.arraycopy(outputBuffer, outputStart, b, off, bytes);
-        outputStart += bytes;
-        return bytes;
-    }
-
-    /**
-     * Read data from the input stream into inputBuffer, then
-     * decode/encode it into the empty outputBuffer, and reset the
-     * outputStart and outputEnd pointers.
-     */
-    private void refill() throws IOException {
-        if (eof) return;
-        int bytesRead = in.read(inputBuffer);
-        if (encode) {
-            if (bytesRead == -1) {
-                eof = true;
-                Base64.encodeInternal(EMPTY, 0, 0, estate, true);
-            } else {
-                Base64.encodeInternal(inputBuffer, 0, bytesRead, estate, false);
-            }
-            outputEnd = estate.op;
-        } else {
-            if (bytesRead == -1) {
-                eof = true;
-                Base64.decodeInternal(EMPTY, 0, 0, dstate, true);
-            } else {
-                Base64.decodeInternal(inputBuffer, 0, bytesRead, dstate, false);
-            }
-            outputEnd = dstate.op;
-        }
-        outputStart = 0;
-    }
-}
diff --git a/common/java/com/android/common/Base64OutputStream.java b/common/java/com/android/common/Base64OutputStream.java
deleted file mode 100644
index 76e1b6a..0000000
--- a/common/java/com/android/common/Base64OutputStream.java
+++ /dev/null
@@ -1,153 +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 java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An OutputStream that does either Base64 encoding or decoding on the
- * data written to it, writing the resulting data to another
- * OutputStream.
- */
-public class Base64OutputStream extends FilterOutputStream {
-    private final boolean encode;
-    private final Base64.EncoderState estate;
-    private final Base64.DecoderState dstate;
-    private final int flags;
-
-    private byte[] buffer = null;
-    private int bpos = 0;
-
-    private static byte[] EMPTY = new byte[0];
-
-    /**
-     * Performs Base64 encoding on the data written to the stream,
-     * writing the encoded data to another OutputStream.
-     *
-     * @param out the OutputStream to write the encoded data to
-     * @param flags bit flags for controlling the encoder; see the
-     *        constants in {@link Base64}
-     */
-    public Base64OutputStream(OutputStream out, int flags) {
-        this(out, flags, true);
-    }
-
-    /**
-     * Performs Base64 encoding or decoding on the data written to the
-     * stream, writing the encoded/decoded data to another
-     * OutputStream.
-     *
-     * @param out the OutputStream to write the encoded data to
-     * @param flags bit flags for controlling the encoder; see the
-     *        constants in {@link Base64}
-     * @param encode true to encode, false to decode
-     */
-    public Base64OutputStream(OutputStream out, int flags, boolean encode) {
-        super(out);
-        this.flags = flags;
-        this.encode = encode;
-        if (encode) {
-            estate = new Base64.EncoderState(flags, null);
-            dstate = null;
-        } else {
-            estate = null;
-            dstate = new Base64.DecoderState(flags, null);
-        }
-    }
-
-    public void write(int b) throws IOException {
-        // To avoid invoking the encoder/decoder routines for single
-        // bytes, we buffer up calls to write(int) in an internal
-        // byte array to transform them into writes of decently-sized
-        // arrays.
-
-        if (buffer == null) {
-            buffer = new byte[1024];
-        }
-        if (bpos >= buffer.length) {
-            // internal buffer full; write it out.
-            internalWrite(buffer, 0, bpos, false);
-            bpos = 0;
-        }
-        buffer[bpos++] = (byte) b;
-    }
-
-    /**
-     * Flush any buffered data from calls to write(int).  Needed
-     * before doing a write(byte[], int, int) or a close().
-     */
-    private void flushBuffer() throws IOException {
-        if (bpos > 0) {
-            internalWrite(buffer, 0, bpos, false);
-            bpos = 0;
-        }
-    }
-
-    public void write(byte[] b, int off, int len) throws IOException {
-        if (len <= 0) return;
-        flushBuffer();
-        internalWrite(b, off, len, false);
-    }
-
-    public void close() throws IOException {
-        flushBuffer();
-        internalWrite(EMPTY, 0, 0, true);
-        if ((flags & Base64.NO_CLOSE) == 0) {
-            out.close();
-        } else {
-            out.flush();
-        }
-    }
-
-    /**
-     * Write the given bytes to the encoder/decoder.
-     *
-     * @param finish true if this is the last batch of input, to cause
-     *        encoder/decoder state to be finalized.
-     */
-    private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException {
-        if (encode) {
-            // len*8/5+10 is an overestimate of the most bytes the
-            // encoder can produce for len bytes of input.
-            estate.output = embiggen(estate.output, len*8/5+10);
-            Base64.encodeInternal(b, off, len, estate, finish);
-            out.write(estate.output, 0, estate.op);
-        } else {
-            // len*3/4+10 is an overestimate of the most bytes the
-            // decoder can produce for len bytes of input.
-            dstate.output = embiggen(dstate.output, len*3/4+10);
-            if (!Base64.decodeInternal(b, off, len, dstate, finish)) {
-                throw new IOException("bad base-64");
-            }
-            out.write(dstate.output, 0, dstate.op);
-        }
-    }
-
-    /**
-     * If b.length is at least len, return b.  Otherwise return a new
-     * byte array of length len.
-     */
-    private byte[] embiggen(byte[] b, int len) {
-        if (b == null || b.length < len) {
-            return new byte[len];
-        } else {
-            return b;
-        }
-    }
-}
diff --git a/common/tests/src/com/android/common/Base64Test.java b/common/tests/src/com/android/common/Base64Test.java
deleted file mode 100644
index 1064625..0000000
--- a/common/tests/src/com/android/common/Base64Test.java
+++ /dev/null
@@ -1,520 +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 junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.Random;
-
-public class Base64Test extends TestCase {
-    private static final String TAG = "B64Test";
-
-    /** Decodes a string, returning a string. */
-    private String decodeString(String in) throws Exception {
-        byte[] out = Base64.decode(in, 0);
-        return new String(out);
-    }
-
-    /**
-     * Encodes the string 'in' using 'flags'.  Asserts that decoding
-     * gives the same string.  Returns the encoded string.
-     */
-    private String encodeToString(String in, int flags) throws Exception {
-        String b64 = Base64.encodeToString(in.getBytes(), flags);
-        String dec = decodeString(b64);
-        assertEquals(in, dec);
-        return b64;
-    }
-
-    /** Assert that decoding 'in' throws IllegalArgumentException. */
-    private void assertBad(String in) throws Exception {
-        try {
-            byte[] out = Base64.decode(in, 0);
-            fail("should have failed to decode");
-        } catch (IllegalArgumentException e) {
-        }
-    }
-
-    /** Assert that actual equals the first len bytes of expected. */
-    private void assertEquals(byte[] expected, int len, byte[] actual) {
-        assertEquals(len, actual.length);
-        for (int i = 0; i < len; ++i) {
-            assertEquals(expected[i], actual[i]);
-        }
-    }
-
-    /** Assert that actual equals the first len bytes of expected. */
-    private void assertEquals(byte[] expected, int len, byte[] actual, int alen) {
-        assertEquals(len, alen);
-        for (int i = 0; i < len; ++i) {
-            assertEquals(expected[i], actual[i]);
-        }
-    }
-
-    /** Assert that actual equals the first len bytes of expected. */
-    private void assertEquals(byte[] expected, byte[] actual) {
-        assertEquals(expected.length, actual.length);
-        for (int i = 0; i < expected.length; ++i) {
-            assertEquals(expected[i], actual[i]);
-        }
-    }
-
-    public void testDecodeExtraChars() throws Exception {
-        // padding 0
-        assertEquals("hello, world", decodeString("aGVsbG8sIHdvcmxk"));
-        assertBad("aGVsbG8sIHdvcmxk=");
-        assertBad("aGVsbG8sIHdvcmxk==");
-        assertBad("aGVsbG8sIHdvcmxk =");
-        assertBad("aGVsbG8sIHdvcmxk = = ");
-        assertEquals("hello, world", decodeString(" aGVs bG8s IHdv cmxk  "));
-        assertEquals("hello, world", decodeString(" aGV sbG8 sIHd vcmx k "));
-        assertEquals("hello, world", decodeString(" aG VsbG 8sIH dvcm xk "));
-        assertEquals("hello, world", decodeString(" a GVsb G8sI Hdvc mxk "));
-        assertEquals("hello, world", decodeString(" a G V s b G 8 s I H d v c m x k "));
-        assertEquals("hello, world", decodeString("_a*G_V*s_b*G_8*s_I*H_d*v_c*m_x*k_"));
-        assertEquals("hello, world", decodeString("aGVsbG8sIHdvcmxk"));
-
-        // padding 1
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPyE="));
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPyE"));
-        assertBad("aGVsbG8sIHdvcmxkPyE==");
-        assertBad("aGVsbG8sIHdvcmxkPyE ==");
-        assertBad("aGVsbG8sIHdvcmxkPyE = = ");
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E="));
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E"));
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E ="));
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E "));
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E = "));
-        assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E   "));
-
-        // padding 2
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkLg=="));
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkLg"));
-        assertBad("aGVsbG8sIHdvcmxkLg=");
-        assertBad("aGVsbG8sIHdvcmxkLg =");
-        assertBad("aGVsbG8sIHdvcmxkLg = ");
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g=="));
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g"));
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g =="));
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g "));
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g = = "));
-        assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g   "));
-    }
-
-    private static final byte[] BYTES = { (byte) 0xff, (byte) 0xee, (byte) 0xdd,
-                                          (byte) 0xcc, (byte) 0xbb, (byte) 0xaa,
-                                          (byte) 0x99, (byte) 0x88, (byte) 0x77 };
-
-    public void testBinaryDecode() throws Exception {
-        assertEquals(BYTES, 0, Base64.decode("", 0));
-        assertEquals(BYTES, 1, Base64.decode("/w==", 0));
-        assertEquals(BYTES, 2, Base64.decode("/+4=", 0));
-        assertEquals(BYTES, 3, Base64.decode("/+7d", 0));
-        assertEquals(BYTES, 4, Base64.decode("/+7dzA==", 0));
-        assertEquals(BYTES, 5, Base64.decode("/+7dzLs=", 0));
-        assertEquals(BYTES, 6, Base64.decode("/+7dzLuq", 0));
-        assertEquals(BYTES, 7, Base64.decode("/+7dzLuqmQ==", 0));
-        assertEquals(BYTES, 8, Base64.decode("/+7dzLuqmYg=", 0));
-    }
-
-    public void testWebSafe() throws Exception {
-        assertEquals(BYTES, 0, Base64.decode("", Base64.WEB_SAFE));
-        assertEquals(BYTES, 1, Base64.decode("_w==", Base64.WEB_SAFE));
-        assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.WEB_SAFE));
-        assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.WEB_SAFE));
-        assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.WEB_SAFE));
-        assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.WEB_SAFE));
-        assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.WEB_SAFE));
-        assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.WEB_SAFE));
-        assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.WEB_SAFE));
-
-        assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.WEB_SAFE));
-        assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.WEB_SAFE));
-        assertEquals("_-4=\n", Base64.encodeToString(BYTES, 0, 2, Base64.WEB_SAFE));
-        assertEquals("_-7d\n", Base64.encodeToString(BYTES, 0, 3, Base64.WEB_SAFE));
-        assertEquals("_-7dzA==\n", Base64.encodeToString(BYTES, 0, 4, Base64.WEB_SAFE));
-        assertEquals("_-7dzLs=\n", Base64.encodeToString(BYTES, 0, 5, Base64.WEB_SAFE));
-        assertEquals("_-7dzLuq\n", Base64.encodeToString(BYTES, 0, 6, Base64.WEB_SAFE));
-        assertEquals("_-7dzLuqmQ==\n", Base64.encodeToString(BYTES, 0, 7, Base64.WEB_SAFE));
-        assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.WEB_SAFE));
-    }
-
-    public void testFlags() throws Exception {
-        assertEquals("YQ==\n",       encodeToString("a", 0));
-        assertEquals("YQ==",         encodeToString("a", Base64.NO_WRAP));
-        assertEquals("YQ\n",         encodeToString("a", Base64.NO_PADDING));
-        assertEquals("YQ",           encodeToString("a", Base64.NO_PADDING | Base64.NO_WRAP));
-        assertEquals("YQ==\r\n",     encodeToString("a", Base64.CRLF));
-        assertEquals("YQ\r\n",       encodeToString("a", Base64.CRLF | Base64.NO_PADDING));
-
-        assertEquals("YWI=\n",       encodeToString("ab", 0));
-        assertEquals("YWI=",         encodeToString("ab", Base64.NO_WRAP));
-        assertEquals("YWI\n",        encodeToString("ab", Base64.NO_PADDING));
-        assertEquals("YWI",          encodeToString("ab", Base64.NO_PADDING | Base64.NO_WRAP));
-        assertEquals("YWI=\r\n",     encodeToString("ab", Base64.CRLF));
-        assertEquals("YWI\r\n",      encodeToString("ab", Base64.CRLF | Base64.NO_PADDING));
-
-        assertEquals("YWJj\n",       encodeToString("abc", 0));
-        assertEquals("YWJj",         encodeToString("abc", Base64.NO_WRAP));
-        assertEquals("YWJj\n",       encodeToString("abc", Base64.NO_PADDING));
-        assertEquals("YWJj",         encodeToString("abc", Base64.NO_PADDING | Base64.NO_WRAP));
-        assertEquals("YWJj\r\n",     encodeToString("abc", Base64.CRLF));
-        assertEquals("YWJj\r\n",     encodeToString("abc", Base64.CRLF | Base64.NO_PADDING));
-
-        assertEquals("YWJjZA==\n",   encodeToString("abcd", 0));
-        assertEquals("YWJjZA==",     encodeToString("abcd", Base64.NO_WRAP));
-        assertEquals("YWJjZA\n",     encodeToString("abcd", Base64.NO_PADDING));
-        assertEquals("YWJjZA",       encodeToString("abcd", Base64.NO_PADDING | Base64.NO_WRAP));
-        assertEquals("YWJjZA==\r\n", encodeToString("abcd", Base64.CRLF));
-        assertEquals("YWJjZA\r\n",   encodeToString("abcd", Base64.CRLF | Base64.NO_PADDING));
-    }
-
-    public void testLineLength() throws Exception {
-        String in_56 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd";
-        String in_57 = in_56 + "e";
-        String in_58 = in_56 + "ef";
-        String in_59 = in_56 + "efg";
-        String in_60 = in_56 + "efgh";
-        String in_61 = in_56 + "efghi";
-
-        String prefix = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5emFi";
-        String out_56 = prefix + "Y2Q=\n";
-        String out_57 = prefix + "Y2Rl\n";
-        String out_58 = prefix + "Y2Rl\nZg==\n";
-        String out_59 = prefix + "Y2Rl\nZmc=\n";
-        String out_60 = prefix + "Y2Rl\nZmdo\n";
-        String out_61 = prefix + "Y2Rl\nZmdoaQ==\n";
-
-        // no newline for an empty input array.
-        assertEquals("", encodeToString("", 0));
-
-        assertEquals(out_56, encodeToString(in_56, 0));
-        assertEquals(out_57, encodeToString(in_57, 0));
-        assertEquals(out_58, encodeToString(in_58, 0));
-        assertEquals(out_59, encodeToString(in_59, 0));
-        assertEquals(out_60, encodeToString(in_60, 0));
-        assertEquals(out_61, encodeToString(in_61, 0));
-
-        assertEquals(out_56.replaceAll("=", ""), encodeToString(in_56, Base64.NO_PADDING));
-        assertEquals(out_57.replaceAll("=", ""), encodeToString(in_57, Base64.NO_PADDING));
-        assertEquals(out_58.replaceAll("=", ""), encodeToString(in_58, Base64.NO_PADDING));
-        assertEquals(out_59.replaceAll("=", ""), encodeToString(in_59, Base64.NO_PADDING));
-        assertEquals(out_60.replaceAll("=", ""), encodeToString(in_60, Base64.NO_PADDING));
-        assertEquals(out_61.replaceAll("=", ""), encodeToString(in_61, Base64.NO_PADDING));
-
-        assertEquals(out_56.replaceAll("\n", ""), encodeToString(in_56, Base64.NO_WRAP));
-        assertEquals(out_57.replaceAll("\n", ""), encodeToString(in_57, Base64.NO_WRAP));
-        assertEquals(out_58.replaceAll("\n", ""), encodeToString(in_58, Base64.NO_WRAP));
-        assertEquals(out_59.replaceAll("\n", ""), encodeToString(in_59, Base64.NO_WRAP));
-        assertEquals(out_60.replaceAll("\n", ""), encodeToString(in_60, Base64.NO_WRAP));
-        assertEquals(out_61.replaceAll("\n", ""), encodeToString(in_61, Base64.NO_WRAP));
-    }
-
-    /**
-     * Tests that Base64.encodeInternal does correct handling of the
-     * tail for each call.
-     *
-     * This test is disabled because while it passes if you can get it
-     * to run, android's test infrastructure currently doesn't allow
-     * us to get at package-private members (Base64.EncoderState in
-     * this case).
-     */
-    public void XXXtestEncodeInternal() throws Exception {
-        byte[] input = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
-        byte[] output = new byte[100];
-
-        Base64.EncoderState state = new Base64.EncoderState(Base64.NO_PADDING | Base64.NO_WRAP,
-                                                            output);
-
-        Base64.encodeInternal(input, 0, 3, state, false);
-        assertEquals("YWJj".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 3, state, false);
-        assertEquals("YWJj".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 1, state, false);
-        assertEquals(0, state.op);
-        assertEquals(1, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 1, state, false);
-        assertEquals(0, state.op);
-        assertEquals(2, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 1, state, false);
-        assertEquals("YWFh".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 2, state, false);
-        assertEquals(0, state.op);
-        assertEquals(2, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 2, state, false);
-        assertEquals("YWJh".getBytes(), 4, state.output, state.op);
-        assertEquals(1, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 2, state, false);
-        assertEquals("YmFi".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
-
-        Base64.encodeInternal(input, 0, 1, state, true);
-        assertEquals("YQ".getBytes(), 2, state.output, state.op);
-    }
-
-    private static final String lipsum =
-            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
-            "Quisque congue eleifend odio, eu ornare nulla facilisis eget. " +
-            "Integer eget elit diam, sit amet laoreet nibh. Quisque enim " +
-            "urna, pharetra vitae consequat eget, adipiscing eu ante. " +
-            "Aliquam venenatis arcu nec nibh imperdiet tempor. In id dui " +
-            "eget lorem aliquam rutrum vel vitae eros. In placerat ornare " +
-            "pretium. Curabitur non fringilla mi. Fusce ultricies, turpis " +
-            "eu ultrices suscipit, ligula nisi consectetur eros, dapibus " +
-            "aliquet dui sapien a turpis. Donec ultricies varius ligula, " +
-            "ut hendrerit arcu malesuada at. Praesent sed elit pretium " +
-            "eros luctus gravida. In ac dolor lorem. Cras condimentum " +
-            "convallis elementum. Phasellus vel felis in nulla ultrices " +
-            "venenatis. Nam non tortor non orci convallis convallis. " +
-            "Nam tristique lacinia hendrerit. Pellentesque habitant morbi " +
-            "tristique senectus et netus et malesuada fames ac turpis " +
-            "egestas. Vivamus cursus, nibh eu imperdiet porta, magna " +
-            "ipsum mollis mauris, sit amet fringilla mi nisl eu mi. " +
-            "Phasellus posuere, leo at ultricies vehicula, massa risus " +
-            "volutpat sapien, eu tincidunt diam ipsum eget nulla. Cras " +
-            "molestie dapibus commodo. Ut vel tellus at massa gravida " +
-            "semper non sed orci.";
-
-    public void testInputStream() throws Exception {
-        int[] flagses = { Base64.DEFAULT,
-                          Base64.NO_PADDING,
-                          Base64.NO_WRAP,
-                          Base64.NO_PADDING | Base64.NO_WRAP,
-                          Base64.CRLF,
-                          Base64.WEB_SAFE };
-        int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
-        Random rng = new Random(32176L);
-
-        // Test input needs to be at least 2048 bytes to fill up the
-        // read buffer of Base64InputStream.
-        byte[] plain = (lipsum + lipsum + lipsum + lipsum + lipsum).getBytes();
-
-        for (int flags: flagses) {
-            byte[] encoded = Base64.encode(plain, flags);
-
-            ByteArrayInputStream bais;
-            Base64InputStream b64is;
-            byte[] actual = new byte[plain.length * 2];
-            int ap;
-            int b;
-
-            // ----- test decoding ("encoded" -> "plain") -----
-
-            // read as much as it will give us in one chunk
-            bais = new ByteArrayInputStream(encoded);
-            b64is = new Base64InputStream(bais, flags);
-            ap = 0;
-            while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) {
-                ap += b;
-            }
-            assertEquals(actual, ap, plain);
-
-            // read individual bytes
-            bais = new ByteArrayInputStream(encoded);
-            b64is = new Base64InputStream(bais, flags);
-            ap = 0;
-            while ((b = b64is.read()) != -1) {
-                actual[ap++] = (byte) b;
-            }
-            assertEquals(actual, ap, plain);
-
-            // mix reads of variously-sized arrays with one-byte reads
-            bais = new ByteArrayInputStream(encoded);
-            b64is = new Base64InputStream(bais, flags);
-            ap = 0;
-            readloop: while (true) {
-                int l = writeLengths[rng.nextInt(writeLengths.length)];
-                if (l >= 0) {
-                    b = b64is.read(actual, ap, l);
-                    if (b == -1) break readloop;
-                    ap += b;
-                } else {
-                    for (int i = 0; i < -l; ++i) {
-                        if ((b = b64is.read()) == -1) break readloop;
-                        actual[ap++] = (byte) b;
-                    }
-                }
-            }
-            assertEquals(actual, ap, plain);
-
-            // ----- test encoding ("plain" -> "encoded") -----
-
-            // read as much as it will give us in one chunk
-            bais = new ByteArrayInputStream(plain);
-            b64is = new Base64InputStream(bais, flags, true);
-            ap = 0;
-            while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) {
-                ap += b;
-            }
-            assertEquals(actual, ap, encoded);
-
-            // read individual bytes
-            bais = new ByteArrayInputStream(plain);
-            b64is = new Base64InputStream(bais, flags, true);
-            ap = 0;
-            while ((b = b64is.read()) != -1) {
-                actual[ap++] = (byte) b;
-            }
-            assertEquals(actual, ap, encoded);
-
-            // mix reads of variously-sized arrays with one-byte reads
-            bais = new ByteArrayInputStream(plain);
-            b64is = new Base64InputStream(bais, flags, true);
-            ap = 0;
-            readloop: while (true) {
-                int l = writeLengths[rng.nextInt(writeLengths.length)];
-                if (l >= 0) {
-                    b = b64is.read(actual, ap, l);
-                    if (b == -1) break readloop;
-                    ap += b;
-                } else {
-                    for (int i = 0; i < -l; ++i) {
-                        if ((b = b64is.read()) == -1) break readloop;
-                        actual[ap++] = (byte) b;
-                    }
-                }
-            }
-            assertEquals(actual, ap, encoded);
-        }
-    }
-
-    /**
-     * Tests that Base64OutputStream produces exactly the same results
-     * as calling Base64.encode/.decode on an in-memory array.
-     */
-    public void testOutputStream() throws Exception {
-        int[] flagses = { Base64.DEFAULT,
-                          Base64.NO_PADDING,
-                          Base64.NO_WRAP,
-                          Base64.NO_PADDING | Base64.NO_WRAP,
-                          Base64.CRLF,
-                          Base64.WEB_SAFE };
-        int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
-        Random rng = new Random(32176L);
-
-        // Test input needs to be at least 1024 bytes to test filling
-        // up the write(int) buffer of Base64OutputStream.
-        byte[] plain = (lipsum + lipsum).getBytes();
-
-        for (int flags: flagses) {
-            byte[] encoded = Base64.encode(plain, flags);
-
-            ByteArrayOutputStream baos;
-            Base64OutputStream b64os;
-            byte[] actual;
-            int p;
-
-            // ----- test encoding ("plain" -> "encoded") -----
-
-            // one large write(byte[]) of the whole input
-            baos = new ByteArrayOutputStream();
-            b64os = new Base64OutputStream(baos, flags);
-            b64os.write(plain);
-            b64os.close();
-            actual = baos.toByteArray();
-            assertEquals(encoded, actual);
-
-            // many calls to write(int)
-            baos = new ByteArrayOutputStream();
-            b64os = new Base64OutputStream(baos, flags);
-            for (int i = 0; i < plain.length; ++i) {
-                b64os.write(plain[i]);
-            }
-            b64os.close();
-            actual = baos.toByteArray();
-            assertEquals(encoded, actual);
-
-            // intermixed sequences of write(int) with
-            // write(byte[],int,int) of various lengths.
-            baos = new ByteArrayOutputStream();
-            b64os = new Base64OutputStream(baos, flags);
-            p = 0;
-            while (p < plain.length) {
-                int l = writeLengths[rng.nextInt(writeLengths.length)];
-                l = Math.min(l, plain.length-p);
-                if (l >= 0) {
-                    b64os.write(plain, p, l);
-                    p += l;
-                } else {
-                    l = Math.min(-l, plain.length-p);
-                    for (int i = 0; i < l; ++i) {
-                        b64os.write(plain[p+i]);
-                    }
-                    p += l;
-                }
-            }
-            b64os.close();
-            actual = baos.toByteArray();
-            assertEquals(encoded, actual);
-
-            // ----- test decoding ("encoded" -> "plain") -----
-
-            // one large write(byte[]) of the whole input
-            baos = new ByteArrayOutputStream();
-            b64os = new Base64OutputStream(baos, flags, false);
-            b64os.write(encoded);
-            b64os.close();
-            actual = baos.toByteArray();
-            assertEquals(plain, actual);
-
-            // many calls to write(int)
-            baos = new ByteArrayOutputStream();
-            b64os = new Base64OutputStream(baos, flags, false);
-            for (int i = 0; i < encoded.length; ++i) {
-                b64os.write(encoded[i]);
-            }
-            b64os.close();
-            actual = baos.toByteArray();
-            assertEquals(plain, actual);
-
-            // intermixed sequences of write(int) with
-            // write(byte[],int,int) of various lengths.
-            baos = new ByteArrayOutputStream();
-            b64os = new Base64OutputStream(baos, flags, false);
-            p = 0;
-            while (p < encoded.length) {
-                int l = writeLengths[rng.nextInt(writeLengths.length)];
-                l = Math.min(l, encoded.length-p);
-                if (l >= 0) {
-                    b64os.write(encoded, p, l);
-                    p += l;
-                } else {
-                    l = Math.min(-l, encoded.length-p);
-                    for (int i = 0; i < l; ++i) {
-                        b64os.write(encoded[p+i]);
-                    }
-                    p += l;
-                }
-            }
-            b64os.close();
-            actual = baos.toByteArray();
-            assertEquals(plain, actual);
-        }
-    }
-}
