diff --git a/java/pom.xml b/java/pom.xml
index a71a69a..69d8ff7 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -198,7 +198,6 @@
                 <include>**/CodedInputStreamMicro.java</include>
                 <include>**/CodedOutputStreamMicro.java</include>
                 <include>**/InvalidProtocolBufferMicroException.java</include>
-                <include>**/StringUtf8Micro.java</include>
                 <include>**/WireFormatMicro.java</include>
               </includes>
               <testIncludes>
diff --git a/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java b/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java
index 68b6e97..0cb0774 100644
--- a/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java
+++ b/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java
@@ -179,13 +179,6 @@
     writeStringNoTag(value);
   }
 
-  /** Write a {@code StringUtf8Micro} field, including tag, to the stream. */
-  public void writeStringUtf8(final int fieldNumber, final StringUtf8Micro value)
-                          throws IOException {
-    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED);
-    writeStringUtf8NoTag(value);
-  }
-
   /** Write a {@code group} field, including tag, to the stream. */
   public void writeGroup(final int fieldNumber, final MessageMicro value)
                          throws IOException {
@@ -208,6 +201,14 @@
     writeBytesNoTag(value);
   }
 
+  /** Write a {@code byte} field, including tag, to the stream. */
+  public void writeByteArray(final int fieldNumber, final byte[] value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED);
+    writeByteArrayNoTag(value);
+  }
+
+
   /** Write a {@code uint32} field, including tag, to the stream. */
   public void writeUInt32(final int fieldNumber, final int value)
                           throws IOException {
@@ -336,13 +337,6 @@
     writeRawBytes(bytes);
   }
 
-  /** Write a {@code StringUtf8Micro} field to the stream. */
-  public void writeStringUtf8NoTag(final StringUtf8Micro value) throws IOException {
-    final byte[] bytes = value.getBytes();
-    writeRawVarint32(bytes.length);
-    writeRawBytes(bytes);
-  }
-
   /** Write a {@code group} field to the stream. */
   public void writeGroupNoTag(final MessageMicro value) throws IOException {
     value.writeTo(this);
@@ -361,6 +355,12 @@
     writeRawBytes(bytes);
   }
 
+  /** Write a {@code byte[]} field to the stream. */
+  public void writeByteArrayNoTag(final byte [] value) throws IOException {
+    writeRawVarint32(value.length);
+    writeRawBytes(value);
+  }
+
   /** Write a {@code uint32} field to the stream. */
   public void writeUInt32NoTag(final int value) throws IOException {
     writeRawVarint32(value);
@@ -475,15 +475,6 @@
 
   /**
    * Compute the number of bytes that would be needed to encode a
-   * {@code StringUtf8Micro} field, including tag.
-   */
-  public static int computeStringUtf8Size(final int fieldNumber,
-                                      final StringUtf8Micro value) {
-    return computeTagSize(fieldNumber) + computeStringUtf8SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a
    * {@code group} field, including tag.
    */
   public static int computeGroupSize(final int fieldNumber,
@@ -511,6 +502,15 @@
 
   /**
    * Compute the number of bytes that would be needed to encode a
+   * {@code byte[]} field, including tag.
+   */
+  public static int computeByteArraySize(final int fieldNumber,
+                                     final byte[] value) {
+    return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
    * {@code uint32} field, including tag.
    */
   public static int computeUInt32Size(final int fieldNumber, final int value) {
@@ -671,16 +671,6 @@
 
   /**
    * Compute the number of bytes that would be needed to encode a
-   * {@code StringUtf8Micro} field.
-   */
-  public static int computeStringUtf8SizeNoTag(final StringUtf8Micro value) {
-    final byte[] bytes = value.getBytes();
-    return computeRawVarint32Size(bytes.length) +
-             bytes.length;
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a
    * {@code group} field.
    */
   public static int computeGroupSizeNoTag(final MessageMicro value) {
@@ -701,8 +691,15 @@
    * {@code bytes} field.
    */
   public static int computeBytesSizeNoTag(final ByteStringMicro value) {
-    return computeRawVarint32Size(value.size()) +
-           value.size();
+    return computeRawVarint32Size(value.size()) + value.size();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code byte[]} field.
+   */
+  public static int computeByteArraySizeNoTag(final byte[] value) {
+    return computeRawVarint32Size(value.length) + value.length;
   }
 
   /**
diff --git a/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java b/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java
deleted file mode 100644
index 0c43e54..0000000
--- a/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://code.google.com/p/protobuf/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf.micro;
-
-/**
- * A surogate for a String with a UTF8 representation.
- *
- * @author wink@google.com Wink Saville
- */
-public final class StringUtf8Micro {
-  private String string;
-  private byte[] bytes;
-
-  public StringUtf8Micro(String string) {
-    setString(string);
-  }
-
-  public static final StringUtf8Micro EMPTY = new StringUtf8Micro("");
-
-  public String getString() {
-    return string;
-  }
-
-  public void setString(String string) {
-    this.string = string;
-    bytes = null;
-  }
-
-  public byte [] getBytes() {
-    if (bytes == null) {
-      try {
-        bytes = string.getBytes("UTF-8");
-      } catch (java.io.UnsupportedEncodingException e) {
-        throw new RuntimeException("UTF-8 not supported.");
-      }
-    }
-    return bytes;
-  }
-}
diff --git a/java/src/test/java/com/google/protobuf/PerfTimer.java b/java/src/test/java/com/google/protobuf/PerfTimer.java
deleted file mode 100644
index d6df4ff..0000000
--- a/java/src/test/java/com/google/protobuf/PerfTimer.java
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.protobuf;
-
-import java.util.Arrays;
-
-/**
- * A Performance Timing class that can be used to estimate the amount of time a
- * sequence of code takes. The typical code sequence would be as follows:</p>
- * <code>
- PerfTimer pt = new PerfTimer();
- pt.calibrate();
- pt.timeEachAutomatically(new Runnable() = {
-    public void run() {
-        // Add code to time
-    }
- });
- System.out.printf("time per loop=" + pt);
-
- * The calibrate method determines the overhead of timing the run() method and
- * the number of times to call the run() method to have approximately 1% precision
- * for timing. The method pt.stats() method will return a string containing some
- * statistics tpl, il, ol, min, max, mean, median, stddev and total.
- *
- * tpl    ::= Timer per loop
- * min    ::= minimum time one call to run() took
- * stddev ::= Standard deviation of the collected times
- * mean   ::= the average time to call run()
- * median ::= 1/2 the times were > than this time and 1/2 were less.
- * total  ::= Sum of the times collected.
- * il     ::= innerLoops; the number of times run() between each call to start/stop
- * ol     ::= outerLoops, the number of times start/stop was called
- *
- * You can also use start/stop/restart to do simple timing:
- *
- * pt.start();
- * a += 1;
- * pt.stop();
- * pt.log("time=" + pt);
- * pt.restart();
- * doSomething();
- * pt.stop();
- * System.out.printf("time=" + pt);
- * </code>
- *
- * @author wink@google.com (Wink Saville)
- */
-public class PerfTimer {
-    /** No debug */
-    public static final int DEBUG_LEVEL_NONE = 0;
-
-    /** Some debug */
-    public static final int DEBUG_LEVEL_SOME = 1;
-
-    /** All debug */
-    public static final int DEBUG_LEVEL_ALL = 2;
-
-    /** Timer ticks per microsecond */
-    private static final double TICKS_PER_MICROSECOND = 1000.0;
-
-    /** Random number generator */
-    java.util.Random rng = new java.util.Random();
-
-    /** get ticks */
-    private static long getTicks() {
-        return System.nanoTime();
-    }
-
-    /** Debug logging */
-    private static void log(String s) {
-        System.out.printf(String.format("[PerfTimer] %s\n", s));
-    }
-
-    /** Outer loops for timeEachAutomatically */
-    private static final int OUTER_LOOPS = 100;
-
-    /** Thrown if an error occurs while timing */
-    public static class PerfTimerException extends RuntimeException {
-    }
-
-    /**
-     * Calibration record
-     */
-    public static class CalibrationRec {
-        /** Runnable overhead */
-        public double mRunnableOverheadInMicros = 0.0;
-
-        /** Minimum Threshold value for timeEachAutomaticaly */
-        public double mMinThresholdInMicros = 3000.0;
-
-        /** Maximum Threshold value for timeEachAutomaticaly */
-        public double mMaxThresholdInMicros = 6000.0;
-
-        /** Desired precision in decimal digits */
-        public double mPrecisionInDecimalDigits = 2.0;
-
-        /**
-         * Default number of retries if the standard deviation ratio is too
-         * large
-         */
-        public final int mStdDevRetrys = 5;
-
-        /** Default maximum standard deviation radio */
-        public final double mMaxStdDevRatio = 0.15;
-
-        /** Number of votes looking for smallest time per loop */
-        public final int mVotes = 3;
-
-        /** Convert to string */
-        @Override
-        public String toString() {
-            return String
-                    .format(
-                            "oh=%.6fus minT=%.6fus maxT=%.6fus prc=%,.3f stdDevRetrys=%d maxStdDevRatio=%.2f votes=%d",
-                            mRunnableOverheadInMicros, mMinThresholdInMicros,
-                            mMaxThresholdInMicros, mPrecisionInDecimalDigits, mStdDevRetrys,
-                            mMaxStdDevRatio, mVotes);
-        }
-    }
-
-    /**
-     * Calibration record
-     */
-    private CalibrationRec mCr;
-
-    /**
-     * Statistics calculated on the timing data.
-     */
-    public static class Stats {
-        /** Number of outer loops */
-        private int mOuterLoops;
-
-        /** Number of inner loops */
-        private int mInnerLoops;
-
-        /** Minimum time in times array */
-        private long mMin;
-
-        /** Maximum time in times array */
-        private long mMax;
-
-        /** Median value in times array */
-        private double mMedian;
-
-        /** The mean (average) of the values in times array */
-        private double mMean;
-
-        /** The standard deviation of the values in times array */
-        private double mStdDev;
-
-        private int mStdDevTooLargeCount;
-
-        /** Sum of the times in the times array */
-        private double mTotal;
-
-        /** Initialize */
-        public void init() {
-            mInnerLoops = 1;
-            mOuterLoops = 1;
-            mMin = 0;
-            mMax = 0;
-            mMedian = 0;
-            mMean = 0;
-            mStdDev = 0;
-            mStdDevTooLargeCount = 0;
-            mTotal = 0;
-        }
-
-        /** Constructor */
-        public Stats() {
-            init();
-        }
-
-        /** Set number of inner loops */
-        public void setInnerLoops(int loops) {
-            mInnerLoops = loops;
-        }
-
-        /** Get number of inner loops */
-        public int getInnerLoops() {
-            return mInnerLoops;
-        }
-
-        /** Set number of inner loops */
-        public void setOuterLoops(int loops) {
-            mOuterLoops = loops;
-        }
-
-        /** Get number of inner loops */
-        public int getOuterLoops() {
-            return mOuterLoops;
-        }
-
-        /**
-         * Minimum value of collected data in microseconds, valid after analyze.
-         */
-        public double getMinInMicros() {
-            return mMin / TICKS_PER_MICROSECOND;
-        }
-
-        /**
-         * Maximum value of collected data in microseconds, valid after analyze.
-         */
-        public double getMaxInMicros() {
-            return mMax / TICKS_PER_MICROSECOND;
-        }
-
-        /**
-         * Sum of the values of collected data in microseconds, valid after
-         * analyze.
-         */
-        public double getTotalInMicros() {
-            return mTotal / TICKS_PER_MICROSECOND;
-        }
-
-        /** Sum of the values of collected data in seconds, valid after analyze. */
-        public double getTotalInSecs() {
-            return mTotal / (TICKS_PER_MICROSECOND * 1000000.0);
-        }
-
-        /** Sum of the values of collected data in seconds, valid after analyze. */
-        public double getMeanInMicros() {
-            return mMean / TICKS_PER_MICROSECOND;
-        }
-
-        /** Median value of collected data in microseconds, valid after analyze. */
-        public double getMedianInMicros() {
-            return mMedian / TICKS_PER_MICROSECOND;
-        }
-
-        /**
-         * Standard deviation of collected data in microseconds, valid after
-         * analyze.
-         */
-        public double getStdDevInMicros() {
-            return mStdDev / TICKS_PER_MICROSECOND;
-        }
-
-        public double getStdDevRatio() {
-            return mStdDev / mMin;
-        }
-
-        /** Return true if (mStdDev / mMin) <= maxStdDevRation */
-        public boolean stdDevOk(double maxStdDevRatio) {
-            return getStdDevRatio() <= maxStdDevRatio;
-        }
-
-        /** Increment StdDevTooLargeCount */
-        public void incStdDevTooLargeCount() {
-            mStdDevTooLargeCount += 1;
-        }
-
-        /** Return number of times stdDev was not ok */
-        public int getStdDevTooLargeCount() {
-            return mStdDevTooLargeCount;
-        }
-
-        /** Return time per loop */
-        public double getTimePerLoop() {
-                return mMin / TICKS_PER_MICROSECOND / mInnerLoops;
-        }
-
-        /**
-         * Calculate the stats for the data. Note the data in the range will be
-         * sorted.
-         *
-         * @param data
-         * @param count
-         */
-        public Stats calculate(long data[], int count) {
-            if (count == 1) {
-                mMin = mMax = data[0];
-                mTotal = mMedian = mMean = data[0];
-                mStdDev = 0;
-            } else if (count > 1) {
-                Arrays.sort(data, 0, count);
-                mMin = data[0];
-                mMax = data[count - 1];
-                if ((count & 1) == 1) {
-                    mMedian = data[((count + 1) / 2) - 1];
-                } else {
-                    mMedian = (data[count / 2] + data[(count / 2) - 1]) / 2;
-                }
-                mTotal = 0;
-                double sumSquares = 0;
-                for (int i = 0; i < count; i++) {
-                    long t = data[i];
-                    mTotal += t;
-                    sumSquares += t * t;
-                }
-                mMean = mTotal / count;
-                double variance = (sumSquares / count) - (mMean * mMean);
-                mStdDev = Math.pow(variance, 0.5);
-            } else {
-                init();
-            }
-            return this;
-        }
-
-        /** Convert to string */
-        @Override
-            public String toString() {
-                double timePerLoop = getTimePerLoop();
-                double stdDevPerLoop = mStdDev / TICKS_PER_MICROSECOND / mInnerLoops;
-                return String.format(
-                        "tpl=%,.6fus stdDev=%,.6fus tpl/stdDev=%.2fpercent min=%,.6fus median=%,.6fus mean=%,.6fus max=%,.6fus total=%,.6fs il=%d, ol=%d tlc=%d",
-                        timePerLoop, stdDevPerLoop, (stdDevPerLoop / timePerLoop) * 100, mMin
-                        / TICKS_PER_MICROSECOND, mMedian / TICKS_PER_MICROSECOND, mMean
-                        / TICKS_PER_MICROSECOND, mMax / TICKS_PER_MICROSECOND, mTotal
-                        / (TICKS_PER_MICROSECOND * 1000000.0), mInnerLoops, mOuterLoops, mStdDevTooLargeCount);
-            }
-    }
-
-    /** Statistics */
-    private Stats mStats = new Stats();
-
-    /** Statistics of the clock precision */
-    private Stats mClockStats;
-
-    /** Number of items in times array */
-    private int mCount;
-
-    /** Array of stop - start times */
-    private long mTimes[];
-
-    /** Time of last started */
-    private long mStart;
-
-    /** Sleep a little so we don't look like a hog */
-    private void sleep() {
-        try {
-            Thread.sleep(0);
-        } catch (InterruptedException e) {
-            // Ignore exception
-        }
-    }
-
-    /** Empty Runnable used for determining overhead */
-    private Runnable mEmptyRunnable = new Runnable() {
-        public void run() {
-        }
-    };
-
-    /** Initialize */
-    private void init(int maxCount, CalibrationRec cr) {
-        mTimes = new long[maxCount];
-        mCr = cr;
-        reset();
-    }
-
-    /** Construct the stop watch */
-    public PerfTimer() {
-        init(10, new CalibrationRec());
-    }
-
-    /** Construct setting size of times array */
-    public PerfTimer(int maxCount) {
-        init(maxCount, new CalibrationRec());
-    }
-
-    /** Construct the stop watch */
-    public PerfTimer(CalibrationRec cr) {
-        init(10, cr);
-    }
-
-    /** Construct the stop watch */
-    public PerfTimer(int maxCount, CalibrationRec cr) {
-        init(maxCount, cr);
-    }
-
-    /** Reset the contents of the times array */
-    public PerfTimer reset() {
-        mCount = 0;
-        mStats.init();
-        return this;
-    }
-
-    /** Reset and then start the timer */
-    public PerfTimer restart() {
-        reset();
-        mStart = getTicks();
-        return this;
-    }
-
-    /** Start timing */
-    public PerfTimer start() {
-        mStart = getTicks();
-        return this;
-    }
-
-    /**
-     * Record the difference between start and now in the times array
-     * incrementing count. The time will be stored in the times array if the
-     * array is not full.
-     */
-    public PerfTimer stop() {
-        long stop = getTicks();
-        if (mCount < mTimes.length) {
-            mTimes[mCount++] = stop - mStart;
-        }
-        return this;
-    }
-
-    /**
-     * Time how long it takes to execute runnable.run() innerLoop number of
-     * times outerLoops number of times.
-     *
-     * @param outerLoops
-     * @param innerLoops
-     * @param runnable
-     * @return PerfTimer
-     */
-    public PerfTimer timeEach(Stats stats, int outerLoops, int innerLoops, Runnable runnable) {
-        reset();
-        resize(outerLoops);
-        stats.setOuterLoops(outerLoops);
-        stats.setInnerLoops(innerLoops);
-        for (int i = 0; i < outerLoops; i++) {
-            start();
-            for (int j = 0; j < innerLoops; j++) {
-                runnable.run();
-            }
-            stop();
-            sleep();
-        }
-        return this;
-    }
-
-    /**
-     * Time how long it takes to execute runnable.run(). Runs runnable votes
-     * times and returns the Stats of the fastest run. The actual number times
-     * that runnable.run() is executes is enough times so that it runs at least
-     * minThreadholeInMicros but not greater than maxThreadholdInMicro. This
-     * minimizes the chance that long context switches influence the result.
-     *
-     * @param votes is the number of runnable will be executed to determine
-     *            fastest run
-     * @param outerLoops is the number of of times the inner loop is run
-     * @param initialInnerLoops is the initial inner loop
-     * @param maxStdDevRetrys if the maxStdDevRatio is exceeded this number of
-     *            time the PerfTimerException is thrown.
-     * @param maxStdDevRatio the ratio of the standard deviation of the run and
-     *            the time to run.
-     * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL
-     * @param runnable is the code to test.
-     * @return Stats of the fastest run.
-     */
-    public Stats timeEachAutomatically(int votes, int outerLoops, int initialInnerLoops,
-            double minThresholdInMicros, double maxThresholdInMicros, int maxStdDevRetrys,
-            double maxStdDevRatio, int debugLevel, Runnable runnable) throws PerfTimerException {
-        Stats minStats = null;
-
-        for (int v = 0; v < votes; v++) {
-            boolean successful = false;
-            Stats stats = new Stats();
-            int innerLoops = initialInnerLoops;
-
-            /* Warm up cache */
-            timeEach(stats, outerLoops, initialInnerLoops, runnable);
-
-            for (int stdDevRetrys = 0; stdDevRetrys < maxStdDevRetrys; stdDevRetrys++) {
-                /**
-                 * First time may be long enough
-                 */
-                timeEach(stats, outerLoops, innerLoops, runnable);
-                analyze(stats, mTimes, outerLoops, debugLevel);
-                double innerLoopTime = stats.getMinInMicros();
-                if ((innerLoopTime >= minThresholdInMicros
-                        - ((maxThresholdInMicros - minThresholdInMicros) / 2))) {
-                    if (stats.stdDevOk(maxStdDevRatio)) {
-                        successful = true;
-                        break;
-                    } else {
-                        stats.incStdDevTooLargeCount();
-                        if (debugLevel >= DEBUG_LEVEL_SOME) {
-                            log(String.format(
-                                    "tea: tlc=%d StdDevRatio=%.2f > maxStdDevRatio=%.2f",
-                                    stats.getStdDevTooLargeCount(), stats.getStdDevRatio(),
-                                    maxStdDevRatio));
-                        }
-                    }
-                } else {
-                    /**
-                     * The initial number of loops is too short find the number
-                     * of loops that exceeds maxThresholdInMicros. Then use a
-                     * binary search to find the approriate innerLoop value that
-                     * is between min/maxThreshold.
-                     */
-                    innerLoops *= 10;
-                    int maxInnerLoops = innerLoops;
-                    int minInnerLoops = 1;
-                    boolean binarySearch = false;
-                    for (int i = 0; i < 10; i++) {
-                        timeEach(stats, outerLoops, innerLoops, runnable);
-                        analyze(stats, mTimes, outerLoops, debugLevel);
-                        innerLoopTime = stats.getMedianInMicros();
-                        if ((innerLoopTime >= minThresholdInMicros)
-                                && (innerLoopTime <= maxThresholdInMicros)) {
-                            if (stats.stdDevOk(maxStdDevRatio)) {
-                                successful = true;
-                                break;
-                            } else {
-                                stats.incStdDevTooLargeCount();
-                                if (debugLevel >= DEBUG_LEVEL_SOME) {
-                                    log(String.format(
-                                         "tea: tlc=%d StdDevRatio=%.2f > maxStdDevRatio=%.2f",
-                                         stats.getStdDevTooLargeCount(), stats.getStdDevRatio(),
-                                         maxStdDevRatio));
-                                }
-                            }
-                        } else if (binarySearch) {
-                            if ((innerLoopTime < minThresholdInMicros)) {
-                                minInnerLoops = innerLoops;
-                            } else {
-                                maxInnerLoops = innerLoops;
-                            }
-                            innerLoops = (maxInnerLoops + minInnerLoops) / 2;
-                        } else if (innerLoopTime >= maxThresholdInMicros) {
-                            /* Found a too large value, change to binary search */
-                            binarySearch = true;
-                            maxInnerLoops = innerLoops;
-                            innerLoops = (maxInnerLoops + minInnerLoops) / 2;
-                        } else {
-                            innerLoops *= 10;
-                        }
-                    }
-                    if (successful) {
-                        break;
-                    }
-                }
-            }
-            if (!successful) {
-                /* Couldn't find the number of loops to execute */
-                throw new PerfTimerException();
-            }
-
-            /** Looking for minimum */
-            if ((minStats == null) || (minStats.getTimePerLoop() > stats.getTimePerLoop())) {
-                minStats = stats;
-            }
-            if (debugLevel >= DEBUG_LEVEL_SOME) {
-                log(String.format("minStats.getTimePerLoop=%f minStats: %s", minStats.getTimePerLoop(), minStats));
-            }
-        }
-
-        return minStats;
-    }
-
-    /**
-     * Time how long it takes to execute runnable.run() with a threshold of 1 to
-     * 10ms.
-     *
-     * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL
-     * @param runnable
-     * @throws PerfTimerException
-     */
-    public Stats timeEachAutomatically(int debugLevel, Runnable runnable)
-            throws PerfTimerException {
-        mStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, 1, mCr.mMinThresholdInMicros,
-                mCr.mMaxThresholdInMicros, mCr.mStdDevRetrys, mCr.mMaxStdDevRatio, debugLevel,
-                runnable);
-        return mStats;
-    }
-
-    /**
-     * Time how long it takes to execute runnable.run() with a threshold of 1 to
-     * 10ms.
-     *
-     * @param runnable
-     * @throws PerfTimerException
-     */
-    public Stats timeEachAutomatically(Runnable runnable) throws PerfTimerException {
-        mStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, 1, mCr.mMinThresholdInMicros,
-                mCr.mMaxThresholdInMicros, mCr.mStdDevRetrys, mCr.mMaxStdDevRatio,
-                DEBUG_LEVEL_NONE, runnable);
-        return mStats;
-    }
-
-    /** Resize the times array */
-    public void resize(int maxCount) {
-        if (maxCount > mTimes.length) {
-            mTimes = new long[maxCount];
-        }
-    }
-
-    /**
-     * Analyze the data calculating the min, max, total, median, mean and
-     * stdDev. The standard deviation is calculated as sqrt(((sum of the squares
-     * of each time) / count) - mean^2)
-     * {@link "http://www.sciencebuddies.org/mentoring/project_data_analysis_variance_std_deviation.shtml"}
-     *
-     * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL
-     * @return StopWatch
-     */
-    public Stats analyze(Stats stats, long data[], int count, int debugLevel) {
-        if (count > 0) {
-            if (debugLevel >= DEBUG_LEVEL_ALL) {
-                for (int j = 0; j < count; j++) {
-                    log(String.format("data[%d]=%,dns", j, data[j]));
-                }
-            }
-            stats.calculate(data, count);
-        } else {
-            stats.init();
-        }
-        if (debugLevel >= DEBUG_LEVEL_SOME) {
-            log("stats: " + stats);
-        }
-        return stats;
-    }
-
-    /**
-     * Calibrate the system and set it for this PerfTimer instance
-     *
-     * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL
-     * @param precisionInDecimalDigits the precision in number of decimal digits
-     */
-    public CalibrationRec calibrate(int debugLevel, double precisionInDecimalDigits)
-            throws PerfTimerException {
-        int nonZeroCount = 0;
-        Stats stats = new Stats();
-        CalibrationRec cr = new CalibrationRec();
-
-        /* initialize the precision */
-        cr.mPrecisionInDecimalDigits = precisionInDecimalDigits;
-
-        /* Warm up the cache */
-        timeEach(stats, OUTER_LOOPS, 10, mEmptyRunnable);
-
-        /*
-         * Determine the clock stats with at least 20% non-zero unique values.
-         */
-        for (int clockStatsTries = 1; clockStatsTries < 100; clockStatsTries++) {
-            int j;
-            int i;
-            long cur;
-            long prev;
-            long min;
-
-            int innerLoops = clockStatsTries * 10;
-            timeEach(stats, OUTER_LOOPS, innerLoops, mEmptyRunnable);
-            long nonZeroValues[] = new long[mCount];
-            prev = 0;
-            for (nonZeroCount = 0, i = 0; i < mCount; i++) {
-                cur = mTimes[i];
-                if (cur > 0) {
-                    nonZeroValues[nonZeroCount++] = cur;
-                }
-            }
-            if (nonZeroCount > (mCount * 0.20)) {
-                // Calculate thresholds
-                analyze(stats, nonZeroValues, nonZeroCount, debugLevel);
-                stats.calculate(nonZeroValues, nonZeroCount);
-                cr.mMinThresholdInMicros = stats.getMeanInMicros()
-                        * Math.pow(10, cr.mPrecisionInDecimalDigits);
-                cr.mMaxThresholdInMicros = cr.mMinThresholdInMicros * 2;
-
-                // Set overhead to 0 and time the empty loop then set overhead.
-                cr.mRunnableOverheadInMicros = 0;
-                mClockStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, innerLoops,
-                        cr.mMinThresholdInMicros, cr.mMaxThresholdInMicros, mCr.mStdDevRetrys,
-                        mCr.mMaxStdDevRatio, debugLevel, mEmptyRunnable);
-                cr.mRunnableOverheadInMicros = mClockStats.getMinInMicros()
-                        / mClockStats.getInnerLoops();
-                break;
-            }
-            nonZeroCount = 0;
-        }
-        if (nonZeroCount == 0) {
-            throw new PerfTimerException();
-        }
-        if (debugLevel >= DEBUG_LEVEL_SOME) {
-            log(String.format("calibrate X oh=%.6fus minT=%,.6fus maxT=%,.6fus stats: %s",
-                    cr.mRunnableOverheadInMicros, cr.mMinThresholdInMicros,
-                    cr.mMaxThresholdInMicros, stats));
-        }
-        mCr = cr;
-        return mCr;
-    }
-
-    /** Calibrate the system and set it for this PerfTimer instance */
-    public CalibrationRec calibrate(double precisionInDecimalDigits) throws PerfTimerException {
-        return calibrate(DEBUG_LEVEL_NONE, precisionInDecimalDigits);
-    }
-
-    /** Calibrate the system and set it for this PerfTimer instance */
-    public CalibrationRec calibrate() throws PerfTimerException {
-        return calibrate(DEBUG_LEVEL_NONE, mCr.mPrecisionInDecimalDigits);
-    }
-
-    /*
-     * Accessors for the private data
-     */
-
-    /** Set calibration record */
-    public void setCalibrationRec(CalibrationRec cr) {
-        mCr = cr;
-    }
-
-    /** Get calibration record */
-    public CalibrationRec getCalibrationRec() {
-        return mCr;
-    }
-
-    /** Number of samples in times array. */
-    public int getCount() {
-        return mCount;
-    }
-
-    /** Minimum value of collected data in microseconds, valid after analyze. */
-    public double getMinInMicros() {
-        return mStats.getMinInMicros();
-    }
-
-    /** Maximum value of collected data in microseconds, valid after analyze. */
-    public double getMaxInMicros() {
-        return mStats.getMaxInMicros();
-    }
-
-    /**
-     * Sum of the values of collected data in microseconds, valid after analyze.
-     */
-    public double getTotalInMicros() {
-        return mStats.getTotalInMicros();
-    }
-
-    /** Sum of the values of collected data in seconds, valid after analyze. */
-    public double getTotalInSecs() {
-        return mStats.getTotalInSecs();
-    }
-
-    /** Sum of the values of collected data in seconds, valid after analyze. */
-    public double getMeanInMicros() {
-        return mStats.getMeanInMicros();
-    }
-
-    /** Median value of collected data in microseconds, valid after analyze. */
-    public double getMedianInMicros() {
-        return mStats.getMedianInMicros();
-    }
-
-    /**
-     * Standard deviation of collected data in microseconds, valid after
-     * analyze.
-     */
-    public double getStdDevInMicros() {
-        return mStats.getStdDevInMicros();
-    }
-
-    /** The mTimes[index] value */
-    public long getTime(int index) {
-        return mTimes[index];
-    }
-
-    /** The mTimes */
-    public long[] getTimes() {
-        return mTimes;
-    }
-
-    /** @return the clock stats as measured in calibrate */
-    public Stats getClockStats() {
-        return mClockStats;
-    }
-
-    /** @return the stats */
-    public Stats getStats() {
-        return mStats;
-    }
-
-    /**
-     * Convert stats to string
-     *
-     * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL
-     */
-    public String stats(int debugLevel) {
-        int innerLoops = mStats.getInnerLoops();
-        if (mCount == 0) {
-            return String.format("%,.3fus", (getTicks() - mStart) / TICKS_PER_MICROSECOND);
-        } else {
-            if (mCount == 1) {
-                return String.format("%,.3fus", getTime());
-            } else {
-                analyze(mStats, mTimes, mCount, debugLevel);
-                return mStats.toString();
-            }
-        }
-    }
-
-    /**
-     * Convert string
-     */
-    public String stats() {
-        return stats(0);
-    }
-
-    /**
-     * Get time
-     */
-    public double getTime() {
-        int innerLoops = mStats.getInnerLoops();
-        if (mCount == 0) {
-            return (getTicks() - mStart) / TICKS_PER_MICROSECOND;
-        } else {
-            if (mCount == 1) {
-                return mStats.getTotalInMicros();
-            } else {
-                analyze(mStats, mTimes, mCount, DEBUG_LEVEL_NONE);
-                return (mStats.getMinInMicros() / innerLoops) - mCr.mRunnableOverheadInMicros;
-            }
-        }
-    }
-
-    /** Convert to string */
-    @Override
-    public String toString() {
-        return String.format("%,.3fus", getTime());
-    }
-}
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
index d6daa44..70f5ac8 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
+++ b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
@@ -175,7 +175,7 @@
   return false;
 }
 
-bool IsStringUtf8Handling(const FieldDescriptor* descriptor,
+bool IsFastStringHandling(const FieldDescriptor* descriptor,
       const Params params) {
   return ((params.optimization() == JAVAMICRO_OPT_SPEED)
       && (GetJavaType(descriptor) == JAVATYPE_STRING));
@@ -188,20 +188,8 @@
   (*variables)["capitalized_name"] =
     UnderscoresToCapitalizedCamelCase(descriptor);
   (*variables)["number"] = SimpleItoa(descriptor->number());
-  if (IsStringUtf8Handling(descriptor, params)) {
-    (*variables)["type"] = "com.google.protobuf.micro.StringUtf8Micro";
-    string defaultValue = DefaultValue(params, descriptor);
-    if (defaultValue == "\"\"") {
-      (*variables)["default"] =
-          "com.google.protobuf.micro.StringUtf8Micro.EMPTY";
-    } else {
-      (*variables)["default"] = "new com.google.protobuf.micro.StringUtf8Micro("
-              + defaultValue + ")";
-    }
-  } else {
-    (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
-    (*variables)["default"] = DefaultValue(params, descriptor);
-  }
+  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["default"] = DefaultValue(params, descriptor);
   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
   (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
@@ -238,28 +226,24 @@
   printer->Print(variables_,
     "private boolean has$capitalized_name$;\n"
     "private $type$ $name$_ = $default$;\n"
+    "public $type$ get$capitalized_name$() { return $name$_; }\n"
     "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n");
-  if (IsStringUtf8Handling(descriptor_, params_)) {
+  if (IsFastStringHandling(descriptor_, params_)) {
     printer->Print(variables_,
-      "public String get$capitalized_name$() { return $name$_.getString(); }\n"
-      "public $type$ get$capitalized_name$StringUtf8() { return $name$_; }\n"
-      "public $message_name$ set$capitalized_name$(String value) {\n"
+      "private byte [] $name$Utf8_ = null;\n"
+      "public $message_name$ set$capitalized_name$($type$ value) {\n"
       "  has$capitalized_name$ = true;\n"
-      "  if ($name$_ == $default$) {\n"
-      "    $name$_ = new $type$(value);\n"
-      "  } else {\n"
-      "    $name$_.setString(value);\n"
-      "  }\n"
+      "  $name$_ = value;\n"
+      "  $name$Utf8_ = null;\n"
       "  return this;\n"
       "}\n"
       "public $message_name$ clear$capitalized_name$() {\n"
       "  has$capitalized_name$ = false;\n"
       "  $name$_ = $default$;\n"
+      "  $name$Utf8_ = null;\n"
       "  return this;\n"
       "}\n");
   } else {
-    printer->Print(variables_,
-      "public $type$ get$capitalized_name$() { return $name$_; }\n");
     if (IsVariableLenType(GetJavaType(descriptor_))) {
       printer->Print(variables_,
         "public $message_name$ set$capitalized_name$($type$ value) {\n"
@@ -304,10 +288,10 @@
 
 void PrimitiveFieldGenerator::
 GenerateSerializationCode(io::Printer* printer) const {
-  if (IsStringUtf8Handling(descriptor_, params_)) {
+  if (IsFastStringHandling(descriptor_, params_)) {
     printer->Print(variables_,
       "if (has$capitalized_name$()) {\n"
-      "  output.writeStringUtf8($number$, get$capitalized_name$StringUtf8());\n"
+      "  output.writeByteArray($number$, $name$Utf8_);\n"
       "}\n");
   } else {
     printer->Print(variables_,
@@ -319,11 +303,16 @@
 
 void PrimitiveFieldGenerator::
 GenerateSerializedSizeCode(io::Printer* printer) const {
-  if (IsStringUtf8Handling(descriptor_, params_)) {
+  if (IsFastStringHandling(descriptor_, params_)) {
     printer->Print(variables_,
       "if (has$capitalized_name$()) {\n"
+      "  try {\n"
+      "    $name$Utf8_ = $name$_.getBytes(\"UTF-8\");\n"
+      "  } catch (java.io.UnsupportedEncodingException e) {\n"
+      "    throw new RuntimeException(\"UTF-8 not supported.\");\n"
+      "  }\n"
       "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
-      "    .computeStringUtf8Size($number$, get$capitalized_name$StringUtf8());\n"
+      "    .computeByteArraySize($number$, $name$Utf8_);\n"
       "}\n");
   } else {
     printer->Print(variables_,
@@ -353,32 +342,33 @@
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateMembers(io::Printer* printer) const {
-  if (IsStringUtf8Handling(descriptor_, params_)) {
+  if (IsFastStringHandling(descriptor_, params_)) {
     if (params_.java_use_vector()) {
       printer->Print(variables_,
         "private java.util.Vector $name$_ = new java.util.Vector();\n"
         "public java.util.Vector get$capitalized_name$List() {\n"
         "  return $name$_;\n"
         "}\n"
+        "private java.util.Vector $name$Utf8_ = new java.util.Vector();\n"
         "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
-        "public String get$capitalized_name$(int index) {\n"
-        "  return (($type$)$name$_.elementAt(index)).getString();\n"
+        "public $type$ get$capitalized_name$(int index) {\n"
+        "  return (($type$)$name$_.elementAt(index));\n"
         "}\n"
-        "public $type$ get$capitalized_name$StringUtf8(int index) {\n"
-        "  return ($type$)$name$_.elementAt(index);\n"
-        "}\n"
-        "public $message_name$ set$capitalized_name$(int index, String value) {\n"
+        "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
         "$null_check$"
-        "  $name$_.setElementAt(new $type$(value), index);\n"
+        "  $name$_.setElementAt(value, index);\n"
+        "  $name$Utf8_ = null;\n"
         "  return this;\n"
         "}\n"
-        "public $message_name$ add$capitalized_name$(String value) {\n"
+        "public $message_name$ add$capitalized_name$($type$ value) {\n"
         "$null_check$"
-        "  $name$_.addElement(new $type$(value));\n"
+        "  $name$_.addElement(value);\n"
+        "  $name$Utf8_ = null;\n"
         "  return this;\n"
         "}\n"
         "public $message_name$ clear$capitalized_name$() {\n"
         "  $name$_.removeAllElements();\n"
+        "  $name$Utf8_ = null;\n"
         "  return this;\n"
         "}\n");
     } else {
@@ -388,25 +378,29 @@
         "public java.util.List<$type$> get$capitalized_name$List() {\n"
         "  return $name$_;\n"   // note:  unmodifiable list
         "}\n"
+        "private java.util.List<byte []> $name$Utf8_ = null;\n"
         "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
-        "public String get$capitalized_name$(int index) {\n"
-        "  return $name$_.get(index).getString();\n"
+        "public $type$ get$capitalized_name$(int index) {\n"
+        "  return $name$_.get(index);\n"
         "}\n"
-        "public $message_name$ set$capitalized_name$(int index, String value) {\n"
+        "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
         "$null_check$"
-        "  $name$_.set(index, new $type$(value));\n"
+        "  $name$_.set(index, value);\n"
+        "  $name$Utf8_ = null;\n"
         "  return this;\n"
         "}\n"
-        "public $message_name$ add$capitalized_name$(String value) {\n"
+        "public $message_name$ add$capitalized_name$($type$ value) {\n"
         "$null_check$"
         "  if ($name$_.isEmpty()) {\n"
         "    $name$_ = new java.util.ArrayList<$type$>();\n"
         "  }\n"
-        "  $name$_.add(new $type$(value));\n"
+        "  $name$_.add(value);\n"
+        "  $name$Utf8_ = null;\n"
         "  return this;\n"
         "}\n"
         "public $message_name$ clear$capitalized_name$() {\n"
         "  $name$_ = java.util.Collections.emptyList();\n"
+        "  $name$Utf8_ = null;\n"
         "  return this;\n"
         "}\n");
     }
@@ -535,7 +529,7 @@
 GenerateSerializationCode(io::Printer* printer) const {
   if (descriptor_->options().packed()) {
     printer->Print(variables_,
-        "if (get$capitalized_name$List().size() > 0) {\n"
+      "if (get$capitalized_name$List().size() > 0) {\n"
         "  output.writeRawVarint32($tag$);\n"
         "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
         "}\n");
@@ -552,10 +546,10 @@
     }
   } else {
     if (params_.java_use_vector()) {
-      if (IsStringUtf8Handling(descriptor_, params_)) {
+      if (IsFastStringHandling(descriptor_, params_)) {
         printer->Print(variables_,
-          "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
-          "  output.writeStringUtf8($number$, get$capitalized_name$StringUtf8(i));\n"
+          "for (int i = 0; i < $name$Utf8_.size(); i++) {\n"
+          "  output.writeByteArray($number$, (byte []) $name$Utf8_.get(i));\n"
           "}\n");
       } else {
         printer->Print(variables_,
@@ -564,10 +558,10 @@
           "}\n");
       }
     } else {
-      if (IsStringUtf8Handling(descriptor_, params_)) {
+      if (IsFastStringHandling(descriptor_, params_)) {
         printer->Print(variables_,
-          "for ($type$ element : get$capitalized_name$List()) {\n"
-          "  output.writeStringUtf8($number$, element);\n"
+          "for (byte [] element : $name$Utf8_) {\n"
+          "  output.writeByteArray($number$, element);\n"
           "}\n");
       } else {
         printer->Print(variables_,
@@ -588,29 +582,51 @@
 
   if (FixedSize(descriptor_->type()) == -1) {
     if (params_.java_use_vector()) {
-      printer->Print(variables_,
-        "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
-        "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n");
-      if (IsStringUtf8Handling(descriptor_, params_)) {
+      if (IsFastStringHandling(descriptor_, params_)) {
         printer->Print(variables_,
-          "    .computeStringUtf8SizeNoTag(get$capitalized_name$StringUtf8(i));\n"
+          "$name$Utf8_ = new java.util.Vector();\n"
+          "byte[] bytes = null;\n"
+          "int sizeArray = get$capitalized_name$List().size();\n"
+          "for (int i = 0; i < sizeArray; i++) {\n"
+          "  $type$ element = ($type$)$name$_.elementAt(i);\n"
+          "  try {\n"
+          "    bytes = element.getBytes(\"UTF-8\");\n"
+          "  } catch (java.io.UnsupportedEncodingException e) {\n"
+          "    throw new RuntimeException(\"UTF-8 not supported.\");\n"
+          "  }\n"
+          "  $name$Utf8_.addElement(bytes);\n"
+          "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+          "    .computeByteArraySizeNoTag(bytes);\n"
           "}\n");
       } else {
         printer->Print(variables_,
+          "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+          "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
           "    .compute$capitalized_type$SizeNoTag(($type$)get$capitalized_name$(i));\n"
           "}\n");
       }
     } else {
-      printer->Print(variables_,
-        "for ($type$ element : get$capitalized_name$List()) {\n"
-        "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n");
-      if (IsStringUtf8Handling(descriptor_, params_)) {
-        printer->Print(variables_,
-          "    .computeStringUtf8SizeNoTag(element);\n"
-          "}\n");
+      if (IsFastStringHandling(descriptor_, params_)) {
+          printer->Print(variables_,
+            "$name$Utf8_ = new java.util.ArrayList<byte[]>();\n"
+            "byte[] bytes = null;\n"
+            "int sizeArray = get$capitalized_name$List().size();\n"
+            "for (int i = 0; i < sizeArray; i++) {\n"
+            "   $type$ element = get$capitalized_name$(i);\n"
+            "  try {\n"
+            "    bytes = element.getBytes(\"UTF-8\");\n"
+            "  } catch (java.io.UnsupportedEncodingException e) {\n"
+            "    throw new RuntimeException(\"UTF-8 not supported.\");\n"
+            "  }\n"
+            "  $name$Utf8_.add(bytes);\n"
+            "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+            "    .computeByteArraySizeNoTag(bytes);\n"
+            "}\n");
       } else {
         printer->Print(variables_,
-          "    .compute$capitalized_type$SizeNoTag(element);\n"
+            "for ($type$ element : get$capitalized_name$List()) {\n"
+            "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+            "    .compute$capitalized_type$SizeNoTag(element);\n"
           "}\n");
       }
     }
