Merge change I75630000 into eclair

* changes:
  Fixing tests that exercise SecurityManager plus stack inspection.
diff --git a/libcore/dalvik/src/main/java/dalvik/system/AllocationLimitError.java b/libcore/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
index 85f7de6..9118199 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
@@ -18,8 +18,9 @@
 
 /**
  * Is thrown when an allocation limit is exceeded.
- * 
- * @since Android 1.0
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public class AllocationLimitError extends VirtualMachineError {
     /**
diff --git a/libcore/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java b/libcore/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
index c85caee..938a5cd 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
@@ -18,8 +18,9 @@
 
 /**
  * Is thrown when the VM identifies a potential deadlock.
- * 
- * @since Android 1.0
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public class PotentialDeadlockError extends VirtualMachineError {
     /**
diff --git a/libcore/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java b/libcore/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
index 44a40a5..ffde7cb 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
@@ -19,6 +19,9 @@
 /**
  * Is thrown when the VM determines that a DEX file's cache is out of date, and
  * that there is no way to recreate it.
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public class StaleDexCacheError extends VirtualMachineError {
     /**
diff --git a/libcore/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java b/libcore/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
index 2f909ac..0e26a70 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
@@ -25,8 +25,9 @@
  * call into this class with an appropriate base directory during its
  * startup, as a reasonably easy way to get the standard property
  * <code>java.io.tmpdir</code> to point at something useful.
- * 
- * @since Android 1.0
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public class TemporaryDirectory {
     /** system property name for the temporary directory */
diff --git a/libcore/dalvik/src/main/java/dalvik/system/TouchDex.java b/libcore/dalvik/src/main/java/dalvik/system/TouchDex.java
index 2dbc3ea..04c6546 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/TouchDex.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/TouchDex.java
@@ -25,13 +25,8 @@
 /**
  * Induces optimization/verification of a set of DEX files.
  *
- * TODO: This class is public, so SystemServer can access it.  This is NOT
- * the correct long-term solution; once we have a real installer and/or
- * dalvik-cache manager, this class should be removed.
- * 
- * @cts See to-do about removing this class...
- * 
- * @since Android 1.0
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public class TouchDex {
 
diff --git a/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java b/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
index bcc8b61..365388a 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -27,8 +27,9 @@
  * <code>android.os.Debug</code>.
  * 
  * @cts Please complete the spec.
- * 
- * @since Android 1.0
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public final class VMDebug {
     /**
diff --git a/libcore/dalvik/src/main/java/dalvik/system/VMRuntime.java b/libcore/dalvik/src/main/java/dalvik/system/VMRuntime.java
index 5d5e600..7ac0849 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/VMRuntime.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/VMRuntime.java
@@ -20,7 +20,10 @@
  * Provides an interface to VM-global, Dalvik-specific features.
  * An application cannot create its own Runtime instance, and must obtain
  * one from the getRuntime method.
- * 
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
+ *
  * @since Android 1.0
  */
 public final class VMRuntime {
@@ -62,6 +65,8 @@
      * be resized so that (size of live objects) / (size of heap) is
      * equal to this number.
      *
+     * <p>This is only a hint to the garbage collector and may be ignored.
+     *
      * @param newTarget the new suggested ideal heap utilization.
      *                  This value may be adjusted internally.
      * @return the previous ideal heap utilization
@@ -98,7 +103,9 @@
      * size, the maximum size will be used.  If size is zero
      * or negative, the minimum size constraint will be removed.
      *
-     * Synchronized to make the order of the exchange reliable.
+     * <p>Synchronized to make the order of the exchange reliable.
+     *
+     * <p>This is only a hint to the garbage collector and may be ignored.
      *
      * @param size the new suggested minimum heap size, in bytes
      * @return the old minimum heap size value
@@ -175,7 +182,7 @@
     /**
      * Returns the number of externally-allocated bytes being tracked by
      * trackExternalAllocation/Free().
-     * 
+     *
      * @return the number of bytes
      */
     public native long getExternalBytesAllocated();
diff --git a/libcore/dalvik/src/main/java/dalvik/system/VMStack.java b/libcore/dalvik/src/main/java/dalvik/system/VMStack.java
index 365613e..b049962 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/VMStack.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/VMStack.java
@@ -19,8 +19,9 @@
 /**
  * Provides a limited interface to the Dalvik VM stack. This class is mostly
  * used for implementing security checks.
- * 
- * @since Android 1.0
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public final class VMStack {
     /**
diff --git a/libcore/dalvik/src/main/java/dalvik/system/Zygote.java b/libcore/dalvik/src/main/java/dalvik/system/Zygote.java
index 9d98bb2..13e7561 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/Zygote.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/Zygote.java
@@ -20,8 +20,9 @@
  * Provides access to the Dalvik "zygote" feature, which allows a VM instance to
  * be partially initialized and then fork()'d from the partially initialized
  * state.
- * 
- * @since Android 1.0
+ *
+ * @deprecated this is an internal Dalvik class that is not appropriate for
+ *      general use. It will be removed from the public API in a future release.
  */
 public class Zygote {
     /*
diff --git a/libcore/luni/src/main/java/java/io/PipedInputStream.java b/libcore/luni/src/main/java/java/io/PipedInputStream.java
index 83987ec..a6b0336 100644
--- a/libcore/luni/src/main/java/java/io/PipedInputStream.java
+++ b/libcore/luni/src/main/java/java/io/PipedInputStream.java
@@ -33,7 +33,22 @@
     private boolean isClosed = false;
 
     /**
-     * The circular buffer through which data is passed.
+     * The circular buffer through which data is passed. Data is read from the
+     * range {@code [out, in)} and written to the range {@code [in, out)}.
+     * Data in the buffer is either sequential: <pre>
+     *     { - - - X X X X X X X - - - - - }
+     *             ^             ^
+     *             |             |
+     *            out           in</pre>
+     * ...or wrapped around the buffer's end: <pre>
+     *     { X X X X - - - - - - - - X X X }
+     *               ^               ^
+     *               |               |
+     *              in              out</pre>
+     * When the buffer is empty, {@code in == -1}. Reading when the buffer is
+     * empty will block until data is available. When the buffer is full,
+     * {@code in == out}. Writing when the buffer is full will block until free
+     * space is available.
      */
     protected byte buffer[];
 
@@ -158,10 +173,14 @@
             throw new IOException(Msg.getString("K0075")); //$NON-NLS-1$
         }
 
-        if (lastWriter != null && !lastWriter.isAlive() && (in < 0)) {
-            // KA030=Write end dead
-            throw new IOException(Msg.getString("KA030")); //$NON-NLS-1$
-        }
+        // BEGIN android-removed
+        // eagerly throwing prevents checking isClosed and returning normally
+        // if (lastWriter != null && !lastWriter.isAlive() && (in < 0)) {
+        //     // KA030=Write end dead
+        //     throw new IOException(Msg.getString("KA030")); //$NON-NLS-1$
+        // }
+        // END android-removed
+
         /**
          * Set the last thread to be reading on this PipedInputStream. If
          * lastReader dies while someone is waiting to write an IOException of
@@ -187,7 +206,8 @@
             throw new InterruptedIOException();
         }
 
-        byte result = buffer[out++];
+        // BEGIN android-changed
+        int result = buffer[out++] & 0xff;
         if (out == buffer.length) {
             out = 0;
         }
@@ -196,7 +216,12 @@
             in = -1;
             out = 0;
         }
-        return result & 0xff;
+
+        // let blocked writers write to the newly available buffer space
+        notifyAll();
+
+        return result;
+        // END android-changed
     }
 
     /**
@@ -261,10 +286,13 @@
             throw new IOException(Msg.getString("K0075")); //$NON-NLS-1$
         }
 
-        if (lastWriter != null && !lastWriter.isAlive() && (in < 0)) {
-            // KA030=Write end dead
-            throw new IOException(Msg.getString("KA030")); //$NON-NLS-1$
-        }
+        // BEGIN android-removed
+        // eagerly throwing prevents checking isClosed and returning normally
+        // if (lastWriter != null && !lastWriter.isAlive() && (in < 0)) {
+        //     // KA030=Write end dead
+        //     throw new IOException(Msg.getString("KA030")); //$NON-NLS-1$
+        // }
+        // END android-removed
 
         /**
          * Set the last thread to be reading on this PipedInputStream. If
@@ -291,13 +319,15 @@
             throw new InterruptedIOException();
         }
 
-        int copyLength = 0;
-        /* Copy bytes from out to end of buffer first */
+        // BEGIN android-changed
+        int totalCopied = 0;
+
+        // copy bytes from out thru the end of buffer
         if (out >= in) {
-            copyLength = count > (buffer.length - out) ? buffer.length - out
-                    : count;
-            System.arraycopy(buffer, out, bytes, offset, copyLength);
-            out += copyLength;
+            int leftInBuffer = buffer.length - out;
+            int length = leftInBuffer < count ? leftInBuffer : count;
+            System.arraycopy(buffer, out, bytes, offset, length);
+            out += length;
             if (out == buffer.length) {
                 out = 0;
             }
@@ -306,28 +336,29 @@
                 in = -1;
                 out = 0;
             }
+            totalCopied += length;
         }
 
-        /*
-         * Did the read fully succeed in the previous copy or is the buffer
-         * empty?
-         */
-        if (copyLength == count || in == -1) {
-            return copyLength;
+        // copy bytes from out thru in
+        if (totalCopied < count && in != -1) {
+            int leftInBuffer = in - out;
+            int leftToCopy = count - totalCopied;
+            int length = leftToCopy < leftInBuffer ? leftToCopy : leftInBuffer;
+            System.arraycopy(buffer, out, bytes, offset + totalCopied, length);
+            out += length;
+            if (out == in) {
+                // empty buffer
+                in = -1;
+                out = 0;
+            }
+            totalCopied += length;
         }
 
-        int bytesCopied = copyLength;
-        /* Copy bytes from 0 to the number of available bytes */
-        copyLength = in - out > (count - bytesCopied) ? count - bytesCopied
-                : in - out;
-        System.arraycopy(buffer, out, bytes, offset + bytesCopied, copyLength);
-        out += copyLength;
-        if (out == in) {
-            // empty buffer
-            in = -1;
-            out = 0;
-        }
-        return bytesCopied + copyLength;
+        // let blocked writers write to the newly available buffer space
+        notifyAll();
+
+        return totalCopied;
+        // END android-changed
     }
 
     /**
@@ -351,9 +382,12 @@
         if (buffer == null || isClosed) {
             throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
         }
-        if (lastReader != null && !lastReader.isAlive()) {
-            throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
-        }
+        // BEGIN android-removed
+        // eagerly throwing causes us to fail even if the buffer's not full
+        // if (lastReader != null && !lastReader.isAlive()) {
+        //     throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
+        // }
+        // END android-removed
         /**
          * Set the last thread to be writing on this PipedInputStream. If
          * lastWriter dies while someone is waiting to read an IOException of
@@ -362,11 +396,14 @@
         lastWriter = Thread.currentThread();
         try {
             while (buffer != null && out == in) {
-                notifyAll();
-                wait(1000);
+                // BEGIN android-changed
+                // moved has-last-reader-died check to be before wait()
                 if (lastReader != null && !lastReader.isAlive()) {
                     throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
                 }
+                notifyAll();
+                wait(1000);
+                // END android-changed
             }
         } catch (InterruptedException e) {
             throw new InterruptedIOException();
@@ -379,7 +416,11 @@
             if (in == buffer.length) {
                 in = 0;
             }
-            return;
+
+            // BEGIN android-added
+            // let blocked readers read the newly available data
+            notifyAll();
+            // END android-added
         }
     }
 
diff --git a/libcore/math/src/main/java/java/math/BitLevel.java b/libcore/math/src/main/java/java/math/BitLevel.java
index 8f3508d..22a486c 100644
--- a/libcore/math/src/main/java/java/math/BitLevel.java
+++ b/libcore/math/src/main/java/java/math/BitLevel.java
@@ -189,6 +189,9 @@
     }
 
     static BigInteger shiftLeftOneBit(BigInteger source) {
+        // BEGIN android-added
+        source.establishOldRepresentation("BitLevel.shiftLeftOneBit");
+        // END android-added
         int srcLen = source.numberLength;
         int resLen = srcLen + 1;
         int resDigits[] = new int[resLen];