diff --git a/src/com/android/calculator2/Calculator.java b/src/com/android/calculator2/Calculator.java
index 4eecb50..035f5b9 100644
--- a/src/com/android/calculator2/Calculator.java
+++ b/src/com/android/calculator2/Calculator.java
@@ -991,7 +991,7 @@
                 setState(CalculatorState.INPUT);
                 mEvaluator.clear();
             }
-            mEvaluator.addSaved();
+            mEvaluator.appendSaved();
             redisplayAfterFormulaChange();
         } else {
             addChars(item.coerceToText(this).toString(), false);
diff --git a/src/com/android/calculator2/CalculatorExpr.java b/src/com/android/calculator2/CalculatorExpr.java
index 8a008b8..b387e8b 100644
--- a/src/com/android/calculator2/CalculatorExpr.java
+++ b/src/com/android/calculator2/CalculatorExpr.java
@@ -36,9 +36,19 @@
 import java.util.HashMap;
 import java.util.IdentityHashMap;
 
-// A mathematical expression represented as a sequence of "tokens".
-// Many tokes are represented by button ids for the corresponding operator.
-// Parsed only when we evaluate the expression using the "eval" method.
+/**
+ * A mathematical expression represented as a sequence of "tokens".
+ * Many tokens are represented by button ids for the corresponding operator.
+ * A token may also represent the result of a previously evaluated expression.
+ * The add() method adds a token to the end of the expression.  The delete method() removes one.
+ * Clear() deletes the entire expression contents. Eval() evaluates the expression,
+ * producing both a constructive real (CR), and possibly a BoundedRational result.
+ * Expressions are parsed only during evaluation; no explicit parse tree is maintained.
+ *
+ * The write() method is used to save the current expression.  Note that CR provides no
+ * serialization facility.  Thus we save all previously computed values by writing out the
+ * expression that was used to compute them, and reevaluate on input.
+ */
 class CalculatorExpr {
     private ArrayList<Token> mExpr;  // The actual representation
                                      // as a list of tokens.  Constant
@@ -66,41 +76,45 @@
         abstract CharSequence toCharSequence(Context context);
     }
 
-    // An operator token
+    /**
+     * Representation of an operator token
+     */
     private static class Operator extends Token {
-	final int mId; // We use the button resource id
+        public final int id; // We use the button resource id
         Operator(int resId) {
-	    mId = resId;
+            id = resId;
         }
         Operator(DataInput in) throws IOException {
-            mId = in.readInt();
+            id = in.readInt();
         }
         @Override
         void write(DataOutput out) throws IOException {
             out.writeByte(TokenKind.OPERATOR.ordinal());
-            out.writeInt(mId);
+            out.writeInt(id);
         }
         @Override
         public CharSequence toCharSequence(Context context) {
-            String desc = KeyMaps.toDescriptiveString(context, mId);
+            String desc = KeyMaps.toDescriptiveString(context, id);
             if (desc != null) {
-                SpannableString result = new SpannableString(KeyMaps.toString(context, mId));
+                SpannableString result = new SpannableString(KeyMaps.toString(context, id));
                 Object descSpan = new TtsSpan.TextBuilder(desc).build();
                 result.setSpan(descSpan, 0, result.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                 return result;
             } else {
-                return KeyMaps.toString(context, mId);
+                return KeyMaps.toString(context, id);
             }
         }
         @Override
         TokenKind kind() { return TokenKind.OPERATOR; }
     }
 
-    // A (possibly incomplete) numerical constant.
-    // Supports addition and removal of trailing characters; hence mutable.
+    /**
+     * Representation of a (possibly incomplete) numerical constant.
+     * Supports addition and removal of trailing characters; hence mutable.
+     */
     private static class Constant extends Token implements Cloneable {
         private boolean mSawDecimal;
-        String mWhole;  // String preceding decimal point.
+        private String mWhole;  // String preceding decimal point.
         private String mFraction; // String after decimal point.
         private int mExponent;  // Explicit exponent, only generated through addExponent.
 
@@ -132,7 +146,7 @@
         // Just return false if this was the second (or later) decimal point
         // in this constant.
         // Assumes that this constant does not have an exponent.
-        boolean add(int id) {
+        public boolean add(int id) {
             if (id == R.id.dec_point) {
                 if (mSawDecimal || mExponent != 0) return false;
                 mSawDecimal = true;
@@ -159,14 +173,16 @@
             return true;
         }
 
-        void addExponent(int exp) {
+        public void addExponent(int exp) {
             // Note that adding a 0 exponent is a no-op.  That's OK.
             mExponent = exp;
         }
 
-        // Undo the last add.
-        // Assumes the constant is nonempty.
-        void delete() {
+        /**
+         * Undo the last add or remove last exponent digit.
+         * Assumes the constant is nonempty.
+         */
+        public void delete() {
             if (mExponent != 0) {
                 mExponent /= 10;
                 // Once zero, it can only be added back with addExponent.
@@ -179,12 +195,14 @@
             }
         }
 
-        boolean isEmpty() {
+        public boolean isEmpty() {
             return (mSawDecimal == false && mWhole.isEmpty());
         }
 
-        // Produces human-readable string, as typed.
-        // Result is internationalized.
+        /**
+         * Produce human-readable string representation of constant, as typed.
+         * Result is internationalized.
+         */
         @Override
         public String toString() {
             String result = mWhole;
@@ -198,7 +216,10 @@
             return KeyMaps.translateResult(result);
         }
 
-        // Return non-null BoundedRational representation.
+        /**
+         * Return BoundedRational representation of constant.
+         * Never null.
+         */
         public BoundedRational toRational() {
             String whole = mWhole;
             if (whole.isEmpty()) whole = "0";
@@ -214,73 +235,75 @@
         }
 
         @Override
-        CharSequence toCharSequence(Context context) {
+        public CharSequence toCharSequence(Context context) {
             return toString();
         }
 
         @Override
-        TokenKind kind() { return TokenKind.CONSTANT; }
+        public TokenKind kind() {
+            return TokenKind.CONSTANT;
+        }
 
         // Override clone to make it public
         @Override
         public Object clone() {
-            Constant res = new Constant();
-            res.mWhole = mWhole;
-            res.mFraction = mFraction;
-            res.mSawDecimal = mSawDecimal;
-            res.mExponent = mExponent;
-            return res;
+            Constant result = new Constant();
+            result.mWhole = mWhole;
+            result.mFraction = mFraction;
+            result.mSawDecimal = mSawDecimal;
+            result.mExponent = mExponent;
+            return result;
         }
     }
 
-    // Hash maps used to detect duplicate subexpressions when
-    // we write out CalculatorExprs and read them back in.
+    // Hash maps used to detect duplicate subexpressions when we write out CalculatorExprs and
+    // read them back in.
     private static final ThreadLocal<IdentityHashMap<CR,Integer>>outMap =
-                new ThreadLocal<IdentityHashMap<CR,Integer>>();
+            new ThreadLocal<IdentityHashMap<CR,Integer>>();
         // Maps expressions to indices on output
     private static final ThreadLocal<HashMap<Integer,PreEval>>inMap =
-                new ThreadLocal<HashMap<Integer,PreEval>>();
+            new ThreadLocal<HashMap<Integer,PreEval>>();
         // Maps expressions to indices on output
-    private static final ThreadLocal<Integer> exprIndex =
-                new ThreadLocal<Integer>();
+    private static final ThreadLocal<Integer> exprIndex = new ThreadLocal<Integer>();
 
-    static void initExprOutput() {
+    /**
+     * Prepare for expression output.
+     * Initializes map that will lbe used to avoid duplicating shared subexpressions.
+     * This avoids a potential exponential blow-up in the expression size.
+     */
+    public static void initExprOutput() {
         outMap.set(new IdentityHashMap<CR,Integer>());
         exprIndex.set(Integer.valueOf(0));
     }
 
-    static void initExprInput() {
+    /**
+     * Prepare for expression input.
+     * Initializes map that will be used to reconstruct shared subexpressions.
+     */
+    public static void initExprInput() {
         inMap.set(new HashMap<Integer,PreEval>());
     }
 
-    // We treat previously evaluated subexpressions as tokens
-    // These are inserted when either:
-    //    - We continue an expression after evaluating some of it.
-    //    - TODO: When we copy/paste expressions.
-    // The representation includes three different representations
-    // of the expression:
-    //  1) The CR value for use in computation.
-    //  2) The integer value for use in the computations,
-    //     if the expression evaluates to an integer.
-    //  3a) The corresponding CalculatorExpr, together with
-    //  3b) The context (currently just deg/rad mode) used to evaluate
-    //      the expression.
-    //  4) A short string representation that is used to
-    //     Display the expression.
-    //
-    // (3) is present only so that we can persist the object.
-    // (4) is stored explicitly to avoid waiting for recomputation in the UI
-    //       thread.
+    /**
+     * The "token" class for previously evaluated subexpressions.
+     * We treat previously evaluated subexpressions as tokens.  These are inserted when we either
+     * continue an expression after evaluating some of it, or copy an expression and paste it back
+     * in.
+     * The representation includes both CR and possibly BoundedRational values.  In order to
+     * support saving and restoring, we also include the underlying expression itself, and the
+     * context (currently just degree mode) used to evaluate it.  The short string representation
+     * is also stored in order to avoid potentially expensive recomputation in the UI thread.
+     */
     private static class PreEval extends Token {
-        final CR mValue;
-        final BoundedRational mRatValue;
+        public final CR value;
+        public final BoundedRational ratValue;
         private final CalculatorExpr mExpr;
         private final EvalContext mContext;
         private final String mShortRep;  // Not internationalized.
         PreEval(CR val, BoundedRational ratVal, CalculatorExpr expr,
                 EvalContext ec, String shortRep) {
-            mValue = val;
-            mRatValue = ratVal;
+            value = val;
+            ratValue = ratVal;
             mExpr = expr;
             mContext = ec;
             mShortRep = shortRep;
@@ -293,13 +316,13 @@
         // The parameter hash map maps expressions we've seen
         // before to their index.
         @Override
-        void write(DataOutput out) throws IOException {
+        public void write(DataOutput out) throws IOException {
             out.writeByte(TokenKind.PRE_EVAL.ordinal());
-            Integer index = outMap.get().get(mValue);
+            Integer index = outMap.get().get(value);
             if (index == null) {
                 int nextIndex = exprIndex.get() + 1;
                 exprIndex.set(nextIndex);
-                outMap.get().put(mValue, nextIndex);
+                outMap.get().put(value, nextIndex);
                 out.writeInt(nextIndex);
                 mExpr.write(out);
                 mContext.write(out);
@@ -315,13 +338,10 @@
             if (prev == null) {
                 mExpr = new CalculatorExpr(in);
                 mContext = new EvalContext(in, mExpr.mExpr.size());
-                // Recompute other fields
-                // We currently do this in the UI thread, but we
-                // only create PreEval expressions that were
-                // previously successfully evaluated, and thus
-                // don't diverge.  We also only evaluate to a
-                // constructive real, which involves substantial
-                // work only in fairly contrived circumstances.
+                // Recompute other fields We currently do this in the UI thread, but we only
+                // create PreEval expressions that were previously successfully evaluated, and
+                // thus don't diverge.  We also only evaluate to a constructive real, which
+                // involves substantial work only in fairly contrived circumstances.
                 // TODO: Deal better with slow evaluations.
                 EvalRet res = null;
                 try {
@@ -331,32 +351,35 @@
                     // expressions that can be evaluated.
                     Log.e("Calculator", "Unexpected syntax exception" + e);
                 }
-                mValue = res.mVal;
-                mRatValue = res.mRatVal;
+                value = res.val;
+                ratValue = res.ratVal;
                 mShortRep = in.readUTF();
                 inMap.get().put(index, this);
             } else {
-                mValue = prev.mValue;
-                mRatValue = prev.mRatValue;
+                value = prev.value;
+                ratValue = prev.ratValue;
                 mExpr = prev.mExpr;
                 mContext = prev.mContext;
                 mShortRep = prev.mShortRep;
             }
         }
         @Override
-        CharSequence toCharSequence(Context context) {
+        public CharSequence toCharSequence(Context context) {
             return KeyMaps.translateResult(mShortRep);
         }
         @Override
-        TokenKind kind() {
+        public TokenKind kind() {
             return TokenKind.PRE_EVAL;
         }
-        boolean hasEllipsis() {
+        public boolean hasEllipsis() {
             return mShortRep.lastIndexOf(KeyMaps.ELLIPSIS) != -1;
         }
     }
 
-    static Token newToken(DataInput in) throws IOException {
+    /**
+     * Read token from in.
+     */
+    public static Token newToken(DataInput in) throws IOException {
         TokenKind kind = tokenKindValues[in.readByte()];
         switch(kind) {
         case CONSTANT:
@@ -377,6 +400,9 @@
         mExpr = expr;
     }
 
+    /**
+     * Construct CalculatorExpr, by reading it from in.
+     */
     CalculatorExpr(DataInput in) throws IOException {
         mExpr = new ArrayList<Token>();
         int size = in.readInt();
@@ -385,7 +411,10 @@
         }
     }
 
-    void write(DataOutput out) throws IOException {
+    /**
+     * Write this expression to out.
+     */
+    public void write(DataOutput out) throws IOException {
         int size = mExpr.size();
         out.writeInt(size);
         for (int i = 0; i < size; ++i) {
@@ -393,6 +422,10 @@
         }
     }
 
+    /**
+     * Does this expression end with a numeric constant?
+     * As opposed to an operator or preevaluated expression.
+     */
     boolean hasTrailingConstant() {
         int s = mExpr.size();
         if (s == 0) {
@@ -402,13 +435,16 @@
         return t instanceof Constant;
     }
 
+    /**
+     * Does this expression end with a binary operator?
+     */
     private boolean hasTrailingBinary() {
         int s = mExpr.size();
         if (s == 0) return false;
         Token t = mExpr.get(s-1);
         if (!(t instanceof Operator)) return false;
         Operator o = (Operator)t;
-        return (KeyMaps.isBinary(o.mId));
+        return (KeyMaps.isBinary(o.id));
     }
 
     /**
@@ -420,10 +456,10 @@
      */
     boolean add(int id) {
         int s = mExpr.size();
-        int d = KeyMaps.digVal(id);
-        boolean binary = KeyMaps.isBinary(id);
+        final int d = KeyMaps.digVal(id);
+        final boolean binary = KeyMaps.isBinary(id);
         Token lastTok = s == 0 ? null : mExpr.get(s-1);
-        int lastOp = lastTok instanceof Operator ? ((Operator) lastTok).mId : 0;
+        int lastOp = lastTok instanceof Operator ? ((Operator) lastTok).id : 0;
         // Quietly replace a trailing binary operator with another one, unless the second
         // operator is minus, in which case we just allow it as a unary minus.
         if (binary && !KeyMaps.isPrefix(id)) {
@@ -436,7 +472,7 @@
             }
             // s invalid and not used below.
         }
-        boolean isConstPiece = (d != KeyMaps.NOT_DIGIT || id == R.id.dec_point);
+        final boolean isConstPiece = (d != KeyMaps.NOT_DIGIT || id == R.id.dec_point);
         if (isConstPiece) {
             // Since we treat juxtaposition as multiplication, a constant can appear anywhere.
             if (s == 0) {
@@ -476,35 +512,37 @@
     void removeTrailingAdditiveOperators() {
         while (true) {
             int s = mExpr.size();
-            if (s == 0) break;
+            if (s == 0) {
+                break;
+            }
             Token lastTok = mExpr.get(s-1);
-            if (!(lastTok instanceof Operator)) break;
-            int lastOp = ((Operator) lastTok).mId;
-            if (lastOp != R.id.op_add && lastOp != R.id.op_sub) break;
+            if (!(lastTok instanceof Operator)) {
+                break;
+            }
+            int lastOp = ((Operator) lastTok).id;
+            if (lastOp != R.id.op_add && lastOp != R.id.op_sub) {
+                break;
+            }
             delete();
         }
     }
 
-    // Append the contents of the argument expression.
-    // It is assumed that the argument expression will not change,
-    // and thus its pieces can be reused directly.
-    // TODO: We probably only need this for expressions consisting of
-    // a single PreEval "token", and may want to check that.
-    void append(CalculatorExpr expr2) {
-        // Check that we're not concatenating Constant or PreEval
-        // tokens, since the result would look like a single constant
+    /**
+     * Append the contents of the argument expression.
+     * It is assumed that the argument expression will not change, and thus its pieces can be
+     * reused directly.
+     */
+    public void append(CalculatorExpr expr2) {
         int s = mExpr.size();
         int s2 = expr2.mExpr.size();
-        // Check that we're not concatenating Constant or PreEval
-        // tokens, since the result would look like a single constant,
-        // with very mysterious results for the user.
+        // Check that we're not concatenating Constant or PreEval tokens, since the result would
+        // look like a single constant, with very mysterious results for the user.
         if (s != 0 && s2 != 0) {
             Token last = mExpr.get(s-1);
             Token first = expr2.mExpr.get(0);
             if (!(first instanceof Operator) && !(last instanceof Operator)) {
-                // Fudge it by adding an explicit multiplication.
-                // We would have interpreted it as such anyway, and this
-                // makes it recognizable to the user.
+                // Fudge it by adding an explicit multiplication.  We would have interpreted it as
+                // such anyway, and this makes it recognizable to the user.
                 mExpr.add(new Operator(R.id.op_mul));
             }
         }
@@ -513,83 +551,97 @@
         }
     }
 
-    // Undo the last key addition, if any.
-    void delete() {
-        int s = mExpr.size();
-        if (s == 0) return;
+    /**
+     * Undo the last key addition, if any.
+     * Or possibly remove a trailing exponent digit.
+     */
+    public void delete() {
+        final int s = mExpr.size();
+        if (s == 0) {
+            return;
+        }
         Token last = mExpr.get(s-1);
         if (last instanceof Constant) {
             Constant c = (Constant)last;
             c.delete();
-            if (!c.isEmpty()) return;
+            if (!c.isEmpty()) {
+                return;
+            }
         }
         mExpr.remove(s-1);
     }
 
-    void clear() {
+    /**
+     * Remove all tokens from the expression.
+     */
+    public void clear() {
         mExpr.clear();
     }
 
-    boolean isEmpty() {
+    public boolean isEmpty() {
         return mExpr.isEmpty();
     }
 
-    // Returns a logical deep copy of the CalculatorExpr.
-    // Operator and PreEval tokens are immutable, and thus
-    // aren't really copied.
+    /**
+     * Returns a logical deep copy of the CalculatorExpr.
+     * Operator and PreEval tokens are immutable, and thus aren't really copied.
+     */
     public Object clone() {
-        CalculatorExpr res = new CalculatorExpr();
+        CalculatorExpr result = new CalculatorExpr();
         for (Token t: mExpr) {
             if (t instanceof Constant) {
-                res.mExpr.add((Token)(((Constant)t).clone()));
+                result.mExpr.add((Token)(((Constant)t).clone()));
             } else {
-                res.mExpr.add(t);
+                result.mExpr.add(t);
             }
         }
-        return res;
+        return result;
     }
 
     // Am I just a constant?
-    boolean isConstant() {
-        if (mExpr.size() != 1) return false;
+    public boolean isConstant() {
+        if (mExpr.size() != 1) {
+            return false;
+        }
         return mExpr.get(0) instanceof Constant;
     }
 
-    // Return a new expression consisting of a single PreEval token
-    // representing the current expression.
-    // The caller supplies the value, degree mode, and short
-    // string representation, which must have been previously computed.
-    // Thus this is guaranteed to terminate reasonably quickly.
-    CalculatorExpr abbreviate(CR val, BoundedRational ratVal,
+    /**
+     * Return a new expression consisting of a single token representing the current pre-evaluated
+     * expression.
+     * The caller supplies the value, degree mode, and short string representation, which must
+     * have been previously computed.  Thus this is guaranteed to terminate reasonably quickly.
+     */
+    public CalculatorExpr abbreviate(CR val, BoundedRational ratVal,
                               boolean dm, String sr) {
         CalculatorExpr result = new CalculatorExpr();
-        Token t = new PreEval(val, ratVal,
-                              new CalculatorExpr(
-                                        (ArrayList<Token>)mExpr.clone()),
-                              new EvalContext(dm, mExpr.size()), sr);
+        Token t = new PreEval(val, ratVal, new CalculatorExpr((ArrayList<Token>) mExpr.clone()),
+                new EvalContext(dm, mExpr.size()), sr);
         result.mExpr.add(t);
         return result;
     }
 
-    // Internal evaluation functions return an EvalRet triple.
-    // We compute rational (BoundedRational) results when possible, both as
-    // a performance optimization, and to detect errors exactly when we can.
-    private class EvalRet {
-        int mPos; // Next position (expression index) to be parsed
-        final CR mVal; // Constructive Real result of evaluating subexpression
-        final BoundedRational mRatVal;  // Exact Rational value or null if
-                                        // irrational or hard to compute.
+    /**
+     * Internal evaluation functions return an EvalRet triple.
+     * We compute rational (BoundedRational) results when possible, both as a performance
+     * optimization, and to detect errors exactly when we can.
+     */
+    private static class EvalRet {
+        public int pos; // Next position (expression index) to be parsed.
+        public final CR val; // Constructive Real result of evaluating subexpression.
+        public final BoundedRational ratVal;  // Exact Rational value or null.
         EvalRet(int p, CR v, BoundedRational r) {
-            mPos = p;
-            mVal = v;
-            mRatVal = r;
+            pos = p;
+            val = v;
+            ratVal = r;
         }
     }
 
-    // And take a context argument:
+    /**
+     * Internal evaluation functions take an EvalContext argument.
+     */
     private static class EvalContext {
-        public final int mPrefixLength; // Length of prefix to evaluate.
-                            // Not explicitly saved.
+        public final int mPrefixLength; // Length of prefix to evaluate. Not explicitly saved.
         public final boolean mDegreeMode;
         // If we add any other kinds of evaluation modes, they go here.
         EvalContext(boolean degreeMode, int len) {
@@ -625,22 +677,25 @@
         }
     }
 
-    // The following methods can all throw IndexOutOfBoundsException
-    // in the event of a syntax error.  We expect that to be caught in
-    // eval below.
+    // The following methods can all throw IndexOutOfBoundsException in the event of a syntax
+    // error.  We expect that to be caught in eval below.
 
     private boolean isOperatorUnchecked(int i, int op) {
         Token t = mExpr.get(i);
-        if (!(t instanceof Operator)) return false;
-        return ((Operator)(t)).mId == op;
+        if (!(t instanceof Operator)) {
+            return false;
+        }
+        return ((Operator)(t)).id == op;
     }
 
     private boolean isOperator(int i, int op, EvalContext ec) {
-        if (i >= ec.mPrefixLength) return false;
+        if (i >= ec.mPrefixLength) {
+            return false;
+        }
         return isOperatorUnchecked(i, op);
     }
 
-    static class SyntaxException extends Exception {
+    public static class SyntaxException extends Exception {
         public SyntaxException() {
             super();
         }
@@ -649,27 +704,26 @@
         }
     }
 
-    // The following functions all evaluate some kind of expression
-    // starting at position i in mExpr in a specified evaluation context.
-    // They return both the expression value (as constructive real and,
-    // if applicable, as BigInteger) and the position of the next token
+    // The following functions all evaluate some kind of expression starting at position i in
+    // mExpr in a specified evaluation context.  They return both the expression value (as
+    // constructive real and, if applicable, as BoundedRational) and the position of the next token
     // that was not used as part of the evaluation.
+    // This is essentially a simple recursive descent parser combined with expression evaluation.
+
     private EvalRet evalUnary(int i, EvalContext ec) throws SyntaxException {
-        Token t = mExpr.get(i);
+        final Token t = mExpr.get(i);
         BoundedRational ratVal;
-        CR value;
         if (t instanceof Constant) {
             Constant c = (Constant)t;
             ratVal = c.toRational();
-            value = ratVal.CRValue();
-            return new EvalRet(i+1, value, ratVal);
+            return new EvalRet(i+1, ratVal.CRValue(), ratVal);
         }
         if (t instanceof PreEval) {
-            PreEval p = (PreEval)t;
-            return new EvalRet(i+1, p.mValue, p.mRatValue);
+            final PreEval p = (PreEval)t;
+            return new EvalRet(i+1, p.value, p.ratValue);
         }
         EvalRet argVal;
-        switch(((Operator)(t)).mId) {
+        switch(((Operator)(t)).id) {
         case R.id.const_pi:
             return new EvalRet(i+1, CR.PI, null);
         case R.id.const_e:
@@ -680,111 +734,144 @@
             // Does seem to accept a leading minus.
             if (isOperator(i+1, R.id.op_sub, ec)) {
                 argVal = evalUnary(i+2, ec);
-                ratVal = BoundedRational.sqrt(
-                                BoundedRational.negate(argVal.mRatVal));
-                if (ratVal != null) break;
-                return new EvalRet(argVal.mPos,
-                                   argVal.mVal.negate().sqrt(), null);
+                ratVal = BoundedRational.sqrt(BoundedRational.negate(argVal.ratVal));
+                if (ratVal != null) {
+                    break;
+                }
+                return new EvalRet(argVal.pos,
+                                   argVal.val.negate().sqrt(), null);
             } else {
                 argVal = evalUnary(i+1, ec);
-                ratVal = BoundedRational.sqrt(argVal.mRatVal);
-                if (ratVal != null) break;
-                return new EvalRet(argVal.mPos, argVal.mVal.sqrt(), null);
+                ratVal = BoundedRational.sqrt(argVal.ratVal);
+                if (ratVal != null) {
+                    break;
+                }
+                return new EvalRet(argVal.pos, argVal.val.sqrt(), null);
             }
         case R.id.lparen:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            return new EvalRet(argVal.mPos, argVal.mVal, argVal.mRatVal);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            return new EvalRet(argVal.pos, argVal.val, argVal.ratVal);
         case R.id.fun_sin:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = ec.mDegreeMode ? BoundedRational.degreeSin(argVal.mRatVal)
-                                     : BoundedRational.sin(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos,
-                    toRadians(argVal.mVal,ec).sin(), null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = ec.mDegreeMode ? BoundedRational.degreeSin(argVal.ratVal)
+                                     : BoundedRational.sin(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos, toRadians(argVal.val,ec).sin(), null);
         case R.id.fun_cos:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = ec.mDegreeMode ? BoundedRational.degreeCos(argVal.mRatVal)
-                                     : BoundedRational.cos(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos,
-                    toRadians(argVal.mVal,ec).cos(), null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = ec.mDegreeMode ? BoundedRational.degreeCos(argVal.ratVal)
+                                     : BoundedRational.cos(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos, toRadians(argVal.val,ec).cos(), null);
         case R.id.fun_tan:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = ec.mDegreeMode ? BoundedRational.degreeTan(argVal.mRatVal)
-                                     : BoundedRational.tan(argVal.mRatVal);
-            if (ratVal != null) break;
-            CR argCR = toRadians(argVal.mVal, ec);
-            return new EvalRet(argVal.mPos,
-                    argCR.sin().divide(argCR.cos()), null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = ec.mDegreeMode ? BoundedRational.degreeTan(argVal.ratVal)
+                                     : BoundedRational.tan(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            CR argCR = toRadians(argVal.val, ec);
+            return new EvalRet(argVal.pos, argCR.sin().divide(argCR.cos()), null);
         case R.id.fun_ln:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = BoundedRational.ln(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos, argVal.mVal.ln(), null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = BoundedRational.ln(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos, argVal.val.ln(), null);
         case R.id.fun_exp:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = BoundedRational.exp(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos, argVal.mVal.exp(), null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = BoundedRational.exp(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos, argVal.val.exp(), null);
         case R.id.fun_log:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = BoundedRational.log(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos,
-                               argVal.mVal.ln().divide(CR.valueOf(10).ln()),
-                               null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = BoundedRational.log(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos, argVal.val.ln().divide(CR.valueOf(10).ln()), null);
         case R.id.fun_arcsin:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = ec.mDegreeMode ? BoundedRational.degreeAsin(argVal.mRatVal)
-                                     : BoundedRational.asin(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos,
-                               fromRadians(UnaryCRFunction
-                                   .asinFunction.execute(argVal.mVal),ec),
-                               null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = ec.mDegreeMode ? BoundedRational.degreeAsin(argVal.ratVal)
+                                     : BoundedRational.asin(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos,
+                    fromRadians(UnaryCRFunction.asinFunction.execute(argVal.val),ec), null);
         case R.id.fun_arccos:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = ec.mDegreeMode ? BoundedRational.degreeAcos(argVal.mRatVal)
-                                     : BoundedRational.acos(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos,
-                               fromRadians(UnaryCRFunction
-                                   .acosFunction.execute(argVal.mVal),ec),
-                               null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = ec.mDegreeMode ? BoundedRational.degreeAcos(argVal.ratVal)
+                                     : BoundedRational.acos(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos,
+                    fromRadians(UnaryCRFunction.acosFunction.execute(argVal.val),ec), null);
         case R.id.fun_arctan:
             argVal = evalExpr(i+1, ec);
-            if (isOperator(argVal.mPos, R.id.rparen, ec)) argVal.mPos++;
-            ratVal = ec.mDegreeMode ? BoundedRational.degreeAtan(argVal.mRatVal)
-                                     : BoundedRational.atan(argVal.mRatVal);
-            if (ratVal != null) break;
-            return new EvalRet(argVal.mPos,
-                               fromRadians(UnaryCRFunction
-                                   .atanFunction.execute(argVal.mVal),ec),
-                               null);
+            if (isOperator(argVal.pos, R.id.rparen, ec)) {
+                argVal.pos++;
+            }
+            ratVal = ec.mDegreeMode ? BoundedRational.degreeAtan(argVal.ratVal)
+                                     : BoundedRational.atan(argVal.ratVal);
+            if (ratVal != null) {
+                break;
+            }
+            return new EvalRet(argVal.pos,
+                    fromRadians(UnaryCRFunction.atanFunction.execute(argVal.val),ec), null);
         default:
             throw new SyntaxException("Unrecognized token in expression");
         }
         // We have a rational value.
-        return new EvalRet(argVal.mPos, ratVal.CRValue(), ratVal);
+        return new EvalRet(argVal.pos, ratVal.CRValue(), ratVal);
     }
 
-    // Compute an integral power of a constructive real.
-    // Unlike the "general" case using logarithms, this handles a negative
-    // base.
+    /**
+     * Compute an integral power of a constructive real.
+     * Unlike the "general" case using logarithms, this handles a negative base.
+     */
     private static CR pow(CR base, BigInteger exp) {
         if (exp.compareTo(BigInteger.ZERO) < 0) {
             return pow(base, exp.negate()).inverse();
         }
-        if (exp.equals(BigInteger.ONE)) return base;
+        if (exp.equals(BigInteger.ONE)) {
+            return base;
+        }
         if (exp.and(BigInteger.ONE).intValue() == 1) {
             return pow(base, exp.subtract(BigInteger.ONE)).multiply(base);
         }
@@ -795,24 +882,23 @@
         return tmp.multiply(tmp);
     }
 
+    // Number of bits past binary point to test for integer-ness.
     private static final int TEST_PREC = -100;
-                     // Test for integer-ness to 100 bits past binary point.
     private static final BigInteger MASK =
             BigInteger.ONE.shiftLeft(-TEST_PREC).subtract(BigInteger.ONE);
     private static final CR REAL_E = CR.valueOf(1).exp();
     private static final CR REAL_ONE_HUNDREDTH = CR.valueOf(100).inverse();
-    private static final BoundedRational RATIONAL_ONE_HUNDREDTH =
-            new BoundedRational(1,100);
+    private static final BoundedRational RATIONAL_ONE_HUNDREDTH = new BoundedRational(1,100);
     private static boolean isApprInt(CR x) {
         BigInteger appr = x.get_appr(TEST_PREC);
         return appr.and(MASK).signum() == 0;
     }
 
     private EvalRet evalSuffix(int i, EvalContext ec) throws SyntaxException {
-        EvalRet tmp = evalUnary(i, ec);
-        int cpos = tmp.mPos;
-        CR cval = tmp.mVal;
-        BoundedRational ratVal = tmp.mRatVal;
+        final EvalRet tmp = evalUnary(i, ec);
+        int cpos = tmp.pos;
+        CR crVal = tmp.val;
+        BoundedRational ratVal = tmp.ratVal;
         boolean isFact;
         boolean isSquared = false;
         while ((isFact = isOperator(cpos, R.id.op_fact, ec)) ||
@@ -820,46 +906,45 @@
                 isOperator(cpos, R.id.op_pct, ec)) {
             if (isFact) {
                 if (ratVal == null) {
-                    // Assume it was an integer, but we
-                    // didn't figure it out.
+                    // Assume it was an integer, but we didn't figure it out.
                     // KitKat may have used the Gamma function.
-                    if (!isApprInt(cval)) {
+                    if (!isApprInt(crVal)) {
                         throw new ArithmeticException("factorial(non-integer)");
                     }
-                    ratVal = new BoundedRational(cval.BigIntegerValue());
+                    ratVal = new BoundedRational(crVal.BigIntegerValue());
                 }
                 ratVal = BoundedRational.fact(ratVal);
-                cval = ratVal.CRValue();
+                crVal = ratVal.CRValue();
             } else if (isSquared) {
                 ratVal = BoundedRational.multiply(ratVal, ratVal);
                 if (ratVal == null) {
-                    cval = cval.multiply(cval);
+                    crVal = crVal.multiply(crVal);
                 } else {
-                    cval = ratVal.CRValue();
+                    crVal = ratVal.CRValue();
                 }
             } else /* percent */ {
                 ratVal = BoundedRational.multiply(ratVal, RATIONAL_ONE_HUNDREDTH);
                 if (ratVal == null) {
-                    cval = cval.multiply(REAL_ONE_HUNDREDTH);
+                    crVal = crVal.multiply(REAL_ONE_HUNDREDTH);
                 } else {
-                    cval = ratVal.CRValue();
+                    crVal = ratVal.CRValue();
                 }
             }
             ++cpos;
         }
-        return new EvalRet(cpos, cval, ratVal);
+        return new EvalRet(cpos, crVal, ratVal);
     }
 
     private EvalRet evalFactor(int i, EvalContext ec) throws SyntaxException {
         final EvalRet result1 = evalSuffix(i, ec);
-        int cpos = result1.mPos;  // current position
-        CR cval = result1.mVal;   // value so far
-        BoundedRational ratVal = result1.mRatVal;  // int value so far
+        int cpos = result1.pos;  // current position
+        CR crVal = result1.val;   // value so far
+        BoundedRational ratVal = result1.ratVal;  // int value so far
         if (isOperator(cpos, R.id.op_pow, ec)) {
-            final EvalRet exp = evalSignedFactor(cpos+1, ec);
-            cpos = exp.mPos;
+            final EvalRet exp = evalSignedFactor(cpos + 1, ec);
+            cpos = exp.pos;
             // Try completely rational evaluation first.
-            ratVal = BoundedRational.pow(ratVal, exp.mRatVal);
+            ratVal = BoundedRational.pow(ratVal, exp.ratVal);
             if (ratVal != null) {
                 return new EvalRet(cpos, ratVal.CRValue(), ratVal);
             }
@@ -867,33 +952,33 @@
             // Thus we handle that case separately.
             // We punt if the exponent is an integer computed from irrational
             // values.  That wouldn't work reliably with floating point either.
-            BigInteger int_exp = BoundedRational.asBigInteger(exp.mRatVal);
+            BigInteger int_exp = BoundedRational.asBigInteger(exp.ratVal);
             if (int_exp != null) {
-                cval = pow(cval, int_exp);
+                crVal = pow(crVal, int_exp);
             } else {
-                cval = cval.ln().multiply(exp.mVal).exp();
+                crVal = crVal.ln().multiply(exp.val).exp();
             }
             ratVal = null;
         }
-        return new EvalRet(cpos, cval, ratVal);
+        return new EvalRet(cpos, crVal, ratVal);
     }
 
     private EvalRet evalSignedFactor(int i, EvalContext ec) throws SyntaxException {
         final boolean negative = isOperator(i, R.id.op_sub, ec);
         int cpos = negative ? i + 1 : i;
         EvalRet tmp = evalFactor(cpos, ec);
-        cpos = tmp.mPos;
-        CR cval = negative ? tmp.mVal.negate() : tmp.mVal;
-        BoundedRational ratVal = negative ? BoundedRational.negate(tmp.mRatVal)
-                                         : tmp.mRatVal;
-        return new EvalRet(cpos, cval, ratVal);
+        cpos = tmp.pos;
+        CR crVal = negative ? tmp.val.negate() : tmp.val;
+        BoundedRational ratVal = negative ? BoundedRational.negate(tmp.ratVal)
+                                         : tmp.ratVal;
+        return new EvalRet(cpos, crVal, ratVal);
     }
 
     private boolean canStartFactor(int i) {
         if (i >= mExpr.size()) return false;
         Token t = mExpr.get(i);
         if (!(t instanceof Operator)) return true;
-        int id = ((Operator)(t)).mId;
+        int id = ((Operator)(t)).id;
         if (KeyMaps.isBinary(id)) return false;
         switch (id) {
             case R.id.op_fact:
@@ -908,72 +993,74 @@
         EvalRet tmp = evalSignedFactor(i, ec);
         boolean is_mul = false;
         boolean is_div = false;
-        int cpos = tmp.mPos;   // Current position in expression.
-        CR cval = tmp.mVal;    // Current value.
-        BoundedRational ratVal = tmp.mRatVal; // Current rational value.
+        int cpos = tmp.pos;   // Current position in expression.
+        CR crVal = tmp.val;    // Current value.
+        BoundedRational ratVal = tmp.ratVal; // Current rational value.
         while ((is_mul = isOperator(cpos, R.id.op_mul, ec))
                || (is_div = isOperator(cpos, R.id.op_div, ec))
                || canStartFactor(cpos)) {
             if (is_mul || is_div) ++cpos;
             tmp = evalSignedFactor(cpos, ec);
             if (is_div) {
-                ratVal = BoundedRational.divide(ratVal, tmp.mRatVal);
+                ratVal = BoundedRational.divide(ratVal, tmp.ratVal);
                 if (ratVal == null) {
-                    cval = cval.divide(tmp.mVal);
+                    crVal = crVal.divide(tmp.val);
                 } else {
-                    cval = ratVal.CRValue();
+                    crVal = ratVal.CRValue();
                 }
             } else {
-                ratVal = BoundedRational.multiply(ratVal, tmp.mRatVal);
+                ratVal = BoundedRational.multiply(ratVal, tmp.ratVal);
                 if (ratVal == null) {
-                    cval = cval.multiply(tmp.mVal);
+                    crVal = crVal.multiply(tmp.val);
                 } else {
-                    cval = ratVal.CRValue();
+                    crVal = ratVal.CRValue();
                 }
             }
-            cpos = tmp.mPos;
+            cpos = tmp.pos;
             is_mul = is_div = false;
         }
-        return new EvalRet(cpos, cval, ratVal);
+        return new EvalRet(cpos, crVal, ratVal);
     }
 
     private EvalRet evalExpr(int i, EvalContext ec) throws SyntaxException {
         EvalRet tmp = evalTerm(i, ec);
         boolean is_plus;
-        int cpos = tmp.mPos;
-        CR cval = tmp.mVal;
-        BoundedRational ratVal = tmp.mRatVal;
+        int cpos = tmp.pos;
+        CR crVal = tmp.val;
+        BoundedRational ratVal = tmp.ratVal;
         while ((is_plus = isOperator(cpos, R.id.op_add, ec))
                || isOperator(cpos, R.id.op_sub, ec)) {
             tmp = evalTerm(cpos+1, ec);
             if (is_plus) {
-                ratVal = BoundedRational.add(ratVal, tmp.mRatVal);
+                ratVal = BoundedRational.add(ratVal, tmp.ratVal);
                 if (ratVal == null) {
-                    cval = cval.add(tmp.mVal);
+                    crVal = crVal.add(tmp.val);
                 } else {
-                    cval = ratVal.CRValue();
+                    crVal = ratVal.CRValue();
                 }
             } else {
-                ratVal = BoundedRational.subtract(ratVal, tmp.mRatVal);
+                ratVal = BoundedRational.subtract(ratVal, tmp.ratVal);
                 if (ratVal == null) {
-                    cval = cval.subtract(tmp.mVal);
+                    crVal = crVal.subtract(tmp.val);
                 } else {
-                    cval = ratVal.CRValue();
+                    crVal = ratVal.CRValue();
                 }
             }
-            cpos = tmp.mPos;
+            cpos = tmp.pos;
         }
-        return new EvalRet(cpos, cval, ratVal);
+        return new EvalRet(cpos, crVal, ratVal);
     }
 
-    // Externally visible evaluation result.
-    public class EvalResult {
-        EvalResult (CR val, BoundedRational ratVal) {
-            mVal = val;
-            mRatVal = ratVal;
+    /**
+     * Externally visible evaluation result.
+     */
+    public static class EvalResult {
+        public final CR val;
+        public final BoundedRational ratVal;
+        EvalResult (CR v, BoundedRational rv) {
+            val = v;
+            ratVal = rv;
         }
-        final CR mVal;
-        final BoundedRational mRatVal;
     }
 
     /**
@@ -985,13 +1072,15 @@
             Token last = mExpr.get(result - 1);
             if (!(last instanceof Operator)) break;
             Operator o = (Operator)last;
-            if (!KeyMaps.isBinary(o.mId)) break;
+            if (!KeyMaps.isBinary(o.id)) break;
             --result;
         }
         return result;
     }
 
-    // Is the current expression worth evaluating?
+    /**
+     * Is the current expression worth evaluating?
+     */
     public boolean hasInterestingOps() {
         int last = trailingBinaryOpsStart();
         int first = 0;
@@ -1011,9 +1100,9 @@
 
     /**
      * Evaluate the expression excluding trailing binary operators.
-     * Errors result in exceptions, most of which are unchecked.
-     * Should not be called concurrently with modification of the expression.
-     * May take a very long time; avoid calling from UI thread.
+     * Errors result in exceptions, most of which are unchecked.  Should not be called
+     * concurrently with modification of the expression.  May take a very long time; avoid calling
+     * from UI thread.
      *
      * @param degreeMode use degrees rather than radians
      */
@@ -1022,18 +1111,17 @@
                         // and BoundedRational.
     {
         try {
-            // We currently never include trailing binary operators, but include
-            // other trailing operators.
-            // Thus we usually, but not always, display results for prefixes
-            // of valid expressions, and don't generate an error where we previously
-            // displayed an instant result.  This reflects the Android L design.
+            // We currently never include trailing binary operators, but include other trailing
+            // operators.  Thus we usually, but not always, display results for prefixes of valid
+            // expressions, and don't generate an error where we previously displayed an instant
+            // result.  This reflects the Android L design.
             int prefixLen = trailingBinaryOpsStart();
             EvalContext ec = new EvalContext(degreeMode, prefixLen);
             EvalRet res = evalExpr(0, ec);
-            if (res.mPos != prefixLen) {
+            if (res.pos != prefixLen) {
                 throw new SyntaxException("Failed to parse full expression");
             }
-            return new EvalResult(res.mVal, res.mRatVal);
+            return new EvalResult(res.val, res.ratVal);
         } catch (IndexOutOfBoundsException e) {
             throw new SyntaxException("Unexpected expression end");
         }
diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java
index 1efa67b..289e13d 100644
--- a/src/com/android/calculator2/CalculatorResult.java
+++ b/src/com/android/calculator2/CalculatorResult.java
@@ -335,9 +335,9 @@
 
     /*
      * Return the most significant digit position in the given string or Evaluator.INVALID_MSD.
-     * Unlike Evaluator.getMsdPos, we treat a final 1 as significant.
+     * Unlike Evaluator.getMsdIndexOf, we treat a final 1 as significant.
      */
-    public static int getNaiveMsdIndex(String s) {
+    public static int getNaiveMsdIndexOf(String s) {
         int len = s.length();
         for (int i = 0; i < len; ++i) {
             char c = s.charAt(i);
@@ -349,14 +349,14 @@
     }
 
     // Format a result returned by Evaluator.getString() into a single line containing ellipses
-    // (if appropriate) and an exponent (if appropriate).  prec is the value that was passed to
-    // getString and thus identifies the significance of the rightmost digit.
+    // (if appropriate) and an exponent (if appropriate).  precOffset is the value that was passed
+    // to getString and thus identifies the significance of the rightmost digit.
     // A value of 1 means the rightmost digits corresponds to tenths.
     // maxDigs is the maximum number of characters in the result.
     // We set lastDisplayedOffset[0] to the offset of the last digit actually appearing in
     // the display.
     // If forcePrecision is true, we make sure that the last displayed digit corresponds to
-    // prec, and allow maxDigs to be exceeded in assing the exponent.
+    // precOffset, and allow maxDigs to be exceeded in assing the exponent.
     // We add two distinct kinds of exponents:
     // (1) If the final result contains the leading digit we use standard scientific notation.
     // (2) If not, we add an exponent corresponding to an interpretation of the final result as
@@ -369,7 +369,7 @@
     public String formatResult(String in, int precOffset, int maxDigs, boolean truncated,
             boolean negative, int lastDisplayedOffset[], boolean forcePrecision) {
         final int minusSpace = negative ? 1 : 0;
-        final int msdIndex = truncated ? -1 : getNaiveMsdIndex(in);  // INVALID_MSD is OK.
+        final int msdIndex = truncated ? -1 : getNaiveMsdIndexOf(in);  // INVALID_MSD is OK.
         final int decIndex = in.indexOf('.');
         String result = in;
         lastDisplayedOffset[0] = precOffset;
diff --git a/src/com/android/calculator2/Evaluator.java b/src/com/android/calculator2/Evaluator.java
index b779a68..e1bcaf6 100644
--- a/src/com/android/calculator2/Evaluator.java
+++ b/src/com/android/calculator2/Evaluator.java
@@ -14,68 +14,6 @@
  * limitations under the License.
  */
 
-//
-// This implements the calculator evaluation logic.
-// An evaluation is started with a call to evaluateAndShowResult().
-// This starts an asynchronous computation, which requests display
-// of the initial result, when available.  When initial evaluation is
-// complete, it calls the calculator onEvaluate() method.
-// This occurs in a separate event, and may happen quite a bit
-// later.  Once a result has been computed, and before the underlying
-// expression is modified, the getString method may be used to produce
-// Strings that represent approximations to various precisions.
-//
-// Actual expressions being evaluated are represented as CalculatorExprs,
-// which are just slightly preprocessed sequences of keypresses.
-//
-// The Evaluator owns the expression being edited and associated
-// state needed for evaluating it. It provides functionality for
-// saving and restoring this state.  However the current
-// CalculatorExpr is exposed to the client, and may be directly modified
-// after cancelling any in-progress computations by invoking the
-// cancelAll() method.
-//
-// When evaluation is requested by the user, we invoke the eval
-// method on the CalculatorExpr from a background AsyncTask.
-// A subsequent getString() callback returns immediately, though it may
-// return a result containing placeholder '?' characters.
-// In that case we start a background task, which invokes the
-// onReevaluate() callback when it completes.
-// In both cases, the background task
-// computes the appropriate result digits by evaluating
-// the constructive real (CR) returned by CalculatorExpr.eval()
-// to the required precision.
-//
-// We cache the best approximation we have already computed.
-// We compute generously to allow for
-// some scrolling without recomputation and to minimize the chance of
-// digits flipping from "0000" to "9999".  The best known
-// result approximation is maintained as a string by mCache (and
-// in a different format by the CR representation of the result).
-// When we are in danger of not having digits to display in response
-// to further scrolling, we initiate a background computation to higher
-// precision.  If we actually do fall behind, we display placeholder
-// characters, e.g. blanks, and schedule a display update when the computation
-// completes.
-// The code is designed to ensure that the error in the displayed
-// result (excluding any placeholder characters) is always strictly less than 1 in
-// the last displayed digit.  Typically we actually display a prefix
-// of a result that has this property and additionally is computed to
-// a significantly higher precision.  Thus we almost always round correctly
-// towards zero.  (Fully correct rounding towards zero is not computable.)
-//
-// Initial expression evaluation may time out.  This may happen in the
-// case of domain errors such as division by zero, or for large computations.
-// We do not currently time out reevaluations to higher precision, since
-// the original evaluation prevcluded a domain error that could result
-// in non-termination.  (We may discover that a presumed zero result is
-// actually slightly negative when re-evaluated; but that results in an
-// exception, which we can handle.)  The user can abort either kind
-// of computation.
-//
-// We ensure that only one evaluation of either kind (AsyncReevaluator
-// or AsyncDisplayResult) is running at a time.
-
 package com.android.calculator2;
 
 import android.app.AlertDialog;
@@ -100,102 +38,145 @@
 import java.util.Random;
 import java.util.TimeZone;
 
+/**
+ * This implements the calculator evaluation logic.  The underlying expression is constructed and
+ * edited with append(), delete(), and clear().  An evaluation an then be started with a call to
+ * evaluateAndShowResult() or requireResult().  This starts an asynchronous computation, which
+ * requests display of the initial result, when available.  When initial evaluation is complete,
+ * it calls the calculator onEvaluate() method.  This occurs in a separate event, possibly quite a
+ * bit later.  Once a result has been computed, and before the underlying expression is modified,
+ * the getString() method may be used to produce Strings that represent approximations to various
+ * precisions.
+ *
+ * Actual expressions being evaluated are represented as {@link CalculatorExpr}s.
+ *
+ * The Evaluator owns the expression being edited and all associated state needed for evaluating
+ * it.  It provides functionality for saving and restoring this state.  However the current
+ * CalculatorExpr is exposed to the client, and may be directly accessed after cancelling any
+ * in-progress computations by invoking the cancelAll() method.
+ *
+ * When evaluation is requested, we invoke the eval() method on the CalculatorExpr from a
+ * background AsyncTask.  A subsequent getString() callback returns immediately, though it may
+ * return a result containing placeholder ' ' characters.  If we had to return palceholder
+ * characters, we start a background task, which invokes the onReevaluate() callback when it
+ * completes.  In either case, the background task computes the appropriate result digits by
+ * evaluating the constructive real (CR) returned by CalculatorExpr.eval() to the required
+ * precision.
+ *
+ * We cache the best decimal approximation we have already computed.  We compute generously to
+ * allow for some scrolling without recomputation and to minimize the chance of digits flipping
+ * from "0000" to "9999".  The best known result approximation is maintained as a string by
+ * mResultString (and in a different format by the CR representation of the result).  When we are
+ * in danger of not having digits to display in response to further scrolling, we also initiate a
+ * background computation to higher precision, as if we had generated placeholder characters.
+ *
+ * The code is designed to ensure that the error in the displayed result (excluding any
+ * placeholder characters) is always strictly less than 1 in the last displayed digit.  Typically
+ * we actually display a prefix of a result that has this property and additionally is computed to
+ * a significantly higher precision.  Thus we almost always round correctly towards zero.  (Fully
+ * correct rounding towards zero is not computable, at least given our representation.)
+ *
+ * Initial expression evaluation may time out.  This may happen in the case of domain errors such
+ * as division by zero, or for large computations.  We do not currently time out reevaluations to
+ * higher precision, since the original evaluation precluded a domain error that could result in
+ * non-termination.  (We may discover that a presumed zero result is actually slightly negative
+ * when re-evaluated; but that results in an exception, which we can handle.)  The user can abort
+ * either kind of computation.
+ *
+ * We ensure that only one evaluation of either kind (AsyncEvaluator or AsyncReevaluator) is
+ * running at a time.
+ */
 class Evaluator {
 
+    // When naming variables and fields, "Offset" denotes a character offset in a string
+    // representing a decimal number, where the offset is relative to the decimal point.  1 =
+    // tenths position, -1 = units position.  Integer.MAX_VALUE is sometimes used for the offset
+    // of the last digit in an a nonterminating decimal expansion.  We use the suffix "Index" to
+    // denote a zero-based absolute index into such a string.
+
     private static final String KEY_PREF_DEGREE_MODE = "degree_mode";
 
-    private final Calculator mCalculator;
-    private final CalculatorResult mResult;  // The result display View
-    private CalculatorExpr mExpr;      // Current calculator expression
-    private CalculatorExpr mSaved;     // Last saved expression.
-                                       // Either null or contains a single
-                                       // preevaluated node.
-    private String mSavedName;         // A hopefully unique name associated
-                                       // with mSaved.
-    // The following are valid only if an evaluation
-    // completed successfully.
-        private CR mVal;               // value of mExpr as constructive real
-        private BoundedRational mRatVal; // value of mExpr as rational or null
-        private int mLastDigs;   // Last digit argument passed to getString()
-                                 // for this result, or the initial preferred
-                                 // precision.
-    private boolean mDegreeMode;       // Currently in degree (not radian) mode
-    private final Handler mTimeoutHandler;
-
-    static final BigInteger BIG_MILLION = BigInteger.valueOf(1000000);
-
+    // The minimum number of extra digits we always try to compute to improve the chance of
+    // producing a correctly-rounded-towards-zero result.  The extra digits can be displayed to
+    // avoid generating placeholder digits, but should only be displayed briefly while computing.
     private static final int EXTRA_DIGITS = 20;
-                // Extra computed digits to minimize probably we will have
-                // to change our minds about digits we already displayed.
-                // (The correct digits are technically not computable using our
-                // representation:  An off by one error in the last digits
-                // can affect earlier ones, even though the display is
-                // always within one in the lsd.  This is only visible
-                // for results that end in EXTRA_DIGITS 9s or 0s, but are
-                // not integers.)
-                // We do use these extra digits to display while we are
-                // computing the correct answer.  Thus they may be
-                // temporarily visible.
-   private static final int EXTRA_DIVISOR = 5;
-                // We add the length of the previous result divided by
-                // EXTRA_DIVISOR to try to recover recompute latency when
-                // scrolling through a long result.
-   private static final int PRECOMPUTE_DIGITS = 30;
-   private static final int PRECOMPUTE_DIVISOR = 5;
-                // When we have to reevaluate, we compute an extra
-                // PRECOMPUTE_DIGITS
-                // + <current_result_length>/PRECOMPUTE_DIVISOR digits.
-                // The last term is dropped if prec < 0.
 
-    // We cache the result as a string to accelerate scrolling.
-    // The cache is filled in by the UI thread, but this may
-    // happen asynchronously, much later than the request.
-    private String mCache;       // Current best known result, which includes
-    private int mCacheDigs = 0;  // mCacheDigs digits to the right of the
-                                 // decimal point.  Always positive.
-                                 // mCache is valid when non-null
-                                 // unless the expression has been
-                                 // changed since the last evaluation call.
-    private int mCacheDigsReq;  // Number of digits that have been
-                                // requested.  Only touched by UI
-                                // thread.
-    public static final int INVALID_MSD = Integer.MAX_VALUE;
-    private int mMsd = INVALID_MSD;  // Position of most significant digit
-                                     // in current cached result, if determined.
-                                     // This is just the index in mCache
-                                     // holding the msd.
+    // We adjust EXTRA_DIGITS by adding the length of the previous result divided by
+    // EXTRA_DIVISOR.  This helps hide recompute latency when long results are requested;
+    // We start the recomputation substantially before the need is likely to be visible.
+    private static final int EXTRA_DIVISOR = 5;
+
+    // In addition to insisting on extra digits (see above), we minimize reevaluation
+    // frequency by precomputing an extra PRECOMPUTE_DIGITS
+    // + <current_precision_offset>/PRECOMPUTE_DIVISOR digits, whenever we are forced to
+    // reevaluate.  The last term is dropped if prec < 0.
+    private static final int PRECOMPUTE_DIGITS = 30;
+    private static final int PRECOMPUTE_DIVISOR = 5;
+
+    // Initial evaluation precision.  Enough to guarantee that we can compute the short
+    // representation, and that we rarely have to evaluate nonzero results to MAX_MSD_PREC_OFFSET.
+    // It also helps if this is at least EXTRA_DIGITS + display width, so that we don't
+    // immediately need a second evaluation.
     private static final int INIT_PREC = 50;
-                             // Initial evaluation precision.  Enough to guarantee
-                             // that we can compute the short representation, and that
-                             // we rarely have to evaluate nonzero results to
-                             // MAX_MSD_PREC.  It also helps if this is at least
-                             // EXTRA_DIGITS + display width, so that we don't
-                             // immediately need a second evaluation.
-    private static final int MAX_MSD_PREC = 320;
-                             // The largest number of digits to the right
-                             // of the decimal point to which we will
-                             // evaluate to compute proper scientific
-                             // notation for values close to zero.
-                             // Chosen to ensure that we always to better than
-                             // IEEE double precision at identifying nonzeros.
+
+    // The largest number of digits to the right of the decimal point to which we will evaluate to
+    // compute proper scientific notation for values close to zero.  Chosen to ensure that we
+    // always to better than IEEE double precision at identifying nonzeros.
+    private static final int MAX_MSD_PREC_OFFSET = 320;
+
+    // If we can replace an exponent by this many leading zeroes, we do so.  Also used in
+    // estimating exponent size for truncating short representation.
     private static final int EXP_COST = 3;
-                             // If we can replace an exponent by this many leading zeroes,
-                             // we do so.  Also used in estimating exponent size for
-                             // truncating short representation.
 
-    private AsyncReevaluator mCurrentReevaluator;
-        // The one and only un-cancelled and currently running reevaluator.
-        // Touched only by UI thread.
+    private final Calculator mCalculator;
+    private final CalculatorResult mResult;
 
-    private AsyncDisplayResult mEvaluator;
-        // Currently running expression evaluator, if any.
+    // The current caluclator expression.
+    private CalculatorExpr mExpr;
 
+    // Last saved expression.  Either null or contains a single CalculatorExpr.PreEval node.
+    private CalculatorExpr mSaved;
+
+    //  A hopefully unique name associated with mSaved.
+    private String mSavedName;
+
+    // The expression may have changed since the last evaluation in ways that would affect its
+    // value.
     private boolean mChangedValue;
-        // The expression may have changed since the last evaluation in ways that would
-        // affect its value.
 
     private SharedPreferences mSharedPrefs;
 
+    private boolean mDegreeMode;       // Currently in degree (not radian) mode.
+
+    private final Handler mTimeoutHandler;  // Used to schedule evaluation timeouts.
+
+    // The following are valid only if an evaluation completed successfully.
+        private CR mVal;               // Value of mExpr as constructive real.
+        private BoundedRational mRatVal; // Value of mExpr as rational or null.
+
+    // We cache the best known decimal result in mResultString.  Whenever that is
+    // non-null, it is computed to exactly mResultStringOffset, which is always > 0.
+    // The cache is filled in by the UI thread.
+    // Valid only if mResultString is non-null and !mChangedValue.
+    private String mResultString;
+    private int mResultStringOffset = 0;
+
+    // Number of digits to which (possibly incomplete) evaluation has been requested.
+    // Only accessed by UI thread.
+    private int mResultStringOffsetReq;  // Number of digits that have been
+
+    public static final int INVALID_MSD = Integer.MAX_VALUE;
+
+    // Position of most significant digit in current cached result, if determined.  This is just
+    // the index in mResultString holding the msd.
+    private int mMsdIndex = INVALID_MSD;
+
+    // Currently running expression evaluator, if any.
+    private AsyncEvaluator mEvaluator;
+
+    // The one and only un-cancelled and currently running reevaluator. Touched only by UI thread.
+    private AsyncReevaluator mCurrentReevaluator;
+
     Evaluator(Calculator calculator,
               CalculatorResult resultDisplay) {
         mCalculator = calculator;
@@ -209,86 +190,36 @@
         mDegreeMode = mSharedPrefs.getBoolean(KEY_PREF_DEGREE_MODE, false);
     }
 
-    // Result of asynchronous reevaluation
-    class ReevalResult {
-        ReevalResult(String s, int p) {
-            mNewCache = s;
-            mNewCacheDigs = p;
-        }
-        final String mNewCache;
-        final int mNewCacheDigs;
-    }
-
-    // Compute new cache contents accurate to prec digits to the right
-    // of the decimal point.  Ensure that redisplay() is called after
-    // doing so.  If the evaluation fails for reasons other than a
-    // timeout, ensure that DisplayError() is called.
-    class AsyncReevaluator extends AsyncTask<Integer, Void, ReevalResult> {
-        @Override
-        protected ReevalResult doInBackground(Integer... prec) {
-            try {
-                int eval_prec = prec[0].intValue();
-                return new ReevalResult(mVal.toString(eval_prec), eval_prec);
-            } catch(ArithmeticException e) {
-                return null;
-            } catch(CR.PrecisionOverflowException e) {
-                return null;
-            } catch(CR.AbortedException e) {
-                // Should only happen if the task was cancelled,
-                // in which case we don't look at the result.
-                return null;
-            }
-        }
-        @Override
-        protected void onPostExecute(ReevalResult result) {
-            if (result == null) {
-                // This should only be possible in the extremely rare
-                // case of encountering a domain error while reevaluating
-                // or in case of a precision overflow.  We don't know of
-                // a way to get the latter with a plausible amount of
-                // user input.
-                mCalculator.onError(R.string.error_nan);
-            } else {
-                if (result.mNewCacheDigs < mCacheDigs) {
-                    throw new AssertionError("Unexpected onPostExecute timing");
-                }
-                mCache = result.mNewCache;
-                mCacheDigs = result.mNewCacheDigs;
-                mCalculator.onReevaluate();
-            }
-            mCurrentReevaluator = null;
-        }
-        // On cancellation we do nothing; invoker should have
-        // left no trace of us.
-    }
-
-    // Result of initial asynchronous computation
+    /**
+     * Result of initial asynchronous result computation.
+     * Represents either an error or a result computed to an initial evaluation precision.
+     */
     private static class InitialResult {
-        InitialResult(CR val, BoundedRational ratVal, String s, int p, int idp) {
-            mErrorResourceId = Calculator.INVALID_RES_ID;
-            mVal = val;
-            mRatVal = ratVal;
-            mNewCache = s;
-            mNewCacheDigs = p;
-            mInitDisplayPrec = idp;
+        public final int errorResourceId;    // Error string or INVALID_RES_ID.
+        public final CR val;                 // Constructive real value.
+        public final BoundedRational ratVal; // Rational value or null.
+        public final String newResultString;       // Null iff it can't be computed.
+        public final int newResultStringOffset;
+        public final int initDisplayOffset;
+        InitialResult(CR v, BoundedRational rv, String s, int p, int idp) {
+            errorResourceId = Calculator.INVALID_RES_ID;
+            val = v;
+            ratVal = rv;
+            newResultString = s;
+            newResultStringOffset = p;
+            initDisplayOffset = idp;
         }
-        InitialResult(int errorResourceId) {
-            mErrorResourceId = errorResourceId;
-            mVal = CR.valueOf(0);
-            mRatVal = BoundedRational.ZERO;
-            mNewCache = "BAD";
-            mNewCacheDigs = 0;
-            mInitDisplayPrec = 0;
+        InitialResult(int errorId) {
+            errorResourceId = errorId;
+            val = CR.valueOf(0);
+            ratVal = BoundedRational.ZERO;
+            newResultString = "BAD";
+            newResultStringOffset = 0;
+            initDisplayOffset = 0;
         }
         boolean isError() {
-            return mErrorResourceId != Calculator.INVALID_RES_ID;
+            return errorResourceId != Calculator.INVALID_RES_ID;
         }
-        final int mErrorResourceId;
-        final CR mVal;
-        final BoundedRational mRatVal;
-        final String mNewCache;       // Null iff it can't be computed.
-        final int mNewCacheDigs;
-        final int mInitDisplayPrec;
     }
 
     private void displayCancelledMessage() {
@@ -302,21 +233,18 @@
             .show();
     }
 
+    // Maximum timeout for background computations.  Exceeding a few tens of seconds
+    // increases the risk of running out of memory and impacting the rest of the system.
     private final long MAX_TIMEOUT = 15000;
-                                   // Milliseconds.
-                                   // Longer is unlikely to help unless
-                                   // we get more heap space.
-    private long mTimeout = 2000;  // Timeout for requested evaluations,
-                                   // in milliseconds.
-                                   // This is currently not saved and restored
-                                   // with the state; we reset
-                                   // the timeout when the
-                                   // calculator is restarted.
-                                   // We'll call that a feature; others
-                                   // might argue it's a bug.
+
+    // Timeout for requested evaluations, in milliseconds.  This is currently not saved and
+    // restored with the state; we reset the timeout when the calculator is restarted.  We'll call
+    // that a feature; others might argue it's a bug.
+    private long mTimeout = 2000;
+
+    // Timeout for unrequested, speculative evaluations, in milliseconds.
     private final long QUICK_TIMEOUT = 1000;
-                                   // Timeout for unrequested, speculative
-                                   // evaluations, in milliseconds.
+
     private int mMaxResultBits = 120000;             // Don't try to display a larger result.
     private final int MAX_MAX_RESULT_BITS = 350000;  // Long timeout version.
     private final int QUICK_MAX_RESULT_BITS = 50000; // Instant result version.
@@ -342,12 +270,12 @@
     // disabled, until this computation completes.
     // Can result in an error display if something goes wrong.
     // By default we set a timeout to catch runaway computations.
-    class AsyncDisplayResult extends AsyncTask<Void, Void, InitialResult> {
+    class AsyncEvaluator extends AsyncTask<Void, Void, InitialResult> {
         private boolean mDm;  // degrees
         private boolean mRequired; // Result was requested by user.
         private boolean mQuiet;  // Suppress cancellation message.
         private Runnable mTimeoutRunnable = null;
-        AsyncDisplayResult(boolean dm, boolean required) {
+        AsyncEvaluator(boolean dm, boolean required) {
             mDm = dm;
             mRequired = required;
             mQuiet = !required;
@@ -379,12 +307,15 @@
             };
             mTimeoutHandler.postDelayed(mTimeoutRunnable, timeout);
         }
+        /**
+         * Is a computed result too big for decimal conversion?
+         */
         private boolean isTooBig(CalculatorExpr.EvalResult res) {
             int maxBits = mRequired ? mMaxResultBits : QUICK_MAX_RESULT_BITS;
-            if (res.mRatVal != null) {
-                return res.mRatVal.wholeNumberBits() > maxBits;
+            if (res.ratVal != null) {
+                return res.ratVal.wholeNumberBits() > maxBits;
             } else {
-                return res.mVal.get_appr(maxBits).bitLength() > 2;
+                return res.val.get_appr(maxBits).bitLength() > 2;
             }
         }
         @Override
@@ -395,35 +326,33 @@
                     // Avoid starting a long uninterruptible decimal conversion.
                     return new InitialResult(R.string.timeout);
                 }
-                int prec = INIT_PREC;
-                String initCache = res.mVal.toString(prec);
-                int msd = getMsdPos(initCache);
-                if (BoundedRational.asBigInteger(res.mRatVal) == null
+                int precOffset = INIT_PREC;
+                String initResult = res.val.toString(precOffset);
+                int msd = getMsdIndexOf(initResult);
+                if (BoundedRational.asBigInteger(res.ratVal) == null
                         && msd == INVALID_MSD) {
-                    prec = MAX_MSD_PREC;
-                    initCache = res.mVal.toString(prec);
-                    msd = getMsdPos(initCache);
+                    precOffset = MAX_MSD_PREC_OFFSET;
+                    initResult = res.val.toString(precOffset);
+                    msd = getMsdIndexOf(initResult);
                 }
-                int lsd = getLsd(res.mRatVal, initCache, initCache.indexOf('.'));
-                int initDisplayPrec = getPreferredPrec(initCache, msd, lsd);
-                int newPrec = initDisplayPrec + EXTRA_DIGITS;
-                if (newPrec > prec) {
-                    prec = newPrec;
-                    initCache = res.mVal.toString(prec);
+                final int lsdOffset = getLsdOffset(res.ratVal, initResult,
+                        initResult.indexOf('.'));
+                final int initDisplayOffset = getPreferredPrec(initResult, msd, lsdOffset);
+                final int newPrecOffset = initDisplayOffset + EXTRA_DIGITS;
+                if (newPrecOffset > precOffset) {
+                    precOffset = newPrecOffset;
+                    initResult = res.val.toString(precOffset);
                 }
-                return new InitialResult(res.mVal, res.mRatVal,
-                                         initCache, prec, initDisplayPrec);
+                return new InitialResult(res.val, res.ratVal,
+                        initResult, precOffset, initDisplayOffset);
             } catch (CalculatorExpr.SyntaxException e) {
                 return new InitialResult(R.string.error_syntax);
             } catch (BoundedRational.ZeroDivisionException e) {
-                // Division by zero caught by BoundedRational;
-                // the easy and more common case.
                 return new InitialResult(R.string.error_zero_divide);
             } catch(ArithmeticException e) {
                 return new InitialResult(R.string.error_nan);
             } catch(CR.PrecisionOverflowException e) {
-                // Extremely unlikely unless we're actually dividing by
-                // zero or the like.
+                // Extremely unlikely unless we're actually dividing by zero or the like.
                 return new InitialResult(R.string.error_overflow);
             } catch(CR.AbortedException e) {
                 return new InitialResult(R.string.error_aborted);
@@ -434,41 +363,41 @@
             mEvaluator = null;
             mTimeoutHandler.removeCallbacks(mTimeoutRunnable);
             if (result.isError()) {
-                if (result.mErrorResourceId == R.string.timeout) {
+                if (result.errorResourceId == R.string.timeout) {
                     if (mRequired) {
                         displayTimeoutMessage();
                     }
                     mCalculator.onCancelled();
                 } else {
-                    mCalculator.onError(result.mErrorResourceId);
+                    mCalculator.onError(result.errorResourceId);
                 }
                 return;
             }
-            mVal = result.mVal;
-            mRatVal = result.mRatVal;
-            mCache = result.mNewCache;
-            mCacheDigs = result.mNewCacheDigs;
-            mLastDigs = result.mInitDisplayPrec;
-            int dotPos = mCache.indexOf('.');
-            String truncatedWholePart = mCache.substring(0, dotPos);
-            // Recheck display precision; it may change, since
-            // display dimensions may have been unknow the first time.
-            // In that case the initial evaluation precision should have
+            mVal = result.val;
+            mRatVal = result.ratVal;
+            // TODO: If the new result ends in lots of zeroes, and we have a rational result which
+            // is greater than (in absolute value) the result string, we should subtract 1 ulp
+            // from the result string.  That will prevent a later change from zeroes to nines.  We
+            // know that the correct, rounded-toward-zero result has nines.
+            mResultString = result.newResultString;
+            mResultStringOffset = result.newResultStringOffset;
+            final int dotIndex = mResultString.indexOf('.');
+            String truncatedWholePart = mResultString.substring(0, dotIndex);
+            // Recheck display precision; it may change, since display dimensions may have been
+            // unknow the first time.  In that case the initial evaluation precision should have
             // been conservative.
-            // TODO: Could optimize by remembering display size and
-            // checking for change.
-            int init_prec = result.mInitDisplayPrec;
-            int msd = getMsdPos(mCache);
-            int leastDigPos = getLsd(mRatVal, mCache, dotPos);
-            int new_init_prec = getPreferredPrec(mCache, msd, leastDigPos);
-            if (new_init_prec < init_prec) {
-                init_prec = new_init_prec;
+            // TODO: Could optimize by remembering display size and checking for change.
+            int initPrecOffset = result.initDisplayOffset;
+            final int msdIndex = getMsdIndexOf(mResultString);
+            final int leastDigOffset = getLsdOffset(mRatVal, mResultString, dotIndex);
+            final int newInitPrecOffset = getPreferredPrec(mResultString, msdIndex, leastDigOffset);
+            if (newInitPrecOffset < initPrecOffset) {
+                initPrecOffset = newInitPrecOffset;
             } else {
-                // They should be equal.  But nothing horrible should
-                // happen if they're not. e.g. because
-                // CalculatorResult.MAX_WIDTH was too small.
+                // They should be equal.  But nothing horrible should happen if they're not. e.g.
+                // because CalculatorResult.MAX_WIDTH was too small.
             }
-            mCalculator.onEvaluate(init_prec, msd, leastDigPos, truncatedWholePart);
+            mCalculator.onEvaluate(initPrecOffset, msdIndex, leastDigOffset, truncatedWholePart);
         }
         @Override
         protected void onCancelled(InitialResult result) {
@@ -476,47 +405,117 @@
             mTimeoutHandler.removeCallbacks(mTimeoutRunnable);
             if (mRequired && !mQuiet) {
                 displayCancelledMessage();
-            } // Otherwise timeout processing displayed message.
+            } // Otherwise, if mRequired, timeout processing displayed message.
             mCalculator.onCancelled();
             // Just drop the evaluation; Leave expression displayed.
             return;
         }
     }
 
+    /**
+     * Result of asynchronous reevaluation.
+     */
+    private static class ReevalResult {
+        public final String newResultString;
+        public final int newResultStringOffset;
+        ReevalResult(String s, int p) {
+            newResultString = s;
+            newResultStringOffset = p;
+        }
+    }
 
-    // Start an evaluation to prec, and ensure that the
-    // display is redrawn when it completes.
-    private void ensureCachePrec(int prec) {
-        if (mCache != null && mCacheDigs >= prec
-                || mCacheDigsReq >= prec) return;
+    /**
+     * Compute new mResultString contents to prec digits to the right of the decimal point.
+     * Ensure that onReevaluate() is called after doing so.  If the evaluation fails for reasons
+     * other than a timeout, ensure that onError() is called.
+     */
+    private class AsyncReevaluator extends AsyncTask<Integer, Void, ReevalResult> {
+        @Override
+        protected ReevalResult doInBackground(Integer... prec) {
+            try {
+                final int precOffset = prec[0].intValue();
+                return new ReevalResult(mVal.toString(precOffset), precOffset);
+            } catch(ArithmeticException e) {
+                return null;
+            } catch(CR.PrecisionOverflowException e) {
+                return null;
+            } catch(CR.AbortedException e) {
+                // Should only happen if the task was cancelled, in which case we don't look at
+                // the result.
+                return null;
+            }
+        }
+        @Override
+        protected void onPostExecute(ReevalResult result) {
+            if (result == null) {
+                // This should only be possible in the extremely rare case of encountering a
+                // domain error while reevaluating or in case of a precision overflow.  We don't
+                // know of a way to get the latter with a plausible amount of user input.
+                mCalculator.onError(R.string.error_nan);
+            } else {
+                if (result.newResultStringOffset < mResultStringOffset) {
+                    throw new AssertionError("Unexpected onPostExecute timing");
+                }
+                // FIXME: We are assuming that the most significant digit never moves to the left,
+                // i.e. that 0.99999 doesn't ever change to 1.00000.  Informally that makes sense,
+                // in that we can only produce the former result after a computation showing that
+                // the true answer is < 1 (otherwise we would have violated our 1 ulp error
+                // bound), and higher precision evaluations should preserve that bound.  But I
+                // don't know how to prove that.  Indeed, it seems like this could be violated
+                // if one of the CR operations, before rounding, produced an error that was
+                // almost exactly at it's error bound of 1/2ulp.  (Since we calculate ahead
+                // so far, we really mean "almost exactly", which makes it very difficult to
+                // generate a test case.)
+                // Instead, we should just check whether (a) all added digits are zeroes, and (b)
+                // any trailing 9's have been replaced.  In that case, we just use the original
+                // result with 9's appended.  This must be correct, since our 1 ulp error bound
+                // implies that the correct answer is between the two.  This has the unfortunate
+                // consequence that we are introducing code that is extremely unlikely to ever be
+                // exercised, and thus very difficult to test.
+                mResultString = result.newResultString;
+                mResultStringOffset = result.newResultStringOffset;
+                mCalculator.onReevaluate();
+            }
+            mCurrentReevaluator = null;
+        }
+        // On cancellation we do nothing; invoker should have left no trace of us.
+    }
+
+    /**
+     * If necessary, start an evaluation to precOffset.
+     * Ensure that the display is redrawn when it completes.
+     */
+    private void ensureCachePrec(int precOffset) {
+        if (mResultString != null && mResultStringOffset >= precOffset
+                || mResultStringOffsetReq >= precOffset) return;
         if (mCurrentReevaluator != null) {
             // Ensure we only have one evaluation running at a time.
             mCurrentReevaluator.cancel(true);
             mCurrentReevaluator = null;
         }
         mCurrentReevaluator = new AsyncReevaluator();
-        mCacheDigsReq = prec + PRECOMPUTE_DIGITS;
-        if (mCache != null) {
-            mCacheDigsReq += mCacheDigsReq / PRECOMPUTE_DIVISOR;
+        mResultStringOffsetReq = precOffset + PRECOMPUTE_DIGITS;
+        if (mResultString != null) {
+            mResultStringOffsetReq += mResultStringOffsetReq / PRECOMPUTE_DIVISOR;
         }
-        mCurrentReevaluator.execute(mCacheDigsReq);
+        mCurrentReevaluator.execute(mResultStringOffsetReq);
     }
 
     /**
      * Return the rightmost nonzero digit position, if any.
      * @param ratVal Rational value of result or null.
      * @param cache Current cached decimal string representation of result.
-     * @param decPos Index of decimal point in cache.
+     * @param decIndex Index of decimal point in cache.
      * @result Position of rightmost nonzero digit relative to decimal point.
      *         Integer.MIN_VALUE if ratVal is zero.  Integer.MAX_VALUE if there is no lsd,
      *         or we cannot determine it.
      */
-    int getLsd(BoundedRational ratVal, String cache, int decPos) {
+    int getLsdOffset(BoundedRational ratVal, String cache, int decIndex) {
         if (ratVal != null && ratVal.signum() == 0) return Integer.MIN_VALUE;
         int result = BoundedRational.digitsRequired(ratVal);
         if (result == 0) {
             int i;
-            for (i = -1; decPos + i > 0 && cache.charAt(decPos + i) == '0'; --i) { }
+            for (i = -1; decIndex + i > 0 && cache.charAt(decIndex + i) == '0'; --i) { }
             result = i;
         }
         return result;
@@ -528,30 +527,33 @@
      * @param cache Current approximation as string.
      * @param msd Position of most significant digit in result.  Index in cache.
      *            Can be INVALID_MSD if we haven't found it yet.
-     * @param lastDigit Position of least significant digit (1 = tenths digit)
+     * @param lastDigitOffset Position of least significant digit (1 = tenths digit)
      *                  or Integer.MAX_VALUE.
      */
-    int getPreferredPrec(String cache, int msd, int lastDigit) {
-        int lineLength = mResult.getMaxChars();
-        int wholeSize = cache.indexOf('.');
-        int negative = cache.charAt(0) == '-' ? 1 : 0;
+    private int getPreferredPrec(String cache, int msd, int lastDigitOffset) {
+        final int lineLength = mResult.getMaxChars();
+        final int wholeSize = cache.indexOf('.');
+        final int negative = cache.charAt(0) == '-' ? 1 : 0;
         // Don't display decimal point if result is an integer.
-        if (lastDigit == 0) lastDigit = -1;
-        if (lastDigit != Integer.MAX_VALUE) {
-            if (wholeSize <= lineLength && lastDigit <= 0) {
+        if (lastDigitOffset == 0) {
+            lastDigitOffset = -1;
+        }
+        if (lastDigitOffset != Integer.MAX_VALUE) {
+            if (wholeSize <= lineLength && lastDigitOffset <= 0) {
                 // Exact integer.  Prefer to display as integer, without decimal point.
                 return -1;
             }
-            if (lastDigit >= 0 && wholeSize + lastDigit + 1 /* dec.pt. */ <= lineLength) {
+            if (lastDigitOffset >= 0
+                    && wholeSize + lastDigitOffset + 1 /* decimal pt. */ <= lineLength) {
                 // Display full exact number wo scientific notation.
-                return lastDigit;
+                return lastDigitOffset;
             }
         }
         if (msd > wholeSize && msd <= wholeSize + EXP_COST + 1) {
             // Display number without scientific notation.  Treat leading zero as msd.
             msd = wholeSize - 1;
         }
-        if (msd > wholeSize + MAX_MSD_PREC) {
+        if (msd > wholeSize + MAX_MSD_PREC_OFFSET) {
             // Display a probable but uncertain 0 as "0.000000000",
             // without exponent.  That's a judgment call, but less likely
             // to confuse naive users.  A more informative and confusing
@@ -576,10 +578,10 @@
      *              that if it doesn't contain enough significant digits, we can
      *              reasonably abbreviate as SHORT_UNCERTAIN_ZERO.
      * @param msdIndex Index of most significant digit in cache, or INVALID_MSD.
-     * @param lsd Position of least significant digit in finite representation,
+     * @param lsdOffset Position of least significant digit in finite representation,
      *            relative to decimal point, or MAX_VALUE.
      */
-    private String getShortString(String cache, int msdIndex, int lsd) {
+    private String getShortString(String cache, int msdIndex, int lsdOffset) {
         // This somewhat mirrors the display formatting code, but
         // - The constants are different, since we don't want to use the whole display.
         // - This is an easier problem, since we don't support scrolling and the length
@@ -594,7 +596,7 @@
             msdIndex = INVALID_MSD;
         }
         if (msdIndex == INVALID_MSD) {
-            if (lsd < INIT_PREC) {
+            if (lsdOffset < INIT_PREC) {
                 return "0";
             } else {
                 return SHORT_UNCERTAIN_ZERO;
@@ -602,19 +604,19 @@
         }
         // Avoid scientific notation for small numbers of zeros.
         // Instead stretch significant digits to include decimal point.
-        if (lsd < -1 && dotIndex - msdIndex + negative <= SHORT_TARGET_LENGTH
-            && lsd >= -CalculatorResult.MAX_TRAILING_ZEROES - 1) {
+        if (lsdOffset < -1 && dotIndex - msdIndex + negative <= SHORT_TARGET_LENGTH
+            && lsdOffset >= -CalculatorResult.MAX_TRAILING_ZEROES - 1) {
             // Whole number that fits in allotted space.
             // CalculatorResult would not use scientific notation either.
-            lsd = -1;
+            lsdOffset = -1;
         }
         if (msdIndex > dotIndex) {
             if (msdIndex <= dotIndex + EXP_COST + 1) {
                 // Preferred display format inthis cases is with leading zeroes, even if
                 // it doesn't fit entirely.  Replicate that here.
                 msdIndex = dotIndex - 1;
-            } else if (lsd <= SHORT_TARGET_LENGTH - negative - 2
-                    && lsd <= CalculatorResult.MAX_LEADING_ZEROES + 1) {
+            } else if (lsdOffset <= SHORT_TARGET_LENGTH - negative - 2
+                    && lsdOffset <= CalculatorResult.MAX_LEADING_ZEROES + 1) {
                 // Fraction that fits entirely in allotted space.
                 // CalculatorResult would not use scientific notation either.
                 msdIndex = dotIndex -1;
@@ -625,10 +627,10 @@
             // Adjust for the fact that the decimal point itself takes space.
             exponent--;
         }
-        if (lsd != Integer.MAX_VALUE) {
-            int lsdIndex = dotIndex + lsd;
-            int totalDigits = lsdIndex - msdIndex + negative + 1;
-            if (totalDigits <= SHORT_TARGET_LENGTH && dotIndex > msdIndex && lsd >= -1) {
+        if (lsdOffset != Integer.MAX_VALUE) {
+            final int lsdIndex = dotIndex + lsdOffset;
+            final int totalDigits = lsdIndex - msdIndex + negative + 1;
+            if (totalDigits <= SHORT_TARGET_LENGTH && dotIndex > msdIndex && lsdOffset >= -1) {
                 // Fits, no exponent needed.
                 return negativeSign + cache.substring(msdIndex, lsdIndex + 1);
             }
@@ -648,52 +650,63 @@
                 + KeyMaps.ELLIPSIS + "E" + exponent;
     }
 
-    // Return the most significant digit position in the given string
-    // or INVALID_MSD.
-    public static int getMsdPos(String s) {
-        int len = s.length();
-        int nonzeroPos = -1;
+    /**
+     * Return the most significant digit index in the given numeric string.
+     * Return INVALID_MSD if there are not enough digits to prove the numeric value is
+     * different from zero.  As usual, we assume an error of strictly less than 1 ulp.
+     */
+    public static int getMsdIndexOf(String s) {
+        final int len = s.length();
+        int nonzeroIndex = -1;
         for (int i = 0; i < len; ++i) {
             char c = s.charAt(i);
             if (c != '-' && c != '.' && c != '0') {
-                nonzeroPos = i;
+                nonzeroIndex = i;
                 break;
             }
         }
-        if (nonzeroPos >= 0 &&
-            (nonzeroPos < len - 1 || s.charAt(nonzeroPos) != '1')) {
-                return nonzeroPos;
+        if (nonzeroIndex >= 0 && (nonzeroIndex < len - 1 || s.charAt(nonzeroIndex) != '1')) {
+            return nonzeroIndex;
         } else {
-            // Unknown, or could change on reevaluation
             return INVALID_MSD;
         }
     }
 
-    // Return most significant digit position in the cache, if determined,
-    // INVALID_MSD ow.
-    // If unknown, and we've computed less than DESIRED_PREC,
-    // schedule reevaluation and redisplay, with higher precision.
-    int getMsd() {
-        if (mMsd != INVALID_MSD) return mMsd;
+    /**
+     * Return most significant digit index in the currently computed result.
+     * Returns an index in the result character array.  Return INVALID_MSD if the current result
+     * is too close to zero to determine the result.
+     */
+    private int getMsdIndex() {
+        // FIXME: We currently never adjust msd once computed, even if the result changes
+        // from 0.100000...  to 0.0999999...  (We know it can't change in the other direction.)
+        // It would be cheap to increment it if the current "most significant digit" is zero.
+        // And it would make it easier to reason about the code.  We should do that.
+        if (mMsdIndex != INVALID_MSD) return mMsdIndex;
         if (mRatVal != null && mRatVal.signum() == 0) {
             return INVALID_MSD;  // None exists
         }
-        int res = INVALID_MSD;
-        if (mCache != null) {
-            res = getMsdPos(mCache);
+        int result = INVALID_MSD;
+        if (mResultString != null) {
+            result = getMsdIndexOf(mResultString);
         }
-        if (res == INVALID_MSD && mEvaluator == null
-            && mCurrentReevaluator == null && mCacheDigs < MAX_MSD_PREC) {
-            // We assert that mCache is not null, since there is no
+        // FIXME: I think the following conditional is no longer needed.  The initial
+        // background evaluation already ensures that either the msd is know, or we've
+        // evaluated to MAX_MSD_PREC_OFFSET.
+        if (result == INVALID_MSD && mEvaluator == null
+            && mCurrentReevaluator == null && mResultStringOffset < MAX_MSD_PREC_OFFSET) {
+            // We assert that mResultString is not null, since there is no
             // evaluator running.
-            ensureCachePrec(MAX_MSD_PREC);
+            ensureCachePrec(MAX_MSD_PREC_OFFSET);
             // Could reevaluate more incrementally, but we suspect that if
             // we have to reevaluate at all, the result is probably zero.
         }
-        return res;
+        return result;
     }
 
-    // Return a string with n placeholder characters.
+    /**
+     * Return a string with n placeholder characters.
+     */
     private String getPadding(int n) {
         StringBuilder padding = new StringBuilder();
         for (int i = 0; i < n; ++i) {
@@ -702,108 +715,107 @@
         return padding.toString();
     }
 
-    // Return the number of zero characters at the beginning of s
+    /**
+     * Return the number of zero characters at the beginning of s.
+     */
     private int leadingZeroes(String s) {
-        int res = 0;
-        int len = s.length();
-        for (res = 0; res < len && s.charAt(res) == '0'; ++res) {}
-        return res;
+        int result = 0;
+        final int len = s.length();
+        for (result = 0; result < len && s.charAt(result) == '0'; ++result) {}
+        return result;
     }
 
-    private static final int MIN_DIGS = 5;
-            // Leave at least this many digits from the whole number
-            // part on the screen, to avoid silly displays like 1E1.
-    // Return result to exactly prec[0] digits to the right of the
-    // decimal point.
-    // The result should be no longer than maxDigs.
-    // No exponent or other indication of precision is added.
-    // The result is returned immediately, based on the
-    // current cache contents, but it may contain question
-    // marks for unknown digits.  It may also use uncertain
-    // digits within EXTRA_DIGITS.  If either of those occurred,
-    // schedule a reevaluation and redisplay operation.
-    // Uncertain digits never appear to the left of the decimal point.
-    // digs may be negative to only retrieve digits to the left
-    // of the decimal point.  (prec[0] = 0 means we include
-    // the decimal point, but nothing to the right.  prec[0] = -1
-    // means we drop the decimal point and start at the ones
-    // position.  Should not be invoked if mVal is null.
-    // This essentially just returns a substring of the full result;
-    // a leading minus sign or leading digits can be dropped.
-    // Result uses US conventions; is NOT internationalized.
-    // We set negative[0] if the number as a whole is negative,
-    // since we may drop the minus sign.
-    // We set truncated[0] if leading nonzero digits were dropped.
-    // getRational() can be used to determine whether the result
-    // is exact, or whether we dropped trailing digits.
-    // If the requested prec[0] value is out of range, we update
-    // it in place and use the updated value.  But we do not make it
-    // greater than maxPrec.
-    public String getString(int[] prec, int maxPrec, int maxDigs,
-                            boolean[] truncated, boolean[] negative) {
-        int digs = prec[0];
-        mLastDigs = digs;
+    // Refuse to scroll past the point at which this many digits from the whole number
+    // part of the result are still displayed.  Avoids sily displays like 1E1.
+    private static final int MIN_DISPLAYED_DIGS = 5;
+
+    /**
+     * Return result to precOffset[0] digits to the right of the decimal point.
+     * PrecOffset[0] is updated if the original value is out of range.  No exponent or other
+     * indication of precision is added.  The result is returned immediately, based on the current
+     * cache contents, but it may contain question marks for unknown digits.  It may also use
+     * uncertain digits within EXTRA_DIGITS.  If either of those occurred, schedule a reevaluation
+     * and redisplay operation.  Uncertain digits never appear to the left of the decimal point.
+     * PrecOffset[0] may be negative to only retrieve digits to the left of the decimal point.
+     * (precOffset[0] = 0 means we include the decimal point, but nothing to the right.
+     * precOffset[0] = -1 means we drop the decimal point and start at the ones position.  Should
+     * not be invoked before the onEvaluate() callback is received.  This essentially just returns
+     * a substring of the full result; a leading minus sign or leading digits can be dropped.
+     * Result uses US conventions; is NOT internationalized.  Use getRational() to determine
+     * whether the result is exact, or whether we dropped trailing digits.
+     *
+     * @param precOffset Zeroth element indicates desired and actual precision
+     * @param maxPrecOffset Maximum adjusted precOffset[0]
+     * @param maxDigs Maximum length of result 
+     * @param truncated Zeroth element is set if leading nonzero digits were dropped
+     * @param negative Zeroth element is set of the result is negative.
+     */
+    public String getString(int[] precOffset, int maxPrecOffset, int maxDigs, boolean[] truncated,
+            boolean[] negative) {
+        int currentPrecOffset = precOffset[0];
         // Make sure we eventually get a complete answer
-            if (mCache == null) {
-                ensureCachePrec(digs + EXTRA_DIGITS);
-                // Nothing else to do now; seems to happen on rare occasion
-                // with weird user input timing;
-                // Will repair itself in a jiffy.
-                return getPadding(1);
-            } else {
-                ensureCachePrec(digs + EXTRA_DIGITS
-                        + mCache.length() / EXTRA_DIVISOR);
+        if (mResultString == null) {
+            ensureCachePrec(currentPrecOffset + EXTRA_DIGITS);
+            // Nothing else to do now; seems to happen on rare occasion with weird user input
+            // timing; Will repair itself in a jiffy.
+            return getPadding(1);
+        } else {
+            ensureCachePrec(currentPrecOffset + EXTRA_DIGITS + mResultString.length()
+                    / EXTRA_DIVISOR);
+        }
+        // Compute an appropriate substring of mResultString.  Pad if necessary.
+        final int len = mResultString.length();
+        final boolean myNegative = mResultString.charAt(0) == '-';
+        negative[0] = myNegative;
+        // Don't scroll left past leftmost digits in mResultString unless that still leaves an
+        // integer.
+            int integralDigits = len - mResultStringOffset;
+                            // includes 1 for dec. pt
+            if (myNegative) {
+                --integralDigits;
             }
-        // Compute an appropriate substring of mCache.
-        // We avoid returning a huge string to minimize string
-        // allocation during scrolling.
-        // Pad as needed.
-            final int len = mCache.length();
-            final boolean myNegative = mCache.charAt(0) == '-';
-            negative[0] = myNegative;
-            // Don't scroll left past leftmost digits in mCache
-            // unless that still leaves an integer.
-                int integralDigits = len - mCacheDigs;
-                                // includes 1 for dec. pt
-                if (myNegative) --integralDigits;
-                int minDigs = Math.min(-integralDigits + MIN_DIGS, -1);
-                digs = Math.min(Math.max(digs, minDigs), maxPrec);
-                prec[0] = digs;
-            int offset = mCacheDigs - digs; // trailing digits to drop
-            int deficit = 0;  // The number of digits we're short
-            if (offset < 0) {
-                offset = 0;
-                deficit = Math.min(digs - mCacheDigs, maxDigs);
-            }
-            int endIndx = len - offset;
-            if (endIndx < 1) return " ";
-            int startIndx = (endIndx + deficit <= maxDigs) ?
-                                0
-                                : endIndx + deficit - maxDigs;
-            truncated[0] = (startIndx > getMsd());
-            String res = mCache.substring(startIndx, endIndx);
-            if (deficit > 0) {
-                res = res + getPadding(deficit);
-                // Since we always compute past the decimal point,
-                // this never fills in the spot where the decimal point
-                // should go, and the rest of this can treat the
-                // made-up symbols as though they were digits.
-            }
-            return res;
+            int minPrecOffset = Math.min(MIN_DISPLAYED_DIGS - integralDigits, -1);
+            currentPrecOffset = Math.min(Math.max(currentPrecOffset, minPrecOffset),
+                    maxPrecOffset);
+            precOffset[0] = currentPrecOffset;
+        int extraDigs = mResultStringOffset - currentPrecOffset; // trailing digits to drop
+        int deficit = 0;  // The number of digits we're short
+        if (extraDigs < 0) {
+            extraDigs = 0;
+            deficit = Math.min(currentPrecOffset - mResultStringOffset, maxDigs);
+        }
+        int endIndex = len - extraDigs;
+        if (endIndex < 1) {
+            return " ";
+        }
+        int startIndex = Math.max(endIndex + deficit - maxDigs, 0);
+        truncated[0] = (startIndex > getMsdIndex());
+        String result = mResultString.substring(startIndex, endIndex);
+        if (deficit > 0) {
+            result += getPadding(deficit);
+            // Since we always compute past the decimal point, this never fills in the spot
+            // where the decimal point should go, and we can otherwise treat placeholders
+            // as though they were digits.
+        }
+        return result;
     }
 
-    // Return rational representation of current result, if any.
+    /**
+     * Return rational representation of current result, if any.
+     * Return null if the result is irrational, or we couldn't track the rational value,
+     * e.g. because the denominator got too big.
+     */
     public BoundedRational getRational() {
         return mRatVal;
     }
 
     private void clearCache() {
-        mCache = null;
-        mCacheDigs = mCacheDigsReq = 0;
-        mMsd = INVALID_MSD;
+        mResultString = null;
+        mResultStringOffset = mResultStringOffsetReq = 0;
+        mMsdIndex = INVALID_MSD;
     }
 
-    void clear() {
+    public void clear() {
         mExpr.clear();
         clearCache();
     }
@@ -813,18 +825,18 @@
      * Will result in display on completion.
      * @param required result was explicitly requested by user.
      */
-    private void reevaluateResult(boolean required) {
+    private void evaluateResult(boolean required) {
         clearCache();
-        mEvaluator = new AsyncDisplayResult(mDegreeMode, required);
+        mEvaluator = new AsyncEvaluator(mDegreeMode, required);
         mEvaluator.execute();
         mChangedValue = false;
     }
 
-    // Begin evaluation of result and display when ready.
-    // We assume this is called after each insertion and deletion.
-    // Thus if we are called twice with the same effective end of
-    // the formula, the evaluation is redundant.
-    void evaluateAndShowResult() {
+    /**
+     * Start optional evaluation of result and display when ready.
+     * Can quietly time out without a user-visible display.
+     */
+    public void evaluateAndShowResult() {
         if (!mChangedValue) {
             // Already done or in progress.
             return;
@@ -832,25 +844,27 @@
         // In very odd cases, there can be significant latency to evaluate.
         // Don't show obsolete result.
         mResult.clear();
-        reevaluateResult(false);
+        evaluateResult(false);
     }
 
-    // Ensure that we either display a result or complain.
-    // Does not invalidate a previously computed cache.
-    // We presume that any prior result was computed using the same
-    // expression.
-    void requireResult() {
-        if (mCache == null || mChangedValue) {
+    /**
+     * Start required evaluation of result and display when ready.
+     * Will eventually call back mCalculator to display result or error, or display
+     * a timeout message.  Uses longer timeouts than optional evaluation.
+     */ 
+    public void requireResult() {
+        if (mResultString == null || mChangedValue) {
             // Restart evaluator in requested mode, i.e. with longer timeout.
             cancelAll(true);
-            reevaluateResult(true);
+            evaluateResult(true);
         } else {
             // Notify immediately, reusing existing result.
-            int dotPos = mCache.indexOf('.');
-            String truncatedWholePart = mCache.substring(0, dotPos);
-            int leastDigOffset = getLsd(mRatVal, mCache, dotPos);
-            int msdIndex = getMsd();
-            int preferredPrecOffset = getPreferredPrec(mCache, msdIndex, leastDigOffset);
+            final int dotIndex = mResultString.indexOf('.');
+            final String truncatedWholePart = mResultString.substring(0, dotIndex);
+            final int leastDigOffset = getLsdOffset(mRatVal, mResultString, dotIndex);
+            final int msdIndex = getMsdIndex();
+            final int preferredPrecOffset = getPreferredPrec(mResultString, msdIndex,
+                    leastDigOffset);
             mCalculator.onEvaluate(preferredPrecOffset, msdIndex, leastDigOffset,
                     truncatedWholePart);
         }
@@ -861,10 +875,10 @@
      * @param quiet suppress cancellation message
      * @return      true if we cancelled an initial evaluation
      */
-    boolean cancelAll(boolean quiet) {
+    public boolean cancelAll(boolean quiet) {
         if (mCurrentReevaluator != null) {
             mCurrentReevaluator.cancel(true);
-            mCacheDigsReq = mCacheDigs;
+            mResultStringOffsetReq = mResultStringOffset;
             // Backgound computation touches only constructive reals.
             // OK not to wait.
             mCurrentReevaluator = null;
@@ -888,10 +902,14 @@
         return false;
     }
 
-    void restoreInstanceState(DataInput in) {
+    /**
+     * Restore the evaluator state, including the expression and any saved value.
+     */
+    public void restoreInstanceState(DataInput in) {
         mChangedValue = true;
         try {
             CalculatorExpr.initExprInput();
+            // FIXME: Do we still need to restore DegreeMode here?
             mDegreeMode = in.readBoolean();
             mExpr = new CalculatorExpr(in);
             mSavedName = in.readUTF();
@@ -901,7 +919,10 @@
         }
     }
 
-    void saveInstanceState(DataOutput out) {
+    /**
+     * Save the evaluator state, including the expression and any saved value.
+     */
+    public void saveInstanceState(DataOutput out) {
         try {
             CalculatorExpr.initExprOutput();
             out.writeBoolean(mDegreeMode);
@@ -913,11 +934,14 @@
         }
     }
 
-    // Append a button press to the current expression.
-    // Return false if we rejected the insertion due to obvious
-    // syntax issues, and the expression is unchanged.
-    // Return true otherwise.
-    boolean append(int id) {
+
+    /**
+     * Append a button press to the current expression.
+     * @param id Button identifier for the character or operator to be added.
+     * @return false if we rejected the insertion due to obvious syntax issues, and the expression
+     * is unchanged; true otherwise
+     */
+    public boolean append(int id) {
         if (id == R.id.fun_10pow) {
             add10pow();  // Handled as macro expansion.
             return true;
@@ -927,7 +951,7 @@
         }
     }
 
-    void delete() {
+    public void delete() {
         mChangedValue = true;
         mExpr.delete();
     }
@@ -946,79 +970,80 @@
     }
 
     /**
-     * @return the {@link CalculatorExpr} representation of the current result
+     * @return the {@link CalculatorExpr} representation of the current result.
      */
-    CalculatorExpr getResultExpr() {
-        final int dotPos = mCache.indexOf('.');
-        final int leastDigPos = getLsd(mRatVal, mCache, dotPos);
+    private CalculatorExpr getResultExpr() {
+        final int dotIndex = mResultString.indexOf('.');
+        final int leastDigOffset = getLsdOffset(mRatVal, mResultString, dotIndex);
         return mExpr.abbreviate(mVal, mRatVal, mDegreeMode,
-               getShortString(mCache, getMsdPos(mCache), leastDigPos));
+                getShortString(mResultString, getMsdIndexOf(mResultString), leastDigOffset));
     }
 
-    // Abbreviate the current expression to a pre-evaluated
-    // expression node, which will display as a short number.
-    // This should not be called unless the expression was
-    // previously evaluated and produced a non-error result.
-    // Pre-evaluated expressions can never represent an
-    // expression for which evaluation to a constructive real
-    // diverges.  Subsequent re-evaluation will also not diverge,
-    // though it may generate errors of various kinds.
-    // E.g. sqrt(-10^-1000)
-    void collapse() {
+    /**
+     * Abbreviate the current expression to a pre-evaluated expression node.
+     * This should not be called unless the expression was previously evaluated and produced a
+     * non-error result.  Pre-evaluated expressions can never represent an expression for which
+     * evaluation to a constructive real diverges.  Subsequent re-evaluation will also not
+     * diverge, though it may generate errors of various kinds.  E.g.  sqrt(-10^-1000) .
+     */
+    public void collapse() {
         final CalculatorExpr abbrvExpr = getResultExpr();
         clear();
         mExpr.append(abbrvExpr);
         mChangedValue = true;
     }
 
-    // Same as above, but put result in mSaved, leaving mExpr alone.
-    // Return false if result is unavailable.
-    boolean collapseToSaved() {
-        if (mCache == null) {
+    /**
+     * Abbreviate current expression, and put result in mSaved.
+     * mExpr is left alone.  Return false if result is unavailable.
+     */
+    public boolean collapseToSaved() {
+        if (mResultString == null) {
             return false;
         }
-
         final CalculatorExpr abbrvExpr = getResultExpr();
         mSaved.clear();
         mSaved.append(abbrvExpr);
         return true;
     }
 
-    Uri uriForSaved() {
+    private Uri uriForSaved() {
         return new Uri.Builder().scheme("tag")
                                 .encodedOpaquePart(mSavedName)
                                 .build();
     }
 
-    // Collapse the current expression to mSaved and return a URI
-    // describing this particular result, so that we can refer to it
-    // later.
-    Uri capture() {
+    /**
+     * Collapse the current expression to mSaved and return a URI describing it.
+     * describing this particular result, so that we can refer to it
+     * later.
+     */
+    public Uri capture() {
         if (!collapseToSaved()) return null;
         // Generate a new (entirely private) URI for this result.
         // Attempt to conform to RFC4151, though it's unclear it matters.
-        Date date = new Date();
-        TimeZone tz = TimeZone.getDefault();
+        final TimeZone tz = TimeZone.getDefault();
         DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
         df.setTimeZone(tz);
-        String isoDate = df.format(new Date());
+        final String isoDate = df.format(new Date());
         mSavedName = "calculator2.android.com," + isoDate + ":"
-                     + (new Random().nextInt() & 0x3fffffff);
-        Uri tag = uriForSaved();
-        return tag;
+                + (new Random().nextInt() & 0x3fffffff);
+        return uriForSaved();
     }
 
-    boolean isLastSaved(Uri uri) {
+    public boolean isLastSaved(Uri uri) {
         return uri.equals(uriForSaved());
     }
 
-    void addSaved() {
+    public void appendSaved() {
         mChangedValue = true;
         mExpr.append(mSaved);
     }
 
-    // Add the power of 10 operator to the expression.  This is treated
-    // essentially as a macro expansion.
+    /**
+     * Add the power of 10 operator to the expression.
+     * This is treated essentially as a macro expansion.
+     */
     private void add10pow() {
         CalculatorExpr ten = new CalculatorExpr();
         ten.add(R.id.digit_1);
@@ -1028,24 +1053,31 @@
         mExpr.add(R.id.op_pow);
     }
 
-    // Retrieve the main expression being edited.
-    // It is the callee's reponsibility to call cancelAll to cancel
-    // ongoing concurrent computations before modifying the result.
-    // TODO: Perhaps add functionality so we can keep this private?
-    CalculatorExpr getExpr() {
+    /**
+     * Retrieve the main expression being edited.
+     * It is the callee's reponsibility to call cancelAll to cancel ongoing concurrent
+     * computations before modifying the result.  The resulting expression should only
+     * be modified by the caller if either the expression value doesn't change, or in
+     * combination with another add() or delete() call that makes the value change apparent
+     * to us.
+     * TODO: Perhaps add functionality so we can keep this private?
+     */
+    public CalculatorExpr getExpr() {
         return mExpr;
     }
 
+    /**
+     * Maximum number of characters in a scientific notation exponent.
+     */
     private static final int MAX_EXP_CHARS = 8;
 
     /**
      * Return the index of the character after the exponent starting at s[offset].
      * Return offset if there is no exponent at that position.
-     * Exponents have syntax E[-]digit* .
-     * "E2" and "E-2" are valid.  "E+2" and "e2" are not.
+     * Exponents have syntax E[-]digit* .  "E2" and "E-2" are valid.  "E+2" and "e2" are not.
      * We allow any Unicode digits, and either of the commonly used minus characters.
      */
-    static int exponentEnd(String s, int offset) {
+    public static int exponentEnd(String s, int offset) {
         int i = offset;
         int len = s.length();
         if (i >= len - 1 || s.charAt(i) != 'E') {
@@ -1068,10 +1100,10 @@
     /**
      * Add the exponent represented by s[begin..end) to the constant at the end of current
      * expression.
-     * The end of the current expression must be a constant.
-     * Exponents have the same syntax as for exponentEnd().
+     * The end of the current expression must be a constant.  Exponents have the same syntax as
+     * for exponentEnd().
      */
-    void addExponent(String s, int begin, int end) {
+    public void addExponent(String s, int begin, int end) {
         int sign = 1;
         int exp = 0;
         int i = begin + 1;
