/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text.cts;

import static android.view.View.LAYOUT_DIRECTION_LTR;
import static android.view.View.LAYOUT_DIRECTION_RTL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.GetChars;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.SpannedString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.text.style.BackgroundColorSpan;
import android.text.style.ReplacementSpan;
import android.text.style.TextAppearanceSpan;
import android.text.style.URLSpan;
import android.util.StringBuilderPrinter;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * Test {@link TextUtils}.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextUtilsTest  {
    private Context mContext;
    private String mEllipsis;
    private int mStart;
    private int mEnd;

    @Before
    public void setup() {
        mContext = InstrumentationRegistry.getTargetContext();
        mEllipsis = getEllipsis();
        resetRange();
    }

    private void resetRange() {
        mStart = -1;
        mEnd = -1;
    }

    /**
     * Get the ellipsis from system.
     * @return the string of ellipsis.
     */
    private static String getEllipsis() {
        String text = "xxxxx";
        TextPaint p = new TextPaint();
        float width = p.measureText(text.substring(1));
        String re = TextUtils.ellipsize(text, p, width, TruncateAt.START).toString();
        return re.substring(0, re.indexOf("x"));
    }

    /**
     * @return the number of times the code unit appears in the CharSequence.
     */
    private static int countChars(CharSequence s, char c) {
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == c) {
                count++;
            }
        }
        return count;
    }

    @Test
    public void testListEllipsize() {
        final TextPaint paint = new TextPaint();
        final int moreId = R.plurals.list_ellipsize_test;  // "one more" for 1, "%d more" for other

        final List fullList = Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H", "I", "J");
        final String separator = ", ";
        final String fullString = TextUtils.join(separator, fullList);
        final float fullWidth = paint.measureText(fullString);
        assertEquals("",
            TextUtils.listEllipsize(mContext, null, separator, paint, fullWidth, moreId));

        final List<CharSequence> emptyList = new ArrayList<>();
        assertEquals("",
            TextUtils.listEllipsize(mContext, emptyList, separator, paint, fullWidth, moreId));

        // Null context should cause ellipsis to be used at the end.
        final String ellipsizedWithNull = TextUtils.listEllipsize(
                null, fullList, separator, paint, fullWidth / 2, 0).toString();
        assertTrue(ellipsizedWithNull.endsWith(getEllipsis()));

        // Test that the empty string gets returned if there's no space.
        assertEquals("",
                TextUtils.listEllipsize(mContext, fullList, separator, paint, 1.0f, moreId));

        // Test that the full string itself can get returned if there's enough space.
        assertEquals(fullString,
                TextUtils.listEllipsize(mContext, fullList, separator, paint, fullWidth, moreId)
                        .toString());
        assertEquals(fullString,
                TextUtils.listEllipsize(mContext, fullList, separator, paint, fullWidth * 2,
                        moreId).toString());

        final float epsilon = fullWidth / 20;
        for (float width = epsilon; width < fullWidth - epsilon / 2; width += epsilon) {
            final String ellipsized = TextUtils.listEllipsize(
                    mContext, fullList, separator, paint, width, moreId).toString();
            // Since we don't have the full space, test that we are not getting the full string.
            assertFalse(fullString.equals(ellipsized));

            if (!ellipsized.isEmpty()) {
                assertTrue(ellipsized.endsWith(" more"));
                // Test that the number of separators (which equals the number of output elements),
                // plus the number output before more always equals the number of original elements.
                final int lastSpace = ellipsized.lastIndexOf(' ');
                final int penultimateSpace = ellipsized.lastIndexOf(' ', lastSpace - 1);
                assertEquals(',', ellipsized.charAt(penultimateSpace - 1));
                final String moreCountString = ellipsized.substring(
                        penultimateSpace + 1, lastSpace);
                final int moreCount = (moreCountString.equals("one"))
                        ? 1 : Integer.parseInt(moreCountString);
                final int commaCount = countChars(ellipsized, ',');
                assertEquals(fullList.size(), commaCount + moreCount);
            }
        }
}

    @Test
    public void testListEllipsize_rtl() {
        final Resources res = mContext.getResources();
        final Configuration newConfig = new Configuration(res.getConfiguration());

        // save the locales and set them to just Arabic
        final LocaleList previousLocales = newConfig.getLocales();
        newConfig.setLocales(LocaleList.forLanguageTags("ar"));
        res.updateConfiguration(newConfig, null);

        try {
            final TextPaint paint = new TextPaint();
            final int moreId = R.plurals.list_ellipsize_test;  // "one more" for 1, else "%d more"
            final String RLM = "\u200F";
            final String LRE = "\u202A";
            final String PDF = "\u202C";

            final List fullList = Arrays.asList("A", "B");
            final String separator = ", ";
            final String expectedString =
                    RLM + LRE + "A" + PDF + RLM + ", " + RLM + LRE + "B" + PDF + RLM;
            final float enoughWidth = paint.measureText(expectedString);

            assertEquals(expectedString,
                    TextUtils.listEllipsize(mContext, fullList, separator, paint, enoughWidth,
                                            moreId).toString());
        } finally {
            // Restore the original locales
            newConfig.setLocales(previousLocales);
            res.updateConfiguration(newConfig, null);
        }
    }

    @Test
    public void testCommaEllipsize() {
        TextPaint p = new TextPaint();
        String text = "long, string, to, truncate";

        float textWidth = p.measureText("long, 3 plus");
        // avail is shorter than text width for only one item plus the appropriate ellipsis.
        // issue 1688347, the expected result for this case does not be described
        // in the javadoc of commaEllipsize().
        assertEquals("",
                TextUtils.commaEllipsize(text, p, textWidth - 1.4f, "plus 1", "%d plus").toString());
        // avail is long enough for only one item plus the appropriate ellipsis.
        assertEquals("long, 3 plus",
                TextUtils.commaEllipsize(text, p, textWidth, "plus 1", "%d plus").toString());

        // avail is long enough for two item plus the appropriate ellipsis.
        textWidth = p.measureText("long, string, 2 more");
        assertEquals("long, string, 2 more",
                TextUtils.commaEllipsize(text, p, textWidth, "more 1", "%d more").toString());

        // avail is long enough for the whole sentence.
        textWidth = p.measureText("long, string, to, truncate");
        assertEquals("long, string, to, truncate",
                TextUtils.commaEllipsize(text, p, textWidth, "more 1", "%d more").toString());

        // the sentence is extended, avail is NOT long enough for the whole sentence.
        assertEquals("long, string, to, more 1", TextUtils.commaEllipsize(
                text + "-extended", p, textWidth, "more 1", "%d more").toString());

        // exceptional value
        assertEquals("", TextUtils.commaEllipsize(text, p, -1f, "plus 1", "%d plus").toString());

        assertEquals(text, TextUtils.commaEllipsize(
                text, p, Float.MAX_VALUE, "more 1", "%d more").toString());

        assertEquals("long, string, to, null", TextUtils.commaEllipsize(
                text + "-extended", p, textWidth, null, "%d more").toString());

        try {
            TextUtils.commaEllipsize(null, p, textWidth, "plus 1", "%d plus");
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
            // issue 1688347, not clear what is supposed to happen if the text to truncate is null.
        }

        try {
            TextUtils.commaEllipsize(text, null, textWidth, "plus 1", "%d plus");
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
            // issue 1688347, not clear what is supposed to happen if TextPaint is null.
        }
    }

    @Test
    public void testConcat() {
        assertEquals("", TextUtils.concat().toString());

        assertEquals("first", TextUtils.concat("first").toString());

        assertEquals("first, second", TextUtils.concat("first", ", ", "second").toString());

        SpannableString string1 = new SpannableString("first");
        SpannableString string2 = new SpannableString("second");
        final String url = "www.test_url.com";
        URLSpan urlSpan = new URLSpan(url);
        string1.setSpan(urlSpan, 0, string1.length() - 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.GREEN);
        string2.setSpan(bgColorSpan, 0, string2.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        final String comma = ", ";
        Spanned strResult = (Spanned) TextUtils.concat(string1, comma, string2);
        assertEquals(string1.toString() + comma + string2.toString(), strResult.toString());
        Object spans[] = strResult.getSpans(0, strResult.length(), Object.class);
        assertEquals(2, spans.length);
        assertTrue(spans[0] instanceof URLSpan);
        assertEquals(url, ((URLSpan) spans[0]).getURL());
        assertTrue(spans[1] instanceof BackgroundColorSpan);
        assertEquals(Color.GREEN, ((BackgroundColorSpan) spans[1]).getBackgroundColor());
        assertEquals(0, strResult.getSpanStart(urlSpan));
        assertEquals(string1.length() - 1, strResult.getSpanEnd(urlSpan));
        assertEquals(string1.length() + comma.length(), strResult.getSpanStart(bgColorSpan));
        assertEquals(strResult.length() - 1, strResult.getSpanEnd(bgColorSpan));

        assertEquals(string1, TextUtils.concat(string1));

        assertEquals(null, TextUtils.concat((CharSequence) null));
    }

    @Test(expected = NullPointerException.class)
    public void testConcat_NullArray() {
        TextUtils.concat((CharSequence[]) null);
    }

    @Test
    public void testConcat_NullParameters() {
        assertEquals("nullA", TextUtils.concat(null, "A"));
        assertEquals("Anull", TextUtils.concat("A", null));
        assertEquals("AnullB", TextUtils.concat("A", null, "B"));

        final SpannableString piece = new SpannableString("A");
        final Object span = new Object();
        piece.setSpan(span, 0, piece.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        final Spanned result = (Spanned) TextUtils.concat(piece, null);
        assertEquals("Anull", result.toString());
        final Object[] spans = result.getSpans(0, result.length(), Object.class);
        assertEquals(1, spans.length);
        assertSame(span, spans[0]);
        assertEquals(0, result.getSpanStart(spans[0]));
        assertEquals(piece.length(), result.getSpanEnd(spans[0]));
    }

    @Test
    public void testConcat_twoParagraphSpans() {
        // Two paragraph spans. The first will get extended to cover the whole string and the second
        // will be dropped.
        final SpannableString string1 = new SpannableString("a");
        final SpannableString string2 = new SpannableString("b");
        final Object span1 = new Object();
        final Object span2 = new Object();
        string1.setSpan(span1, 0, string1.length(), Spanned.SPAN_PARAGRAPH);
        string2.setSpan(span2, 0, string2.length(), Spanned.SPAN_PARAGRAPH);

        final Spanned result = (Spanned) TextUtils.concat(string1, string2);
        assertEquals("ab", result.toString());
        final Object[] spans = result.getSpans(0, result.length(), Object.class);
        assertEquals(1, spans.length);
        assertSame(span1, spans[0]);
        assertEquals(0, result.getSpanStart(spans[0]));
        assertEquals(result.length(), result.getSpanEnd(spans[0]));
    }

    @Test
    public void testConcat_oneParagraphSpanAndOneInclusiveSpan() {
        // One paragraph span and one double-inclusive span. The first will get extended to cover
        // the whole string and the second will be kept.
        final SpannableString string1 = new SpannableString("a");
        final SpannableString string2 = new SpannableString("b");
        final Object span1 = new Object();
        final Object span2 = new Object();
        string1.setSpan(span1, 0, string1.length(), Spanned.SPAN_PARAGRAPH);
        string2.setSpan(span2, 0, string2.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);

        final Spanned result = (Spanned) TextUtils.concat(string1, string2);
        assertEquals("ab", result.toString());
        final Object[] spans = result.getSpans(0, result.length(), Object.class);
        assertEquals(2, spans.length);
        assertSame(span1, spans[0]);
        assertEquals(0, result.getSpanStart(spans[0]));
        assertEquals(result.length(), result.getSpanEnd(spans[0]));
        assertSame(span2, spans[1]);
        assertEquals(string1.length(), result.getSpanStart(spans[1]));
        assertEquals(result.length(), result.getSpanEnd(spans[1]));
    }

    @Test
    public void testCopySpansFrom() {
        Object[] spans;
        String text = "content";
        SpannableString source1 = new SpannableString(text);
        int midPos = source1.length() / 2;
        final String url = "www.test_url.com";
        URLSpan urlSpan = new URLSpan(url);
        source1.setSpan(urlSpan, 0, midPos, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.GREEN);
        source1.setSpan(bgColorSpan, midPos - 1,
                source1.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        // normal test
        SpannableString dest1 = new SpannableString(text);
        TextUtils.copySpansFrom(source1, 0, source1.length(), Object.class, dest1, 0);
        spans = dest1.getSpans(0, dest1.length(), Object.class);
        assertEquals(2, spans.length);
        assertTrue(spans[0] instanceof URLSpan);
        assertEquals(url, ((URLSpan) spans[0]).getURL());
        assertTrue(spans[1] instanceof BackgroundColorSpan);
        assertEquals(Color.GREEN, ((BackgroundColorSpan) spans[1]).getBackgroundColor());
        assertEquals(0, dest1.getSpanStart(urlSpan));
        assertEquals(midPos, dest1.getSpanEnd(urlSpan));
        assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, dest1.getSpanFlags(urlSpan));
        assertEquals(midPos - 1, dest1.getSpanStart(bgColorSpan));
        assertEquals(source1.length() - 1, dest1.getSpanEnd(bgColorSpan));
        assertEquals(Spanned.SPAN_EXCLUSIVE_EXCLUSIVE, dest1.getSpanFlags(bgColorSpan));

        SpannableString source2 = new SpannableString(text);
        source2.setSpan(urlSpan, 0, source2.length() - 1, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        SpannableString dest2 = new SpannableString(text);
        TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest2, 0);
        spans = dest2.getSpans(0, dest2.length(), Object.class);
        assertEquals(1, spans.length);
        assertTrue(spans[0] instanceof URLSpan);
        assertEquals(url, ((URLSpan) spans[0]).getURL());
        assertEquals(0, dest2.getSpanStart(urlSpan));
        assertEquals(source2.length() - 1, dest2.getSpanEnd(urlSpan));
        assertEquals(Spanned.SPAN_EXCLUSIVE_INCLUSIVE, dest2.getSpanFlags(urlSpan));

        SpannableString dest3 = new SpannableString(text);
        TextUtils.copySpansFrom(source2, 0, source2.length(), BackgroundColorSpan.class, dest3, 0);
        spans = dest3.getSpans(0, dest3.length(), Object.class);
        assertEquals(0, spans.length);
        TextUtils.copySpansFrom(source2, 0, source2.length(), URLSpan.class, dest3, 0);
        spans = dest3.getSpans(0, dest3.length(), Object.class);
        assertEquals(1, spans.length);

        SpannableString dest4 = new SpannableString("short");
        try {
            TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest4, 0);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }
        TextUtils.copySpansFrom(source2, 0, dest4.length(), Object.class, dest4, 0);
        spans = dest4.getSpans(0, dest4.length(), Object.class);
        assertEquals(1, spans.length);
        assertEquals(0, dest4.getSpanStart(spans[0]));
        // issue 1688347, not clear the expected result when 'start ~ end' only
        // covered a part of the span.
        assertEquals(dest4.length(), dest4.getSpanEnd(spans[0]));

        SpannableString dest5 = new SpannableString("longer content");
        TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest5, 0);
        spans = dest5.getSpans(0, 1, Object.class);
        assertEquals(1, spans.length);

        dest5 = new SpannableString("longer content");
        TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest5, 2);
        spans = dest5.getSpans(0, 1, Object.class);
        assertEquals(0, spans.length);
        spans = dest5.getSpans(2, dest5.length(), Object.class);
        assertEquals(1, spans.length);
        try {
            TextUtils.copySpansFrom(source2, 0, source2.length(),
                    Object.class, dest5, dest5.length() - source2.length() + 2);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        // issue 1688347, no javadoc about the expected behavior of the exceptional argument.
        // exceptional source start
        SpannableString dest6 = new SpannableString("exceptional test");
        TextUtils.copySpansFrom(source2, -1, source2.length(), Object.class, dest6, 0);
        spans = dest6.getSpans(0, dest6.length(), Object.class);
        assertEquals(1, spans.length);
        dest6 = new SpannableString("exceptional test");
        TextUtils.copySpansFrom(source2, Integer.MAX_VALUE, source2.length() - 1,
                    Object.class, dest6, 0);
        spans = dest6.getSpans(0, dest6.length(), Object.class);
        assertEquals(0, spans.length);

        // exceptional source end
        dest6 = new SpannableString("exceptional test");
        TextUtils.copySpansFrom(source2, 0, -1, Object.class, dest6, 0);
        spans = dest6.getSpans(0, dest6.length(), Object.class);
        assertEquals(0, spans.length);
        TextUtils.copySpansFrom(source2, 0, Integer.MAX_VALUE, Object.class, dest6, 0);
        spans = dest6.getSpans(0, dest6.length(), Object.class);
        assertEquals(1, spans.length);

        // exceptional class kind
        dest6 = new SpannableString("exceptional test");
        TextUtils.copySpansFrom(source2, 0, source2.length(), null, dest6, 0);
        spans = dest6.getSpans(0, dest6.length(), Object.class);
        assertEquals(1, spans.length);

        // exceptional destination offset
        dest6 = new SpannableString("exceptional test");
        try {
            TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest6, -1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        try {
            TextUtils.copySpansFrom(source2, 0, source2.length(),
                    Object.class, dest6, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }

        // exceptional source
        try {
            TextUtils.copySpansFrom(null, 0, source2.length(), Object.class, dest6, 0);
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
            // expect
        }

        // exceptional destination
        try {
            TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, null, 0);
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
            // expect
        }
    }

    @Test
    public void testEllipsize() {
        TextPaint p = new TextPaint();

        // turn off kerning. with kerning enabled, different methods of measuring the same text
        // produce different results.
        p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG);

        CharSequence text = "long string to truncate";

        float textWidth = p.measureText(mEllipsis) + p.measureText("uncate");
        assertEquals(mEllipsis + "uncate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.START).toString());

        textWidth = p.measureText("long str") + p.measureText(mEllipsis);
        assertEquals("long str" + mEllipsis,
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.END).toString());

        textWidth = p.measureText("long") + p.measureText(mEllipsis) + p.measureText("ate");
        assertEquals("long" + mEllipsis + "ate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE).toString());

        // issue 1688347, ellipsize() is not defined for TruncateAt.MARQUEE.
        // In the code it looks like this does the same as MIDDLE.
        // In other methods, MARQUEE is equivalent to END, except for the first line.
        assertEquals("long" + mEllipsis + "ate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.MARQUEE).toString());

        textWidth = p.measureText(mEllipsis);
        assertEquals("", TextUtils.ellipsize(text, p, textWidth, TruncateAt.END).toString());
        assertEquals("", TextUtils.ellipsize(text, p, textWidth - 1, TruncateAt.END).toString());
        assertEquals("", TextUtils.ellipsize(text, p, -1f, TruncateAt.END).toString());
        assertEquals(text,
                TextUtils.ellipsize(text, p, Float.MAX_VALUE, TruncateAt.END).toString());

        assertEquals("", TextUtils.ellipsize(text, p, textWidth, TruncateAt.START).toString());
        assertEquals("", TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE).toString());

        try {
            TextUtils.ellipsize(text, null, textWidth, TruncateAt.MIDDLE);
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }

        try {
            TextUtils.ellipsize(null, p, textWidth, TruncateAt.MIDDLE);
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }
    }

    @Test
    public void testEllipsize_emoji() {
        // 2 family emojis (11 code units + 11 code units).
        final String text = "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66"
                + "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66";

        final TextPaint p = new TextPaint();
        final float width = p.measureText(text);

        final TextUtils.TruncateAt[] kinds = {TextUtils.TruncateAt.START,
                TextUtils.TruncateAt.MIDDLE, TextUtils.TruncateAt.END};
        for (final TextUtils.TruncateAt kind : kinds) {
            for (int i = 0; i <= 8; i++) {
                float avail = width * i / 7.0f;
                final String out = TextUtils.ellipsize(text, p, avail, kind).toString();
                assertTrue("kind: " + kind + ", avail: " + avail + ", out length: " + out.length(),
                        out.length() == text.length()
                                || out.length() == text.length() / 2 + 1
                                || out.length() == 0);
            }
        }
    }

    @Test
    public void testEllipsizeCallback() {
        TextPaint p = new TextPaint();

        // turn off kerning. with kerning enabled, different methods of measuring the same text
        // produce different results.
        p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG);

        TextUtils.EllipsizeCallback callback = new TextUtils.EllipsizeCallback() {
            public void ellipsized(final int start, final int end) {
                mStart = start;
                mEnd = end;
            }
        };

        String text = "long string to truncate";

        // TruncateAt.START, does not specify preserveLength
        resetRange();
        float textWidth = p.measureText(mEllipsis + "uncate");
        assertEquals(mEllipsis + "uncate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.START, false,
                        callback).toString());
        assertEquals(0, mStart);
        assertEquals(text.length() - "uncate".length(), mEnd);

        // TruncateAt.START, specify preserveLength
        resetRange();
        int ellipsisNum = text.length() - "uncate".length();
        assertEquals(getBlankString(true, ellipsisNum) + "uncate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.START, true,
                        callback).toString());
        assertEquals(0, mStart);
        assertEquals(text.length() - "uncate".length(), mEnd);

        // TruncateAt.END, specify preserveLength
        resetRange();
        textWidth = p.measureText("long str") + p.measureText(mEllipsis);
        ellipsisNum = text.length() - "long str".length();
        assertEquals("long str" + getBlankString(true, ellipsisNum),
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.END, true, callback).toString());
        assertEquals("long str".length(), mStart);
        assertEquals(text.length(), mEnd);

        // TruncateAt.MIDDLE, specify preserveLength
        resetRange();
        textWidth = p.measureText("long" + mEllipsis + "ate");
        ellipsisNum = text.length() - "long".length() - "ate".length();
        assertEquals("long" + getBlankString(true, ellipsisNum) + "ate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE, true,
                        callback).toString());
        assertEquals("long".length(), mStart);
        assertEquals(text.length() - "ate".length(), mEnd);

        // TruncateAt.MIDDLE, specify preserveLength, but does not specify callback.
        resetRange();
        assertEquals("long" + getBlankString(true, ellipsisNum) + "ate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE, true,
                        null).toString());
        assertEquals(-1, mStart);
        assertEquals(-1, mEnd);

        // TruncateAt.MARQUEE, specify preserveLength
        // issue 1688347, ellipsize() is not defined for TruncateAt.MARQUEE.
        // In the code it looks like this does the same as MIDDLE.
        // In other methods, MARQUEE is equivalent to END, except for the first line.
        resetRange();
        textWidth = p.measureText("long" + mEllipsis + "ate");
        ellipsisNum = text.length() - "long".length() - "ate".length();
        assertEquals("long" + getBlankString(true, ellipsisNum) + "ate",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.MARQUEE, true,
                        callback).toString());
        assertEquals("long".length(), mStart);
        assertEquals(text.length() - "ate".length(), mEnd);

        // avail is not long enough for ELLIPSIS, and preserveLength is specified.
        resetRange();
        textWidth = p.measureText(mEllipsis);
        assertEquals(getBlankString(false, text.length()),
                TextUtils.ellipsize(text, p, textWidth - 1f, TruncateAt.END, true,
                        callback).toString());
        assertEquals(0, mStart);
        assertEquals(text.length(), mEnd);

        // avail is not long enough for ELLIPSIS, and preserveLength doesn't be specified.
        resetRange();
        assertEquals("",
                TextUtils.ellipsize(text, p, textWidth - 1f, TruncateAt.END, false,
                        callback).toString());
        assertEquals(0, mStart);
        assertEquals(text.length(), mEnd);

        // avail is long enough for ELLIPSIS, and preserveLength is specified.
        resetRange();
        assertEquals(getBlankString(false, text.length()),
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.END, true, callback).toString());
        assertEquals(0, mStart);
        assertEquals(text.length(), mEnd);

        // avail is long enough for ELLIPSIS, and preserveLength doesn't be specified.
        resetRange();
        assertEquals("",
                TextUtils.ellipsize(text, p, textWidth, TruncateAt.END, false,
                        callback).toString());
        assertEquals(0, mStart);
        assertEquals(text.length(), mEnd);

        // avail is long enough for the whole sentence.
        resetRange();
        assertEquals(text,
                TextUtils.ellipsize(text, p, Float.MAX_VALUE, TruncateAt.END, true,
                        callback).toString());
        assertEquals(0, mStart);
        assertEquals(0, mEnd);

        textWidth = p.measureText("long str" + mEllipsis);
        try {
            TextUtils.ellipsize(text, null, textWidth, TruncateAt.END, true, callback);
        } catch (NullPointerException e) {
            // expected
        }

        try {
            TextUtils.ellipsize(null, p, textWidth, TruncateAt.END, true, callback);
        } catch (NullPointerException e) {
            // expected
        }
    }

    /**
     * Get a blank string which is filled up by '\uFEFF'.
     *
     * @param isNeedStart - boolean whether need to start with char '\u2026' in the string.
     * @param len - int length of string.
     * @return a blank string which is filled up by '\uFEFF'.
     */
    private static String getBlankString(boolean isNeedStart, int len) {
        StringBuilder buf = new StringBuilder();

        int i = 0;
        if (isNeedStart) {
            buf.append('\u2026');
            i++;
        }
        for (; i < len; i++) {
            buf.append('\uFEFF');
        }

        return buf.toString();
    }

    @Test
    public void testEquals() {
        // compare with itself.
        // String is a subclass of CharSequence and overrides equals().
        String string = "same object";
        assertTrue(TextUtils.equals(string, string));

        // SpannableString is a subclass of CharSequence and does NOT override equals().
        SpannableString spanString = new SpannableString("same object");
        final String url = "www.test_url.com";
        spanString.setSpan(new URLSpan(url), 0, spanString.length(),
                Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        assertTrue(TextUtils.equals(spanString, spanString));

        // compare with other objects which have same content.
        assertTrue(TextUtils.equals("different object", "different object"));

        SpannableString urlSpanString = new SpannableString("same content");
        SpannableString bgColorSpanString = new SpannableString(
                "same content");
        URLSpan urlSpan = new URLSpan(url);
        urlSpanString.setSpan(urlSpan, 0, urlSpanString.length(),
                Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.GREEN);
        bgColorSpanString.setSpan(bgColorSpan, 0, bgColorSpanString.length(),
                Spanned.SPAN_INCLUSIVE_INCLUSIVE);

        assertTrue(TextUtils.equals(bgColorSpanString, urlSpanString));

        // compare with other objects which have different content.
        assertFalse(TextUtils.equals("different content A", "different content B"));
        assertFalse(TextUtils.equals(spanString, urlSpanString));
        assertFalse(TextUtils.equals(spanString, bgColorSpanString));

        // compare with null
        assertTrue(TextUtils.equals(null, null));
        assertFalse(TextUtils.equals(spanString, null));
        assertFalse(TextUtils.equals(null, string));
    }

    @Test
    public void testExpandTemplate() {
        // ^1 at the start of template string.
        assertEquals("value1 template to be expanded",
                TextUtils.expandTemplate("^1 template to be expanded", "value1").toString());
        // ^1 at the end of template string.
        assertEquals("template to be expanded value1",
                TextUtils.expandTemplate("template to be expanded ^1", "value1").toString());
        // ^1 in the middle of template string.
        assertEquals("template value1 to be expanded",
                TextUtils.expandTemplate("template ^1 to be expanded", "value1").toString());
        // ^1 followed by a '0'
        assertEquals("template value10 to be expanded",
                TextUtils.expandTemplate("template ^10 to be expanded", "value1").toString());
        // ^1 followed by a 'a'
        assertEquals("template value1a to be expanded",
                TextUtils.expandTemplate("template ^1a to be expanded", "value1").toString());
        // no ^1
        assertEquals("template ^a to be expanded",
                TextUtils.expandTemplate("template ^a to be expanded", "value1").toString());
        assertEquals("template to be expanded",
                TextUtils.expandTemplate("template to be expanded", "value1").toString());
        // two consecutive ^ in the input to produce a single ^ in the output.
        assertEquals("template ^ to be expanded",
                TextUtils.expandTemplate("template ^^ to be expanded", "value1").toString());
        // two ^ with a space in the middle.
        assertEquals("template ^ ^ to be expanded",
                TextUtils.expandTemplate("template ^ ^ to be expanded", "value1").toString());
        // ^1 follow a '^'
        assertEquals("template ^1 to be expanded",
                TextUtils.expandTemplate("template ^^1 to be expanded", "value1").toString());
        // ^1 followed by a '^'
        assertEquals("template value1^ to be expanded",
                TextUtils.expandTemplate("template ^1^ to be expanded", "value1").toString());

        // 9 replacement values
        final int MAX_SUPPORTED_VALUES_NUM = 9;
        CharSequence values[] = createCharSequenceArray(MAX_SUPPORTED_VALUES_NUM);
        String expected = "value1 value2 template value3 value4 to value5 value6" +
                " be value7 value8 expanded value9";
        String template = "^1 ^2 template ^3 ^4 to ^5 ^6 be ^7 ^8 expanded ^9";
        assertEquals(expected, TextUtils.expandTemplate(template, values).toString());

        //  only up to 9 replacement values are supported
        values = createCharSequenceArray(MAX_SUPPORTED_VALUES_NUM + 1);
        try {
            TextUtils.expandTemplate(template, values);
            fail("Should throw IllegalArgumentException!");
        } catch (IllegalArgumentException e) {
            // expect
        }
    }

    @Test(expected=IllegalArgumentException.class)
    public void testExpandTemplateCaret0WithValue() {
        // template string is ^0
        TextUtils.expandTemplate("template ^0 to be expanded", "value1");
    }

    @Test(expected=IllegalArgumentException.class)
    public void testExpandTemplateCaret0NoValues() {
        // template string is ^0
        TextUtils.expandTemplate("template ^0 to be expanded");
    }

    @Test(expected=IllegalArgumentException.class)
    public void testExpandTemplateNotEnoughValues() {
        // the template requests 2 values but only 1 is provided
        TextUtils.expandTemplate("template ^2 to be expanded", "value1");
    }

    @Test(expected=NullPointerException.class)
    public void testExpandTemplateNullValues() {
        // values is null
        TextUtils.expandTemplate("template ^2 to be expanded", (CharSequence[]) null);
    }

    @Test(expected=IllegalArgumentException.class)
    public void testExpandTemplateNotEnoughValuesAndFirstIsNull() {
        // the template requests 2 values but only one null value is provided
        TextUtils.expandTemplate("template ^2 to be expanded", (CharSequence) null);
    }

    @Test(expected=NullPointerException.class)
    public void testExpandTemplateAllValuesAreNull() {
        // the template requests 2 values and 2 values is provided, but all values are null.
        TextUtils.expandTemplate("template ^2 to be expanded",
                (CharSequence) null, (CharSequence) null);
    }

    @Test(expected=IllegalArgumentException.class)
    public void testExpandTemplateNoValues() {
        // the template requests 2 values but no value is provided.
        TextUtils.expandTemplate("template ^2 to be expanded");
    }

    @Test(expected=NullPointerException.class)
    public void testExpandTemplateNullTemplate() {
        // template is null
        TextUtils.expandTemplate(null, "value1");
    }

    /**
     * Create a char sequence array with the specified length
     * @param len the length of the array
     * @return The char sequence array with the specified length.
     * The value of each item is "value[index+1]"
     */
    private static CharSequence[] createCharSequenceArray(int len) {
        CharSequence array[] = new CharSequence[len];

        for (int i = 0; i < len; i++) {
            array[i] = "value" + (i + 1);
        }

        return array;
    }

    @Test
    public void testGetChars() {
        char[] destOriginal = "destination".toCharArray();
        char[] destResult = destOriginal.clone();

        // check whether GetChars.getChars() is called and with the proper parameters.
        MockGetChars mockGetChars = new MockGetChars();
        int start = 1;
        int end = destResult.length;
        int destOff = 2;
        TextUtils.getChars(mockGetChars, start, end, destResult, destOff);
        assertTrue(mockGetChars.hasCalledGetChars());
        assertEquals(start, mockGetChars.ReadGetCharsParams().start);
        assertEquals(end, mockGetChars.ReadGetCharsParams().end);
        assertEquals(destResult, mockGetChars.ReadGetCharsParams().dest);
        assertEquals(destOff, mockGetChars.ReadGetCharsParams().destoff);

        // use MockCharSequence to do the test includes corner cases.
        MockCharSequence mockCharSequence = new MockCharSequence("source string mock");
        // get chars to place at the beginning of the destination except the latest one char.
        destResult = destOriginal.clone();
        start = 0;
        end = destResult.length - 1;
        destOff = 0;
        TextUtils.getChars(mockCharSequence, start, end, destResult, destOff);
        // chars before end are copied from the mockCharSequence.
        for (int i = 0; i < end - start; i++) {
            assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]);
        }
        // chars after end doesn't be changed.
        for (int i = destOff + (end - start); i < destOriginal.length; i++) {
            assertEquals(destOriginal[i], destResult[i]);
        }

        // get chars to place at the end of the destination except the earliest two chars.
        destResult = destOriginal.clone();
        start = 0;
        end = destResult.length - 2;
        destOff = 2;
        TextUtils.getChars(mockCharSequence, start, end, destResult, destOff);
        // chars before start doesn't be changed.
        for (int i = 0; i < destOff; i++) {
            assertEquals(destOriginal[i], destResult[i]);
        }
        // chars after start are copied from the mockCharSequence.
        for (int i = 0; i < end - start; i++) {
            assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]);
        }

        // get chars to place at the end of the destination except the earliest two chars
        // and the latest one word.
        destResult = destOriginal.clone();
        start = 1;
        end = destResult.length - 2;
        destOff = 0;
        TextUtils.getChars(mockCharSequence, start, end, destResult, destOff);
        for (int i = 0; i < destOff; i++) {
            assertEquals(destOriginal[i], destResult[i]);
        }
        for (int i = 0; i < end - start; i++) {
            assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]);
        }
        for (int i = destOff + (end - start); i < destOriginal.length; i++) {
            assertEquals(destOriginal[i], destResult[i]);
        }

        // get chars to place the whole of the destination
        destResult = destOriginal.clone();
        start = 0;
        end = destResult.length;
        destOff = 0;
        TextUtils.getChars(mockCharSequence, start, end, destResult, destOff);
        for (int i = 0; i < end - start; i++) {
            assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]);
        }

        // exceptional start.
        end = 2;
        destOff = 0;
        destResult = destOriginal.clone();
        try {
            TextUtils.getChars(mockCharSequence, -1, end, destResult, destOff);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        destResult = destOriginal.clone();
        TextUtils.getChars(mockCharSequence, Integer.MAX_VALUE, end, destResult, destOff);
        for (int i = 0; i < destResult.length; i++) {
            assertEquals(destOriginal[i], destResult[i]);
        }

        // exceptional end.
        destResult = destOriginal.clone();
        start = 0;
        destOff = 0;
        try {
            TextUtils.getChars(mockCharSequence, start, destResult.length + 1, destResult, destOff);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        destResult = destOriginal.clone();
        TextUtils.getChars(mockCharSequence, start, -1, destResult, destOff);
        for (int i = 0; i < destResult.length; i++) {
            assertEquals(destOriginal[i], destResult[i]);
        }

        // exceptional destOff.
        destResult = destOriginal.clone();
        start = 0;
        end = 2;
        try {
            TextUtils.getChars(mockCharSequence, start, end, destResult, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        try {
            TextUtils.getChars(mockCharSequence, start, end, destResult, Integer.MIN_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }

        // exceptional source
        start = 0;
        end = 2;
        destOff =0;
        try {
            TextUtils.getChars(null, start, end, destResult, destOff);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }

        // exceptional destination
        try {
            TextUtils.getChars(mockCharSequence, start, end, null, destOff);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
    }

    /**
     * MockGetChars for test.
     */
    private static class MockGetChars implements GetChars {
        private boolean mHasCalledGetChars;
        private GetCharsParams mGetCharsParams = new GetCharsParams();

        class GetCharsParams {
            int start;
            int end;
            char[] dest;
            int destoff;
        }

        public boolean hasCalledGetChars() {
            return mHasCalledGetChars;
        }

        public void reset() {
            mHasCalledGetChars = false;
        }

        public GetCharsParams ReadGetCharsParams() {
            return mGetCharsParams;
        }

        public void getChars(int start, int end, char[] dest, int destoff) {
            mHasCalledGetChars = true;
            mGetCharsParams.start = start;
            mGetCharsParams.end = end;
            mGetCharsParams.dest = dest;
            mGetCharsParams.destoff = destoff;
        }

        public char charAt(int arg0) {
            return 0;
        }

        public int length() {
            return 100;
        }

        public CharSequence subSequence(int arg0, int arg1) {
            return null;
        }
    }

    /**
     * MockCharSequence for test.
     */
    private static class MockCharSequence implements CharSequence {
        private char mText[];

        public MockCharSequence(String text) {
            mText = text.toCharArray();
        }

        public char charAt(int arg0) {
            if (arg0 >= 0 && arg0 < mText.length) {
                return mText[arg0];
            }
            throw new IndexOutOfBoundsException();
        }

        public int length() {
            return mText.length;
        }

        public CharSequence subSequence(int arg0, int arg1) {
            return null;
        }
    }

    @Test
    public void testGetOffsetAfter() {
        // the first '\uD800' is index 9, the second 'uD800' is index 16
        // the '\uDBFF' is index 26
        final int POS_FIRST_D800 = 9;       // the position of the first '\uD800'.
        final int POS_SECOND_D800 = 16;
        final int POS_FIRST_DBFF = 26;
        final int SUPPLEMENTARY_CHARACTERS_OFFSET = 2;  // the offset for a supplementary characters
        final int NORMAL_CHARACTERS_OFFSET = 1;
        SpannableString text = new SpannableString(
                "string to\uD800\uDB00 get \uD800\uDC00 offset \uDBFF\uDFFF after");
        assertEquals(0 + 1, TextUtils.getOffsetAfter(text, 0));
        assertEquals(text.length(), TextUtils.getOffsetAfter(text, text.length()));
        assertEquals(text.length(), TextUtils.getOffsetAfter(text, text.length() - 1));
        assertEquals(POS_FIRST_D800 + NORMAL_CHARACTERS_OFFSET,
                TextUtils.getOffsetAfter(text, POS_FIRST_D800));
        assertEquals(POS_SECOND_D800 + SUPPLEMENTARY_CHARACTERS_OFFSET,
                TextUtils.getOffsetAfter(text, POS_SECOND_D800));
        assertEquals(POS_FIRST_DBFF + SUPPLEMENTARY_CHARACTERS_OFFSET,
                TextUtils.getOffsetAfter(text, POS_FIRST_DBFF));

        // the CharSequence string has a span.
        ReplacementSpan mockReplacementSpan = mock(ReplacementSpan.class);
        when(mockReplacementSpan.getSize(any(), any(), anyInt(), anyInt(), any())).thenReturn(0);
        text.setSpan(mockReplacementSpan, POS_FIRST_D800 - 1, text.length() - 1,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        assertEquals(text.length() - 1, TextUtils.getOffsetAfter(text, POS_FIRST_D800));

        try {
            TextUtils.getOffsetAfter(text, -1);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.getOffsetAfter(text, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.getOffsetAfter(null, 0);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
    }

    @Test
    public void testGetOffsetBefore() {
        // the first '\uDC00' is index 10, the second 'uDC00' is index 17
        // the '\uDFFF' is index 27
        final int POS_FIRST_DC00 = 10;
        final int POS_SECOND_DC00 = 17;
        final int POS_FIRST_DFFF = 27;
        final int SUPPLYMENTARY_CHARACTERS_OFFSET = 2;
        final int NORMAL_CHARACTERS_OFFSET = 1;
        SpannableString text = new SpannableString(
                "string to\uD700\uDC00 get \uD800\uDC00 offset \uDBFF\uDFFF before");
        assertEquals(0, TextUtils.getOffsetBefore(text, 0));
        assertEquals(0, TextUtils.getOffsetBefore(text, 1));
        assertEquals(text.length() - 1, TextUtils.getOffsetBefore(text, text.length()));
        assertEquals(POS_FIRST_DC00 + 1 - NORMAL_CHARACTERS_OFFSET,
                TextUtils.getOffsetBefore(text, POS_FIRST_DC00 + 1));
        assertEquals(POS_SECOND_DC00 + 1 - SUPPLYMENTARY_CHARACTERS_OFFSET,
                TextUtils.getOffsetBefore(text, POS_SECOND_DC00 + 1));
        assertEquals(POS_FIRST_DFFF + 1 - SUPPLYMENTARY_CHARACTERS_OFFSET,
                TextUtils.getOffsetBefore(text, POS_FIRST_DFFF + 1));

        // the CharSequence string has a span.
        ReplacementSpan mockReplacementSpan = mock(ReplacementSpan.class);
        when(mockReplacementSpan.getSize(any(), any(), anyInt(), anyInt(), any())).thenReturn(0);
        text.setSpan(mockReplacementSpan, 0, POS_FIRST_DC00 + 1,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        assertEquals(0, TextUtils.getOffsetBefore(text, POS_FIRST_DC00));

        try {
            TextUtils.getOffsetBefore(text, -1);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.getOffsetBefore(text, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.getOffsetBefore(null, POS_FIRST_DC00);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
    }

    @Test
    public void testGetReverse() {
        String source = "string to be reversed";
        assertEquals("gnirts", TextUtils.getReverse(source, 0, "string".length()).toString());
        assertEquals("desrever",
                TextUtils.getReverse(source, source.length() - "reversed".length(),
                        source.length()).toString());
        assertEquals("", TextUtils.getReverse(source, 0, 0).toString());

        // issue 1695243, exception is thrown after the result of some cases
        // convert to a string, is this expected?
        CharSequence result = TextUtils.getReverse(source, -1, "string".length());
        try {
            result.toString();
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        TextUtils.getReverse(source, 0, source.length() + 1);
        try {
            result.toString();
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        TextUtils.getReverse(source, "string".length(), 0);
        try {
            result.toString();
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        TextUtils.getReverse(source, 0, Integer.MAX_VALUE);
        try {
            result.toString();
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        TextUtils.getReverse(source, Integer.MIN_VALUE, "string".length());
        try {
            result.toString();
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        TextUtils.getReverse(null, 0, "string".length());
        try {
            result.toString();
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }
    }

    @Test
    public void testGetTrimmedLength() {
        assertEquals("normalstring".length(), TextUtils.getTrimmedLength("normalstring"));
        assertEquals("normal string".length(), TextUtils.getTrimmedLength("normal string"));
        assertEquals("blank before".length(), TextUtils.getTrimmedLength(" \t  blank before"));
        assertEquals("blank after".length(), TextUtils.getTrimmedLength("blank after   \n    "));
        assertEquals("blank both".length(), TextUtils.getTrimmedLength(" \t   blank both  \n "));

        char[] allTrimmedChars = new char[]{
                '\u0000', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007',
                '\u0008', '\u0009', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015',
                '\u0016', '\u0017', '\u0018', '\u0019', '\u0020'
        };
        assertEquals(0, TextUtils.getTrimmedLength(String.valueOf(allTrimmedChars)));
    }

    @Test(expected=NullPointerException.class)
    public void testGetTrimmedLengthNull() {
        TextUtils.getTrimmedLength(null);
    }

    @Test
    public void testHtmlEncode() {
        assertEquals("&lt;_html_&gt;\\ &amp;&quot;&#39;string&#39;&quot;",
                TextUtils.htmlEncode("<_html_>\\ &\"'string'\""));
    }

    @Test(expected=NullPointerException.class)
    public void testHtmlEncodeNull() {
         TextUtils.htmlEncode(null);
    }

    @Test
    public void testIndexOf1() {
        String searchString = "string to be searched";
        final int INDEX_OF_FIRST_R = 2;     // first occurrence of 'r'
        final int INDEX_OF_FIRST_T = 1;
        final int INDEX_OF_FIRST_D = searchString.length() - 1;

        assertEquals(INDEX_OF_FIRST_T, TextUtils.indexOf(searchString, 't'));
        assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(searchString, 'r'));
        assertEquals(INDEX_OF_FIRST_D, TextUtils.indexOf(searchString, 'd'));
        assertEquals(-1, TextUtils.indexOf(searchString, 'f'));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(stringBuffer, 'r'));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(stringBuilder, 'r'));

        MockGetChars mockGetChars = new MockGetChars();
        assertFalse(mockGetChars.hasCalledGetChars());
        TextUtils.indexOf(mockGetChars, 'r');
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(mockCharSequence, 'r'));
    }

    @Test
    public void testIndexOf2() {
        String searchString = "string to be searched";
        final int INDEX_OF_FIRST_R = 2;
        final int INDEX_OF_SECOND_R = 16;

        assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(searchString, 'r', 0));
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(searchString, 'r', INDEX_OF_FIRST_R + 1));
        assertEquals(-1, TextUtils.indexOf(searchString, 'r', searchString.length()));
        assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(searchString, 'r', Integer.MIN_VALUE));
        assertEquals(-1, TextUtils.indexOf(searchString, 'r', Integer.MAX_VALUE));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(stringBuffer, 'r', INDEX_OF_FIRST_R + 1));
        try {
            TextUtils.indexOf(stringBuffer, 'r', Integer.MIN_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        assertEquals(-1, TextUtils.indexOf(stringBuffer, 'r', Integer.MAX_VALUE));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_SECOND_R,
                TextUtils.indexOf(stringBuilder, 'r', INDEX_OF_FIRST_R + 1));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.indexOf(mockGetChars, 'r', INDEX_OF_FIRST_R + 1);
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(mockCharSequence, 'r',
                INDEX_OF_FIRST_R + 1));
    }

    @Test
    public void testIndexOf3() {
        String searchString = "string to be searched";
        final int INDEX_OF_FIRST_R = 2;
        final int INDEX_OF_SECOND_R = 16;

        assertEquals(INDEX_OF_FIRST_R,
                TextUtils.indexOf(searchString, 'r', 0, searchString.length()));
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(searchString, 'r',
                INDEX_OF_FIRST_R + 1, searchString.length()));
        assertEquals(-1, TextUtils.indexOf(searchString, 'r',
                INDEX_OF_FIRST_R + 1, INDEX_OF_SECOND_R));

        try {
            TextUtils.indexOf(searchString, 'r', Integer.MIN_VALUE, INDEX_OF_SECOND_R);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        assertEquals(-1,
                TextUtils.indexOf(searchString, 'r', Integer.MAX_VALUE, INDEX_OF_SECOND_R));
        assertEquals(-1, TextUtils.indexOf(searchString, 'r', 0, Integer.MIN_VALUE));
        try {
            TextUtils.indexOf(searchString, 'r', 0, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(stringBuffer, 'r',
                INDEX_OF_FIRST_R + 1, searchString.length()));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(stringBuilder, 'r',
                INDEX_OF_FIRST_R + 1, searchString.length()));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.indexOf(mockGetChars, 'r', INDEX_OF_FIRST_R + 1, searchString.length());
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(mockCharSequence, 'r',
                INDEX_OF_FIRST_R + 1, searchString.length()));
    }

    @Test
    public void testIndexOf4() {
        String searchString = "string to be searched by string";
        final int SEARCH_INDEX = 13;

        assertEquals(0, TextUtils.indexOf(searchString, "string"));
        assertEquals(SEARCH_INDEX, TextUtils.indexOf(searchString, "search"));
        assertEquals(-1, TextUtils.indexOf(searchString, "tobe"));
        assertEquals(0, TextUtils.indexOf(searchString, ""));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(SEARCH_INDEX, TextUtils.indexOf(stringBuffer, "search"));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(SEARCH_INDEX, TextUtils.indexOf(stringBuilder, "search"));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.indexOf(mockGetChars, "search");
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(SEARCH_INDEX, TextUtils.indexOf(mockCharSequence, "search"));
    }

    @Test
    public void testIndexOf5() {
        String searchString = "string to be searched by string";
        final int INDEX_OF_FIRST_STRING = 0;
        final int INDEX_OF_SECOND_STRING = 25;

        assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string", 0));
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string",
                INDEX_OF_FIRST_STRING + 1));
        assertEquals(-1, TextUtils.indexOf(searchString, "string", INDEX_OF_SECOND_STRING + 1));
        assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string",
                Integer.MIN_VALUE));
        assertEquals(-1, TextUtils.indexOf(searchString, "string", Integer.MAX_VALUE));

        assertEquals(1, TextUtils.indexOf(searchString, "", 1));
        assertEquals(Integer.MAX_VALUE, TextUtils.indexOf(searchString, "", Integer.MAX_VALUE));

        assertEquals(0, TextUtils.indexOf(searchString, searchString, 0));
        assertEquals(-1, TextUtils.indexOf(searchString, searchString + "longer needle", 0));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer, "string",
                INDEX_OF_FIRST_STRING + 1));
        try {
            TextUtils.indexOf(stringBuffer, "string", Integer.MIN_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        assertEquals(-1, TextUtils.indexOf(stringBuffer, "string", Integer.MAX_VALUE));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuilder, "string",
                INDEX_OF_FIRST_STRING + 1));

        MockGetChars mockGetChars = new MockGetChars();
        assertFalse(mockGetChars.hasCalledGetChars());
        TextUtils.indexOf(mockGetChars, "string", INDEX_OF_FIRST_STRING + 1);
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(mockCharSequence, "string",
                INDEX_OF_FIRST_STRING + 1));
    }

    @Test
    public void testIndexOf6() {
        String searchString = "string to be searched by string";
        final int INDEX_OF_FIRST_STRING = 0;
        final int INDEX_OF_SECOND_STRING = 25;

        assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string", 0,
                searchString.length()));
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string",
                INDEX_OF_FIRST_STRING + 1, searchString.length()));
        assertEquals(-1, TextUtils.indexOf(searchString, "string", INDEX_OF_FIRST_STRING + 1,
                INDEX_OF_SECOND_STRING - 1));
        assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string",
                Integer.MIN_VALUE, INDEX_OF_SECOND_STRING - 1));
        assertEquals(-1, TextUtils.indexOf(searchString, "string", Integer.MAX_VALUE,
                INDEX_OF_SECOND_STRING - 1));

        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string",
                INDEX_OF_FIRST_STRING + 1, Integer.MIN_VALUE));
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string",
                INDEX_OF_FIRST_STRING + 1, Integer.MAX_VALUE));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer, "string",
                INDEX_OF_FIRST_STRING + 1, searchString.length()));
        try {
            TextUtils.indexOf(stringBuffer, "string", Integer.MIN_VALUE,
                    INDEX_OF_SECOND_STRING - 1);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        assertEquals(-1, TextUtils.indexOf(stringBuffer, "string", Integer.MAX_VALUE,
                searchString.length()));
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer,
                "string", INDEX_OF_FIRST_STRING + 1, Integer.MIN_VALUE));
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer,
                "string", INDEX_OF_FIRST_STRING + 1, Integer.MAX_VALUE));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuilder, "string",
                INDEX_OF_FIRST_STRING + 1, searchString.length()));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.indexOf(mockGetChars, "string", INDEX_OF_FIRST_STRING + 1, searchString.length());
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(mockCharSequence, "string",
                INDEX_OF_FIRST_STRING + 1, searchString.length()));
    }

    @Test
    public void testIsDigitsOnly() {
        assertTrue(TextUtils.isDigitsOnly(""));
        assertFalse(TextUtils.isDigitsOnly("no digit"));
        assertFalse(TextUtils.isDigitsOnly("character and 56 digits"));
        assertTrue(TextUtils.isDigitsOnly("0123456789"));
        assertFalse(TextUtils.isDigitsOnly("1234 56789"));

        // U+104A0 OSMANYA DIGIT ZERO
        assertTrue(TextUtils.isDigitsOnly(new String(Character.toChars(0x104A0))));
        // U+10858 IMPERIAL ARAMAIC NUMBER ONE
        assertFalse(TextUtils.isDigitsOnly(new String(Character.toChars(0x10858))));

        assertFalse(TextUtils.isDigitsOnly("\uD801")); // lonely lead surrogate
        assertFalse(TextUtils.isDigitsOnly("\uDCA0")); // lonely trailing surrogate
    }

    @Test(expected=NullPointerException.class)
    public void testIsDigitsOnlyNull() {
        TextUtils.isDigitsOnly(null);
    }

    @Test
    public void testIsEmpty() {
        assertFalse(TextUtils.isEmpty("not empty"));
        assertFalse(TextUtils.isEmpty("    "));
        assertTrue(TextUtils.isEmpty(""));
        assertTrue(TextUtils.isEmpty(null));
    }

    @Test
    public void testIsGraphicChar() {
        assertTrue(TextUtils.isGraphic('a'));
        assertTrue(TextUtils.isGraphic('\uBA00'));

        // LINE_SEPARATOR
        assertFalse(TextUtils.isGraphic('\u2028'));

        // PARAGRAPH_SEPARATOR
        assertFalse(TextUtils.isGraphic('\u2029'));

        // CONTROL
        assertFalse(TextUtils.isGraphic('\u0085'));

        // UNASSIGNED
        assertFalse(TextUtils.isGraphic('\uFFFF'));

        // SURROGATE
        assertFalse(TextUtils.isGraphic('\uD800'));

        // SPACE_SEPARATOR
        assertFalse(TextUtils.isGraphic('\u0020'));
    }

    @Test(expected=NullPointerException.class)
    public void testIsGraphicCharNull() {
        assertFalse(TextUtils.isGraphic((Character) null));
    }

    @Test
    public void testIsGraphicCharSequence() {
        assertTrue(TextUtils.isGraphic("printable characters"));

        assertFalse(TextUtils.isGraphic("\u2028\u2029\u0085\uFFFF\uD800\u0020"));

        assertTrue(TextUtils.isGraphic("a\u2028\u2029\u0085\uFFFF\uD800\u0020"));

        assertTrue(TextUtils.isGraphic("\uD83D\uDC0C")); // U+1F40C SNAIL
        assertFalse(TextUtils.isGraphic("\uDB40\uDC01")); // U+E0000 (unassigned)
        assertFalse(TextUtils.isGraphic("\uDB3D")); // unpaired high surrogate
        assertFalse(TextUtils.isGraphic("\uDC0C")); // unpaired low surrogate
    }

    @Test(expected=NullPointerException.class)
    public void testIsGraphicCharSequenceNull() {
        TextUtils.isGraphic(null);
    }

    @Test
    public void testJoinIterable() {
        ArrayList<CharSequence> charTokens = new ArrayList<>();
        charTokens.add("string1");
        charTokens.add("string2");
        charTokens.add("string3");
        assertEquals("string1|string2|string3", TextUtils.join("|", charTokens));
        assertEquals("string1; string2; string3", TextUtils.join("; ", charTokens));
        assertEquals("string1string2string3", TextUtils.join("", charTokens));

        // issue 1695243, not clear what is supposed result if the delimiter or tokens are null.
        assertEquals("string1nullstring2nullstring3", TextUtils.join(null, charTokens));

        ArrayList<SpannableString> spannableStringTokens = new ArrayList<SpannableString>();
        spannableStringTokens.add(new SpannableString("span 1"));
        spannableStringTokens.add(new SpannableString("span 2"));
        spannableStringTokens.add(new SpannableString("span 3"));
        assertEquals("span 1;span 2;span 3", TextUtils.join(";", spannableStringTokens));

        assertEquals("", TextUtils.join("|", new ArrayList<CharSequence>()));
    }

    @Test(expected=NullPointerException.class)
    public void testJoinIterableNull() {
        TextUtils.join("|", (Iterable) null);
    }

    @Test
    public void testJoinArray() {
        CharSequence[] charTokens = new CharSequence[] { "string1", "string2", "string3" };
        assertEquals("string1|string2|string3", TextUtils.join("|", charTokens));
        assertEquals("string1; string2; string3", TextUtils.join("; ", charTokens));
        assertEquals("string1string2string3", TextUtils.join("", charTokens));

        // issue 1695243, not clear what is supposed result if the delimiter or tokens are null.
        assertEquals("string1nullstring2nullstring3", TextUtils.join(null, charTokens));

        SpannableString[] spannableStringTokens = new SpannableString[] {
                new SpannableString("span 1"),
                new SpannableString("span 2"),
                new SpannableString("span 3") };
        assertEquals("span 1;span 2;span 3", TextUtils.join(";", spannableStringTokens));

        assertEquals("", TextUtils.join("|", new String[0]));
    }

    @Test(expected=NullPointerException.class)
    public void testJoinArrayNull() {
        TextUtils.join("|", (Object[]) null);
    }

    @Test
    public void testLastIndexOf1() {
        String searchString = "string to be searched";
        final int INDEX_OF_LAST_R = 16;
        final int INDEX_OF_LAST_T = 7;
        final int INDEX_OF_LAST_D = searchString.length() - 1;

        assertEquals(INDEX_OF_LAST_T, TextUtils.lastIndexOf(searchString, 't'));
        assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(searchString, 'r'));
        assertEquals(INDEX_OF_LAST_D, TextUtils.lastIndexOf(searchString, 'd'));
        assertEquals(-1, TextUtils.lastIndexOf(searchString, 'f'));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(stringBuffer, 'r'));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(stringBuilder, 'r'));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.lastIndexOf(mockGetChars, 'r');
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(mockCharSequence, 'r'));
    }

    @Test
    public void testLastIndexOf2() {
        String searchString = "string to be searched";
        final int INDEX_OF_FIRST_R = 2;
        final int INDEX_OF_SECOND_R = 16;

        assertEquals(INDEX_OF_SECOND_R,
                TextUtils.lastIndexOf(searchString, 'r', searchString.length()));
        assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', 0));
        assertEquals(INDEX_OF_FIRST_R,
                TextUtils.lastIndexOf(searchString, 'r', INDEX_OF_FIRST_R));
        assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', Integer.MIN_VALUE));
        assertEquals(INDEX_OF_SECOND_R,
                TextUtils.lastIndexOf(searchString, 'r', Integer.MAX_VALUE));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_FIRST_R,
                TextUtils.lastIndexOf(stringBuffer, 'r', INDEX_OF_FIRST_R));
        assertEquals(-1, TextUtils.lastIndexOf(stringBuffer, 'r', Integer.MIN_VALUE));
        assertEquals(INDEX_OF_SECOND_R,
                TextUtils.lastIndexOf(stringBuffer, 'r', Integer.MAX_VALUE));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_FIRST_R,
                TextUtils.lastIndexOf(stringBuilder, 'r', INDEX_OF_FIRST_R));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.lastIndexOf(mockGetChars, 'r', INDEX_OF_FIRST_R);
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_FIRST_R,
                TextUtils.lastIndexOf(mockCharSequence, 'r', INDEX_OF_FIRST_R));
    }

    @Test
    public void testLastIndexOf3() {
        String searchString = "string to be searched";
        final int INDEX_OF_FIRST_R = 2;
        final int INDEX_OF_SECOND_R = 16;

        assertEquals(INDEX_OF_SECOND_R, TextUtils.lastIndexOf(searchString, 'r', 0,
                searchString.length()));
        assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(searchString, 'r', 0,
                INDEX_OF_SECOND_R - 1));
        assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', 0, INDEX_OF_FIRST_R - 1));

        try {
            TextUtils.lastIndexOf(searchString, 'r', Integer.MIN_VALUE, INDEX_OF_SECOND_R - 1);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expect
        }
        assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', Integer.MAX_VALUE,
                INDEX_OF_SECOND_R - 1));
        assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', 0, Integer.MIN_VALUE));
        assertEquals(INDEX_OF_SECOND_R, TextUtils.lastIndexOf(searchString, 'r', 0,
                Integer.MAX_VALUE));

        StringBuffer stringBuffer = new StringBuffer(searchString);
        assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(stringBuffer, 'r', 0,
                INDEX_OF_SECOND_R - 1));

        StringBuilder stringBuilder = new StringBuilder(searchString);
        assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(stringBuilder, 'r', 0,
                INDEX_OF_SECOND_R - 1));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.lastIndexOf(mockGetChars, 'r', 0, INDEX_OF_SECOND_R - 1);
        assertTrue(mockGetChars.hasCalledGetChars());

        MockCharSequence mockCharSequence = new MockCharSequence(searchString);
        assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(mockCharSequence, 'r', 0,
                INDEX_OF_SECOND_R - 1));
    }

    @Test
    public void testRegionMatches() {
        assertFalse(TextUtils.regionMatches("one", 0, "two", 0, "one".length()));
        assertTrue(TextUtils.regionMatches("one", 0, "one", 0, "one".length()));
        try {
            TextUtils.regionMatches("one", 0, "one", 0, "one".length() + 1);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        String one = "Hello Android, hello World!";
        String two = "Hello World";
        // match "Hello"
        assertTrue(TextUtils.regionMatches(one, 0, two, 0, "Hello".length()));

        // match "Hello A" and "Hello W"
        assertFalse(TextUtils.regionMatches(one, 0, two, 0, "Hello A".length()));

        // match "World"
        assertTrue(TextUtils.regionMatches(one, "Hello Android, hello ".length(),
                two, "Hello ".length(), "World".length()));
        assertFalse(TextUtils.regionMatches(one, "Hello Android, hello ".length(),
                two, 0, "World".length()));

        try {
            TextUtils.regionMatches(one, Integer.MIN_VALUE, two, 0, "Hello".length());
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }
        try {
            TextUtils.regionMatches(one, Integer.MAX_VALUE, two, 0, "Hello".length());
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.regionMatches(one, 0, two, Integer.MIN_VALUE, "Hello".length());
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }
        try {
            TextUtils.regionMatches(one, 0, two, Integer.MAX_VALUE, "Hello".length());
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.regionMatches(one, 0, two, 0, Integer.MIN_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }
        try {
            TextUtils.regionMatches(one, 0, two, 0, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            TextUtils.regionMatches(null, 0, two, 0, "Hello".length());
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expect
        }
        try {
            TextUtils.regionMatches(one, 0, null, 0, "Hello".length());
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expect
        }
    }

    @Test
    public void testReplace() {
        String template = "this is a string to be as the template for replacement";

        String sources[] = new String[] { "string" };
        CharSequence destinations[] = new CharSequence[] { "text" };
        SpannableStringBuilder replacedString = (SpannableStringBuilder) TextUtils.replace(template,
                sources, destinations);
        assertEquals("this is a text to be as the template for replacement",
                replacedString.toString());

        sources = new String[] {"is", "the", "for replacement"};
        destinations = new CharSequence[] {"was", "", "to be replaced"};
        replacedString = (SpannableStringBuilder)TextUtils.replace(template, sources, destinations);
        assertEquals("thwas is a string to be as  template to be replaced",
                replacedString.toString());

        sources = new String[] {"is", "for replacement"};
        destinations = new CharSequence[] {"was", "", "to be replaced"};
        replacedString = (SpannableStringBuilder)TextUtils.replace(template, sources, destinations);
        assertEquals("thwas is a string to be as the template ", replacedString.toString());

        sources = new String[] {"is", "the", "for replacement"};
        destinations = new CharSequence[] {"was", "to be replaced"};
        try {
            TextUtils.replace(template, sources, destinations);
            fail("Should throw ArrayIndexOutOfBoundsException!");
        } catch (ArrayIndexOutOfBoundsException e) {
            // expected
        }

        try {
            TextUtils.replace(null, sources, destinations);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
        try {
            TextUtils.replace(template, null, destinations);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
        try {
            TextUtils.replace(template, sources, null);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
    }

    @Test
    public void testSplitPattern() {
        String testString = "abccbadecdebz";
        assertEquals(calculateCharsCount(testString, "c") + 1,
                TextUtils.split(testString, Pattern.compile("c")).length);
        assertEquals(calculateCharsCount(testString, "a") + 1,
                TextUtils.split(testString, Pattern.compile("a")).length);
        assertEquals(calculateCharsCount(testString, "z") + 1,
                TextUtils.split(testString, Pattern.compile("z")).length);
        assertEquals(calculateCharsCount(testString, "de") + 1,
                TextUtils.split(testString, Pattern.compile("de")).length);
        int totalCount = 1 + calculateCharsCount(testString, "a")
                + calculateCharsCount(testString, "b") + calculateCharsCount(testString, "c");
        assertEquals(totalCount,
                TextUtils.split(testString, Pattern.compile("[a-c]")).length);
        assertEquals(0, TextUtils.split("", Pattern.compile("a")).length);
        // issue 1695243, not clear what is supposed result if the pattern string is empty.
        assertEquals(testString.length() + 2,
                TextUtils.split(testString, Pattern.compile("")).length);
    }

    @Test(expected=NullPointerException.class)
    public void testSplitPatternNullText() {
        TextUtils.split(null, Pattern.compile("a"));
    }

    @Test(expected=NullPointerException.class)
    public void testSplitPatternNullPattern() {
            TextUtils.split("abccbadecdebz", (Pattern) null);
    }

    /*
     * return the appearance count of searched chars in text.
     */
    private static int calculateCharsCount(CharSequence text, CharSequence searches) {
        int count = 0;
        int start = TextUtils.indexOf(text, searches, 0);

        while (start != -1) {
            count++;
            start = TextUtils.indexOf(text, searches, start + 1);
        }
        return count;
    }

    @Test
    public void testSplitString() {
        String testString = "abccbadecdebz";
        assertEquals(calculateCharsCount(testString, "c") + 1,
                TextUtils.split("abccbadecdebz", "c").length);
        assertEquals(calculateCharsCount(testString, "a") + 1,
                TextUtils.split("abccbadecdebz", "a").length);
        assertEquals(calculateCharsCount(testString, "z") + 1,
                TextUtils.split("abccbadecdebz", "z").length);
        assertEquals(calculateCharsCount(testString, "de") + 1,
                TextUtils.split("abccbadecdebz", "de").length);
        assertEquals(0, TextUtils.split("", "a").length);
        // issue 1695243, not clear what is supposed result if the pattern string is empty.
        assertEquals(testString.length() + 2,
                TextUtils.split("abccbadecdebz", "").length);
    }

    @Test(expected=NullPointerException.class)
    public void testSplitStringNullText() {
        TextUtils.split(null, "a");
    }

    @Test(expected=NullPointerException.class)
    public void testSplitStringNullPattern() {
        TextUtils.split("abccbadecdebz", (String) null);
    }

    @Test
    public void testStringOrSpannedString() {
        assertNull(TextUtils.stringOrSpannedString(null));

        SpannedString spannedString = new SpannedString("Spanned String");
        assertSame(spannedString, TextUtils.stringOrSpannedString(spannedString));

        SpannableString spannableString = new SpannableString("Spannable String");
        assertEquals("Spannable String",
                TextUtils.stringOrSpannedString(spannableString).toString());
        assertEquals(SpannedString.class,
                TextUtils.stringOrSpannedString(spannableString).getClass());

        StringBuffer stringBuffer = new StringBuffer("String Buffer");
        assertEquals("String Buffer",
                TextUtils.stringOrSpannedString(stringBuffer).toString());
        assertEquals(String.class,
                TextUtils.stringOrSpannedString(stringBuffer).getClass());
    }

    @Test
    public void testSubString() {
        String string = "String";
        assertSame(string, TextUtils.substring(string, 0, string.length()));
        assertEquals("Strin", TextUtils.substring(string, 0, string.length() - 1));
        assertEquals("", TextUtils.substring(string, 1, 1));

        try {
            TextUtils.substring(string, string.length(), 0);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        try {
            TextUtils.substring(string, -1, string.length());
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        try {
            TextUtils.substring(string, Integer.MAX_VALUE, string.length());
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        try {
            TextUtils.substring(string, 0, -1);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        try {
            TextUtils.substring(string, 0, Integer.MAX_VALUE);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }

        try {
            TextUtils.substring(null, 0, string.length());
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }

        StringBuffer stringBuffer = new StringBuffer("String Buffer");
        assertEquals("Strin", TextUtils.substring(stringBuffer, 0, string.length() - 1));
        assertEquals("", TextUtils.substring(stringBuffer, 1, 1));

        MockGetChars mockGetChars = new MockGetChars();
        TextUtils.substring(mockGetChars, 0, string.length());
        assertTrue(mockGetChars.hasCalledGetChars());
    }

    @Test
    public void testWriteToParcel() {
        Parcelable.Creator<CharSequence> creator = TextUtils.CHAR_SEQUENCE_CREATOR;
        String string = "String";
        Parcel p = Parcel.obtain();
        try {
            TextUtils.writeToParcel(string, p, 0);
            p.setDataPosition(0);
            assertEquals(string, creator.createFromParcel(p).toString());
        } finally {
            p.recycle();
        }

        p = Parcel.obtain();
        try {
            TextUtils.writeToParcel(null, p, 0);
            p.setDataPosition(0);
            assertNull(creator.createFromParcel(p));
        } finally {
            p.recycle();
        }

        SpannableString spannableString = new SpannableString("Spannable String");
        int urlSpanStart = spannableString.length() >> 1;
        int urlSpanEnd = spannableString.length();
        p = Parcel.obtain();
        try {
            URLSpan urlSpan = new URLSpan("URL Span");
            spannableString.setSpan(urlSpan, urlSpanStart, urlSpanEnd,
                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            TextUtils.writeToParcel(spannableString, p, 0);
            p.setDataPosition(0);
            SpannableString ret = (SpannableString) creator.createFromParcel(p);
            assertEquals("Spannable String", ret.toString());
            Object[] spans = ret.getSpans(0, ret.length(), Object.class);
            assertEquals(1, spans.length);
            assertEquals("URL Span", ((URLSpan) spans[0]).getURL());
            assertEquals(urlSpanStart, ret.getSpanStart(spans[0]));
            assertEquals(urlSpanEnd, ret.getSpanEnd(spans[0]));
            assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, ret.getSpanFlags(spans[0]));
        } finally {
            p.recycle();
        }

        p = Parcel.obtain();
        try {
            ColorStateList colors = new ColorStateList(new int[][] {
                    new int[] {android.R.attr.state_focused}, new int[0]},
                    new int[] {Color.rgb(0, 255, 0), Color.BLACK});
            int textSize = 20;
            TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(
                    null, Typeface.ITALIC, textSize, colors, null);
            int textAppearanceSpanStart = 0;
            int textAppearanceSpanEnd = spannableString.length() >> 1;
            spannableString.setSpan(textAppearanceSpan, textAppearanceSpanStart,
                    textAppearanceSpanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            TextUtils.writeToParcel(spannableString, p, -1);
            p.setDataPosition(0);
            SpannableString ret = (SpannableString) creator.createFromParcel(p);
            assertEquals("Spannable String", ret.toString());
            Object[] spans = ret.getSpans(0, ret.length(), Object.class);
            assertEquals(2, spans.length);
            assertEquals("URL Span", ((URLSpan) spans[0]).getURL());
            assertEquals(urlSpanStart, ret.getSpanStart(spans[0]));
            assertEquals(urlSpanEnd, ret.getSpanEnd(spans[0]));
            assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, ret.getSpanFlags(spans[0]));
            assertEquals(null, ((TextAppearanceSpan) spans[1]).getFamily());

            assertEquals(Typeface.ITALIC, ((TextAppearanceSpan) spans[1]).getTextStyle());
            assertEquals(textSize, ((TextAppearanceSpan) spans[1]).getTextSize());

            assertEquals(colors.toString(), ((TextAppearanceSpan) spans[1]).getTextColor().toString());
            assertEquals(null, ((TextAppearanceSpan) spans[1]).getLinkTextColor());
            assertEquals(textAppearanceSpanStart, ret.getSpanStart(spans[1]));
            assertEquals(textAppearanceSpanEnd, ret.getSpanEnd(spans[1]));
            assertEquals(Spanned.SPAN_INCLUSIVE_EXCLUSIVE, ret.getSpanFlags(spans[1]));
        } finally {
            p.recycle();
        }

        try {
            TextUtils.writeToParcel(spannableString, null, 0);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }
    }

    @Test
    public void testGetCapsMode() {
        final int CAP_MODE_ALL = TextUtils.CAP_MODE_CHARACTERS
                | TextUtils.CAP_MODE_WORDS | TextUtils.CAP_MODE_SENTENCES;
        final int CAP_MODE_CHARACTERS_AND_WORD =
                TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS;
        String testString = "Start. Sentence word!No space before\n\t" +
                "Paragraph? (\"\'skip begin\'\"). skip end";

        // CAP_MODE_SENTENCES should be in effect in the whole text.
        for (int i = 0; i < testString.length(); i++) {
            assertEquals(TextUtils.CAP_MODE_CHARACTERS,
                    TextUtils.getCapsMode(testString, i, TextUtils.CAP_MODE_CHARACTERS));
        }

        // all modes should be in effect at the start of the text.
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, 0, TextUtils.CAP_MODE_WORDS));
        // issue 1586346
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, 0, TextUtils.CAP_MODE_SENTENCES));
        assertEquals(CAP_MODE_CHARACTERS_AND_WORD,
                TextUtils.getCapsMode(testString, 0, CAP_MODE_ALL));

        // all mode should be in effect at the position after "." or "?" or "!" + " ".
        int offset = testString.indexOf("Sentence word!");
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS));
        assertEquals(TextUtils.CAP_MODE_SENTENCES,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES));
        // issue 1586346
        assertEquals(CAP_MODE_CHARACTERS_AND_WORD,
                TextUtils.getCapsMode(testString, 0, CAP_MODE_ALL));

        // CAP_MODE_SENTENCES should NOT be in effect at the position after other words + " ".
        offset = testString.indexOf("word!");
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS));
        assertEquals(0,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES));
        // issue 1586346
        assertEquals(TextUtils.CAP_MODE_CHARACTERS,
                TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL));

        // if no space after "." or "?" or "!", CAP_MODE_SENTENCES and CAP_MODE_WORDS
        // should NOT be in effect.
        offset = testString.indexOf("No space before");
        assertEquals(0,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS));
        assertEquals(0,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES));
        assertEquals(TextUtils.CAP_MODE_CHARACTERS,
                TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL));

        // all mode should be in effect at a beginning of a new paragraph.
        offset = testString.indexOf("Paragraph");
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS));
        // issue 1586346
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES));
        assertEquals(CAP_MODE_CHARACTERS_AND_WORD,
                TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL));

        // some special word which means the start of a sentence should be skipped.
        offset = testString.indexOf("skip begin");
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS));
        assertEquals(TextUtils.CAP_MODE_SENTENCES,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES));
        // issue 1586346
        assertEquals(TextUtils.CAP_MODE_SENTENCES | TextUtils.CAP_MODE_CHARACTERS,
                TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL));

        // some special word which means the end of a sentence should be skipped.
        offset = testString.indexOf("skip end");
        assertEquals(TextUtils.CAP_MODE_WORDS,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS));
        assertEquals(TextUtils.CAP_MODE_SENTENCES,
                TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES));
        // issue 1586346
        assertEquals(TextUtils.CAP_MODE_SENTENCES | TextUtils.CAP_MODE_CHARACTERS,
                TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL));
    }

    @Test
    public void testGetCapsModeException() {
        String testString = "Start. Sentence word!No space before\n\t" +
                "Paragraph? (\"\'skip begin\'\"). skip end";

        int offset = testString.indexOf("Sentence word!");
        assertEquals(TextUtils.CAP_MODE_CHARACTERS,
                TextUtils.getCapsMode(null, offset, TextUtils.CAP_MODE_CHARACTERS));

        try {
            TextUtils.getCapsMode(null, offset, TextUtils.CAP_MODE_SENTENCES);
            fail("Should throw NullPointerException!");
        } catch (NullPointerException e) {
            // expected
        }

        assertEquals(0, TextUtils.getCapsMode(testString, -1, TextUtils.CAP_MODE_SENTENCES));

        try {
            TextUtils.getCapsMode(testString, testString.length() + 1,
                    TextUtils.CAP_MODE_SENTENCES);
            fail("Should throw IndexOutOfBoundsException!");
        } catch (IndexOutOfBoundsException e) {
            // expected
        }
    }

    @Test
    public void testDumpSpans() {
        StringBuilder builder = new StringBuilder();
        StringBuilderPrinter printer = new StringBuilderPrinter(builder);
        CharSequence source = "test dump spans";
        String prefix = "prefix";

        assertEquals(0, builder.length());
        TextUtils.dumpSpans(source, printer, prefix);
        assertTrue(builder.length() > 0);

        builder = new StringBuilder();
        printer = new StringBuilderPrinter(builder);
        assertEquals(0, builder.length());
        SpannableString spanned = new SpannableString(source);
        spanned.setSpan(new Object(), 0, source.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        TextUtils.dumpSpans(spanned, printer, prefix);
        assertTrue(builder.length() > 0);
    }

    @Test
    public void testGetLayoutDirectionFromLocale() {
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(null));

        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.ENGLISH));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.CANADA));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.FRANCE));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.FRENCH));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.GERMAN));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.GERMANY));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.ITALIAN));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.ITALY));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.UK));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.US));

        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.ROOT));

        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.CHINA));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.CHINESE));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.JAPAN));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.JAPANESE));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.KOREA));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.KOREAN));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.PRC));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.TAIWAN));
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));

        // Some languages always use an RTL script.
        for (Locale l : Locale.getAvailableLocales()) {
            String languageCode = l.getLanguage();
            if (languageCode.equals("ar") ||
                    languageCode.equals("fa") ||
                    languageCode.equals("iw") ||
                    languageCode.equals("he") ||
                    languageCode.equals("ps") ||
                    languageCode.equals("ur")) {
                int direction = TextUtils.getLayoutDirectionFromLocale(l);
                assertEquals(l.toLanguageTag() + " not RTL: " + direction,
                             LAYOUT_DIRECTION_RTL, direction);
            }
        }

        // Other languages have some cases where they use an RTL script.
        String[] tags = {
            "pa-Arab",
            "pa-Arab-PK",
            "ps",
            "ps-AF",
            "uz-Arab",
            "uz-Arab-AF",
        };
        for (String tag : tags) {
            Locale l = Locale.forLanguageTag(tag);
            int direction = TextUtils.getLayoutDirectionFromLocale(l);
            assertEquals(l.toLanguageTag() + " not RTL: " + direction,
                         LAYOUT_DIRECTION_RTL, direction);
        }

        // Locale without a real language
        Locale locale = Locale.forLanguageTag("zz");
        assertEquals(LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(locale));
    }
}
