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

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.TestAnnotatedMessages.Nested;
import com.google.gwt.i18n.client.gen.Colors;
import com.google.gwt.i18n.client.gen.Shapes;
import com.google.gwt.i18n.client.gen.TestMessages;
import com.google.gwt.i18n.client.resolutiontest.Inners;
import com.google.gwt.i18n.client.resolutiontest.Inners.ExtendsInnerInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.HasInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.HasInner.IsInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass.InnerInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass.InnerInnerMessages;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass.LocalizableInnerInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.LocalizableSimpleInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.OuterLoc;
import com.google.gwt.i18n.client.resolutiontest.Inners.SimpleInner;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.safehtml.shared.SimpleHtmlSanitizer;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;

/**
 * Tests Internationalization. Assumes locale is set to piglatin_UK
 */
public class I18NTest extends GWTTestCase {

  /**
   * A test object to verify that when formatting a message with an arbitrary
   * object passed as an argument, that object's toString method is called.
   */
  public static class TestObjectToString {
    @Override
    public String toString() {
      return "TestObjectToString";
    }
  }

  private static final String HTML_TO_SANITIZE =
      "<em>this</em> gets escaped: <script>evil</script>";
  private static final String SANITIZED_HTML =
      "<em>this</em> gets escaped: &lt;script&gt;evil&lt;/script&gt;";
  private static final String STRING_WITH_B_TAG = "<b>text</b>";
  private static final String STRING_WITH_B_TAG_ESCAPED = "&lt;b&gt;text&lt;/b&gt;";

  @Override
  public String getModuleName() {
    return "com.google.gwt.i18n.I18NTest";
  }

  @SuppressWarnings("unchecked") // intentional test of raw map
  public void testAnnotatedConstants() {
    TestAnnotatedConstants c = GWT.create(TestAnnotatedConstants.class);
    assertEquals(14, c.fourteen());
    assertFalse(c.isFalse());
    assertTrue(c.isTrue());
    assertArrayEquals(new String[] {"String array with one string"},
        c.singleString());
    assertArrayEquals(new String[] {"One", "Two", "Three,Comma"},
        c.threeStrings());
    assertEquals("Properties value #s need quoting!", c.propertiesQuoting());
    Map<String, String> stringMap = c.stringMap();
    assertTrue(stringMap.containsKey("key1"));
    assertTrue(stringMap.containsKey("key2"));
    assertEquals("value1", stringMap.get("key1"));
    assertEquals("value2", stringMap.get("key2"));
    assertEquals(2, stringMap.size());
    stringMap = c.rawMap();
    assertTrue(stringMap.containsKey("key1"));
    assertTrue(stringMap.containsKey("key2"));
    assertEquals("value1", stringMap.get("key1"));
    assertEquals("value2", stringMap.get("key2"));
    assertEquals(2, stringMap.size());
    assertEquals("Test me", c.testMe());
    assertEquals(13.7f, c.thirteenPointSeven());
    assertEquals(3.14, c.threePointOneFour());
    assertEquals("Once more, with meaning", c.withMeaning());
  }

  public void testAnnotatedConstantsGenMD5() {
    TestAnnotatedConstantsGenMD5 c = GWT.create(TestAnnotatedConstantsGenMD5.class);
    assertEquals(14, c.fourteen());
    assertFalse(c.isFalse());
    assertTrue(c.isTrue());
    assertArrayEquals(new String[] {"String array with one string"},
        c.singleString());
    assertArrayEquals(new String[] {"One", "Two"}, c.twoStrings());
    Map<String, String> stringMap = c.stringMap();
    assertTrue(stringMap.containsKey("key1"));
    assertTrue(stringMap.containsKey("key2"));
    assertEquals("value1", stringMap.get("key1"));
    assertEquals("value2", stringMap.get("key2"));
    assertEquals(2, stringMap.size());
    assertEquals("Test me", c.testMe());
    assertEquals(13.7f, c.thirteenPointSeven());
    assertEquals(3.14, c.threePointOneFour());
    assertEquals("Once more, with meaning", c.withMeaning());
  }

  public void testAnnotatedMessages() {
    TestAnnotatedMessages m = GWT.create(TestAnnotatedMessages.class);
    assertEquals("Estay emay", m.basicText());
    assertEquals("Oncay oremay, ithway eaningmay", m.withMeaning());
    assertEquals("PL: One argument: one", m.oneArgument("one"));
    assertEquals("PL: One argument (where am I?), which is optional",
        m.optionalArgument("where am I?"));
    assertEquals("Two arguments, second and first, inverted",
        m.invertedArguments("first", "second")); // from default locale
    assertEquals("PL: Don't tell me I can't {quote things in braces}",
        m.quotedText());
    assertEquals("PL: This {0} would be an argument if not quoted",
        m.quotedArg());
    assertEquals("PL: Total is $11,305.01", m.currencyFormat(11305.01));
    assertEquals("PL: Default number format is 1,017.1",
        m.defaultNumberFormat(1017.1));
    @SuppressWarnings("deprecation")
    Date date = new Date(107, 11, 1, 12, 1, 2);
    assertEquals("PL: It is 12:01 on 2007 December 1, Saturday",
        m.getTimeDate(date));
    assertEquals("PL: 13 widgets", m.pluralWidgetsOther(13));
    assertEquals("Too many widgets to count (150) in pig-latin",
        m.pluralWidgetsOther(150));
    assertEquals("PL: A widget", m.pluralWidgetsOther(1));

    assertEquals("PL: A thingy", m.twoParamPlural("thingy", 1));
    assertEquals("PL: 42 thingies", m.twoParamPlural("thingies", 42));
    assertEquals("PL: Tons (249) of thingies", m.twoParamPlural("thingies", 249));
  }

  public void testAnnotatedMessagesAsSafeHtml() {
    // Duplicate of non-SafeHtml tests
    TestAnnotatedMessages m = GWT.create(TestAnnotatedMessages.class);
    assertEquals("Estay emay", m.basicTextAsSafeHtml().asString());
    assertEquals("Oncay oremay, ithway eaningmay", m.withMeaningAsSafeHtml().asString());
    assertEquals("PL: One argument: one", m.oneArgumentAsSafeHtml("one").asString());
    assertEquals("PL: One argument (where am I?), which is optional",
        m.optionalArgumentAsSafeHtml("where am I?").asString());
    assertEquals("Two arguments, second and first, inverted",
        m.invertedArgumentsAsSafeHtml("first", "second").asString()); // from default locale
    assertEquals("PL: Don't tell me I can't {quote things in braces}",
        m.quotedTextAsSafeHtml().asString());
    assertEquals("PL: This {0} would be an argument if not quoted",
        m.quotedArgAsSafeHtml().asString());
    assertEquals("PL: Total is $11,305.01",
        m.currencyFormatAsSafeHtml(11305.01).asString());
    assertEquals("PL: Default number format is 1,017.1",
        m.defaultNumberFormatAsSafeHtml(1017.1).asString());
    @SuppressWarnings("deprecation")
    Date date = new Date(107, 11, 1, 12, 1, 2);
    assertEquals("PL: It is 12:01 on 2007 December 1, Saturday",
        m.getTimeDateAsSafeHtml(date).asString());
    assertEquals("PL: 13 widgets", m.pluralWidgetsOtherAsSafeHtml(13).asString());
    assertEquals("Too many widgets to count (150) in pig-latin",
        m.pluralWidgetsOtherAsSafeHtml(150).asString());

    assertEquals("PL: A widget", m.pluralWidgetsOtherAsSafeHtml(1).asString());

    assertEquals("PL: A thingy",
        m.twoParamPluralAsSafeHtml("thingy", 1).asString());
    assertEquals("PL: 42 thingies",
        m.twoParamPluralAsSafeHtml("thingies", 42).asString());
    assertEquals("PL: Tons (249) of thingies",
        m.twoParamPluralAsSafeHtml("thingies", 249).asString());

    // Additional SafeHtml-specific tests
    assertEquals("PL: One argument: " + STRING_WITH_B_TAG_ESCAPED,
        m.oneArgumentAsSafeHtml(STRING_WITH_B_TAG).asString());
    assertEquals("PL: One argument: " + SANITIZED_HTML,
        m.oneArgumentAsSafeHtml(SimpleHtmlSanitizer.sanitizeHtml(HTML_TO_SANITIZE)).asString());
    assertEquals(
        "Two arguments, " + STRING_WITH_B_TAG_ESCAPED + " and " + SANITIZED_HTML + ", inverted",
        m.invertedArgumentsAsSafeHtml(
            SimpleHtmlSanitizer.sanitizeHtml(HTML_TO_SANITIZE),
            STRING_WITH_B_TAG).asString());

    assertEquals("PL: A " + STRING_WITH_B_TAG_ESCAPED,
        m.twoParamPluralAsSafeHtml(STRING_WITH_B_TAG, 1).asString());
    assertEquals("PL: 42 " + STRING_WITH_B_TAG_ESCAPED,
        m.twoParamPluralAsSafeHtml(STRING_WITH_B_TAG, 42).asString());
    assertEquals("PL: Tons (249) of " + STRING_WITH_B_TAG_ESCAPED,
        m.twoParamPluralAsSafeHtml(STRING_WITH_B_TAG, 249).asString());

    assertEquals("PL: A " + SANITIZED_HTML,
        m.twoParamPluralAsSafeHtml(
            SimpleHtmlSanitizer.sanitizeHtml(HTML_TO_SANITIZE), 1).asString());
    assertEquals("PL: 42 " + SANITIZED_HTML,
        m.twoParamPluralAsSafeHtml(
            SimpleHtmlSanitizer.sanitizeHtml(HTML_TO_SANITIZE), 42).asString());
    assertEquals("PL: Tons (249) of " + SANITIZED_HTML,
        m.twoParamPluralAsSafeHtml(
            SimpleHtmlSanitizer.sanitizeHtml(HTML_TO_SANITIZE), 249).asString());
  }

  public void testAnnotationInheritance() {
    TestAnnotationGrandchild m = GWT.create(TestAnnotationGrandchild.class);
    assertEquals("foo", m.foo());
    assertEquals("bar_piglatin", m.bar());
    assertEquals("baz_piglatin", m.baz());
  }

  public void testAnnotationInheritanceAsSafeHtml() {
    // Duplicate of non-SafeHtml tests
    TestAnnotationGrandchild m = GWT.create(TestAnnotationGrandchild.class);
    assertEquals("foo", m.fooAsSafeHtml().asString());
    assertEquals("bar_piglatin", m.barAsSafeHtml().asString());
    assertEquals("baz_piglatin", m.bazAsSafeHtml().asString());
  }

  public void testBindings() {
    TestBinding b = GWT.create(TestBinding.class);
    assertEquals("default", b.a());
    TestLeafBundle c = GWT.create(TestLeafBundle.class);
    assertEquals("TestLeafBundle_piglatin_UK_WINDOWS", c.b());
    com.google.gwt.i18n.client.Wrapper2.TestBindingImpl d = GWT.create(com.google.gwt.i18n.client.Wrapper2.TestBindingImpl.class);
    assertEquals("default", d.a());
  }

  public void testColors() {
    Colors colors = GWT.create(Colors.class);
    assertNotNull(colors);
    // No piglatin version exists for grey
    assertEquals("ĝréý", colors.grey());
    assertEquals("ackblay", colors.black());
    assertEquals("ueblay", colors.blue());
  }

  public void testColorsAndShapes() {
    ColorsAndShapes s = GWT.create(ColorsAndShapes.class);
    assertEquals("ueblay", s.blue());
    assertEquals("ĝréý", s.grey());
  }

  public void testConstantBooleans() {
    TestConstants types = GWT.create(TestConstants.class);
    assertEquals(false, types.booleanFalse());
    assertEquals(true, types.booleanTrue());
  }

  public void testConstantDoubles() {
    TestConstants types = GWT.create(TestConstants.class);
    double delta = 0.0000001;
    assertEquals(3.14159, types.doublePi(), delta);
    assertEquals(0.0, types.doubleZero(), delta);
    assertEquals(1.0, types.doubleOne(), delta);
    assertEquals(-1.0, types.doubleNegOne(), delta);
    assertEquals(Double.MAX_VALUE, types.doublePosMax(), delta);
    assertEquals(Double.MIN_VALUE, types.doublePosMin(), delta);
    assertEquals(-Double.MAX_VALUE, types.doubleNegMax(), delta);
    assertEquals(-Double.MIN_VALUE, types.doubleNegMin(), delta);
  }

  public void testConstantFloats() {
    TestConstants types = GWT.create(TestConstants.class);
    double delta = 0.0000001;
    assertEquals(3.14159f, types.floatPi(), delta);
    assertEquals(0.0f, types.floatZero(), delta);
    assertEquals(1.0f, types.floatOne(), delta);
    assertEquals(-1.0f, types.floatNegOne(), delta);
    assertEquals(Float.MAX_VALUE, types.floatPosMax(), delta);
    assertEquals(Float.MIN_VALUE, types.floatPosMin(), delta);
    assertEquals(-Float.MAX_VALUE, types.floatNegMax(), delta);
    assertEquals(-Float.MIN_VALUE, types.floatNegMin(), delta);
  }

  /**
   * Exercises ConstantMap more than the other map tests.
   */
  public void testConstantMapABCD() {
    TestConstants types = GWT.create(TestConstants.class);

    Map<String, String> map = types.mapABCD();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {
        "A", "B", "C", "D"});
    assertNull(map.get("bogus"));
    compareMapsComprehensively(map, expectedMap);

    /*
     * Test if the returned map can be modified in any way. Things are working
     * as expected if exceptions are thrown in each case.
     */
    String failureMessage = "Should have thrown UnsupportedOperationException";
    /* test map operations */
    try {
      map.remove("keyA");
      fail(failureMessage + " on map.remove");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.put("keyA", "allA");
      fail(failureMessage + "on map.put of existing key");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.put("keyZ", "allZ");
      fail(failureMessage + "on map.put of new key");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.clear();
      fail(failureMessage + " on map.clear");
    } catch (UnsupportedOperationException e) {
    }

    /* test map.keySet() operations */
    try {
      map.keySet().add("keyZ");
      fail(failureMessage + " on map.keySet().add");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.keySet().remove("keyA");
      fail(failureMessage + " on map.keySet().remove");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.keySet().clear();
      fail(failureMessage + " on map.keySet().clear");
    } catch (UnsupportedOperationException e) {
    }

    /* test map.values() operations */
    try {
      map.values().add("valueZ");
      fail(failureMessage + " on map.values().add");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.values().remove("valueA");
      fail(failureMessage + " on map.values().clear()");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.values().clear();
      fail(failureMessage + " on map.values().clear()");
    } catch (UnsupportedOperationException e) {
    }

    /* test map.entrySet() operations */
    Map.Entry<String, String> firstEntry = map.entrySet().iterator().next();
    try {
      map.entrySet().clear();
      fail(failureMessage + "on map.entrySet().clear");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.entrySet().remove(firstEntry);
      fail(failureMessage + " on map.entrySet().remove");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.entrySet().add(firstEntry);
      fail(failureMessage + "on map.entrySet().add");
    } catch (UnsupportedOperationException e) {
    }
    try {
      firstEntry.setValue("allZ");
      fail(failureMessage + "on firstEntry.setValue");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.clear();
      fail(failureMessage + " on map.clear");
    } catch (UnsupportedOperationException e) {
    }
  }

  /**
   * Tests exercise the cache.
   */
  public void testConstantMapBACD() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapBACD();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {
        "B", "A", "C", "D"});
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests exercise the cache.
   */
  public void testConstantMapBBB() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapBBB();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {"B"});
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests exercise the cache and check if Map works as the declared return
   * type.
   */
  @SuppressWarnings("unchecked")
  public void testConstantMapDCBA() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapDCBA();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {
        "D", "C", "B", "A"});
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests focus on correctness of entries, since ABCD exercises the map.
   */
  public void testConstantMapEmpty() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapEmpty();
    Map<String, String> expectedMap = new HashMap<String, String>();
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests exercise the cache and check if Map works as the declared return
   * type.
   */
  public void testConstantMapXYZ() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapXYZ();
    Map<String, String> expectedMap = new HashMap<String, String>();
    expectedMap.put("keyX", "valueZ");
    expectedMap.put("keyY", "valueZ");
    expectedMap.put("keyZ", "valueZ");
    compareMapsComprehensively(map, expectedMap);
  }

  public void testConstantStringArrays() {
    TestConstants types = GWT.create(TestConstants.class);
    String[] s;

    s = types.stringArrayABCDEFG();
    assertArrayEquals(new String[] {"A", "B", "C", "D", "E", "F", "G"}, s);

    s = types.stringArraySizeOneEmptyString();
    assertArrayEquals(new String[] {""}, s);

    s = types.stringArraySizeOneX();
    assertArrayEquals(new String[] {"X"}, s);

    s = types.stringArraySizeTwoBothEmpty();
    assertArrayEquals(new String[] {"", ""}, s);

    s = types.stringArraySizeThreeAllEmpty();
    assertArrayEquals(new String[] {"", "", ""}, s);

    s = types.stringArraySizeTwoWithEscapedComma();
    assertArrayEquals(new String[] {"X", ", Y"}, s);

    s = types.stringArraySizeOneWithBackslashX();
    assertArrayEquals(new String[] {"\\X"}, s);

    s = types.stringArraySizeThreeWithDoubleBackslash();
    assertArrayEquals(new String[] {"X", "\\", "Y"}, s);
  }

  public void testConstantStrings() {
    TestConstants types = GWT.create(TestConstants.class);
    assertEquals("string", types.getString());
    assertEquals("stringTrimsLeadingWhitespace",
        types.stringTrimsLeadingWhitespace());
    assertEquals("stringDoesNotTrimTrailingThreeSpaces   ",
        types.stringDoesNotTrimTrailingThreeSpaces());
    assertEquals("", types.stringEmpty());
    String jaBlue = types.stringJapaneseBlue();
    assertEquals("あお", jaBlue);
    String jaGreen = types.stringJapaneseGreen();
    assertEquals("みどり", jaGreen);
    String jaRed = types.stringJapaneseRed();
    assertEquals("あか", jaRed);
  }

  public void testConstantsWithLookup() {
    TestConstantsWithLookup l = GWT.create(TestConstantsWithLookup.class);
    Map<String, String> map = l.getMap("mapABCD");
    assertEquals("valueA", map.get("keyA"));
    map = l.getMap("mapDCBA");
    assertEquals("valueD", map.get("keyD"));
    assertEquals(l.mapABCD(), l.getMap("mapABCD"));
    assertEquals(l.mapDCBA(), l.getMap("mapDCBA"));
    assertEquals(l.mapBACD(), l.getMap("mapBACD"));
    assertEquals(l.getString(), l.getString("getString"));
    assertSame(l.stringArrayABCDEFG(), l.getStringArray("stringArrayABCDEFG"));
    assertEquals(l.booleanFalse(), l.getBoolean("booleanFalse"));
    assertEquals(l.floatPi(), l.getFloat("floatPi"), .001);
    assertEquals(l.doublePi(), l.getDouble("doublePi"), .001);
    try {
      // even though getString has the gwt.key "string", it is not the lookup
      // value
      l.getMap("string");
      fail("Should have thrown MissingResourceException");
    } catch (MissingResourceException e) {
      // success if the exception was caught
    }
  }

  public void testDictionary() {
    createDummyDictionaries();
    Dictionary d = Dictionary.getDictionary("testDic");
    assertEquals("3 {2},{2},{2}, one {0}, two {1} {1}",
        d.get("formattedMessage"));
    assertEquals("4", d.get("d"));
    Set<String> s = d.keySet();
    assertTrue(s.contains("a"));
    assertTrue(s.contains("b"));
    assertFalse(s.contains("c"));
    Collection<String> s2 = d.values();
    assertTrue(s2.contains("A"));
    assertTrue(s2.contains("B"));
    Iterator<String> iter = s2.iterator();
    assertEquals("3 {2},{2},{2}, one {0}, two {1} {1}", iter.next());
    assertEquals(4, s2.size());
    Dictionary empty = Dictionary.getDictionary("emptyDic");
    assertEquals(0, empty.keySet().size());
    boolean threwError = false;
    try {
      Dictionary.getDictionary("malformedDic");
    } catch (MissingResourceException e) {
      threwError = true;
    }
    assertTrue(threwError);
  }

  public void testIntConstant() {
    TestConstants types = GWT.create(TestConstants.class);
    assertEquals(0, types.intZero());
    assertEquals(1, types.intOne());
    assertEquals(-1, types.intNegOne());
    assertEquals(Integer.MAX_VALUE, types.intMax());
    assertEquals(Integer.MIN_VALUE, types.intMin());
  }

  public void testLocalizableInner() {
    // Check simple inner
    LocalizableSimpleInner s = GWT.create(Inners.LocalizableSimpleInner.class);
    assertEquals("getLocalizableInner", s.getLocalizableInner());

    LocalizableInnerInner localizableInnerInner = GWT.create(Inners.InnerClass.LocalizableInnerInner.class);
    assertEquals("localizableInnerInner", localizableInnerInner.string());

    // Check success of finding embedded
    OuterLoc lock = GWT.create(OuterLoc.class);
    assertEquals("piglatin", lock.string());

    assertEquals("InnerLoc", Inners.testInnerLoc());
  }

  public void testLocalizableInterfaceInner() {
    Inners inner = new Inners();

    // Simple Inner
    SimpleInner simpleInner = GWT.create(Inners.SimpleInner.class);
    assertEquals(0, simpleInner.intZero());
    assertEquals("Simple Inner", simpleInner.simpleInner());
    assertTrue(inner.testProtectedInner());

    // Has Inner
    HasInner hasInner = GWT.create(Inners.HasInner.class);
    assertEquals("Has Inner", hasInner.hasInner());
    assertEquals(0, hasInner.floatZero(), .0001);

    // Is Inner
    IsInner isInner = GWT.create(IsInner.class);
    assertEquals(2, isInner.isInner());

    // Inner Inner
    InnerInner innerInner = GWT.create(InnerInner.class);
    assertEquals(4.321, innerInner.innerInner(), .0001);
    assertEquals("outer", innerInner.outer());

    // Inner Inner Message
    InnerInnerMessages innerInnerMessages = GWT.create(InnerInnerMessages.class);
    assertEquals("I am a person",
        innerInnerMessages.innerClassMessages("person"));

    // Extends Inner Inner
    ExtendsInnerInner extendsInnerInner = GWT.create(ExtendsInnerInner.class);
    assertEquals("Extends Inner Inner", extendsInnerInner.extendsInnerInner());

    // Protected InnerClass
    InnerClass innerClass = new Inners.InnerClass();
    Map<String, String> extendsAnotherInner = innerClass.testExtendsAnotherInner();
    assertEquals("4.321", extendsAnotherInner.get("innerInner"));
    assertEquals("outer", extendsAnotherInner.get("outer"));

    // ExtendProtectedInner
    String extendProtectedInner = innerClass.testExtendsProtectedInner();
    assertEquals("Extend Protected Inner", extendProtectedInner);
  }

  public void testNestedAnnotations() {
    Nested m = GWT.create(Nested.class);
    // no translation exists in piglatin for nested dollar
    assertEquals("nested dollar", m.nestedDollar());
    assertEquals("estednay underscoray", m.nestedUnderscore());
  }

  public void testNestedAnnotationsAsSafeHtml() {
    // Duplicate of non-SafeHtml tests
    TestAnnotatedMessages.Nested m = GWT.create(TestAnnotatedMessages.Nested.class);
    // no translation exists in piglatin for nested dollar
    assertEquals("nested dollar", m.nestedDollarAsSafeHtml().asString());
    assertEquals("estednay underscoray", m.nestedUnderscoreAsSafeHtml().asString());
  }

  /**
   * Test that messages works with Number subclasses.
   */
  public void testNumber() {
    TestAnnotatedMessages m = GWT.create(TestAnnotatedMessages.class);
    BigInteger intVal = new BigInteger("1000000000000000000");
    assertEquals("Total is $1,000,000,000,000,000,000.00",
        m.withNumberCurrency(intVal));
    BigDecimal decVal = new BigDecimal("1000000000000000000.01");
    assertEquals("Total is $1,000,000,000,000,000,000.01",
        m.withNumberCurrency(decVal));
    assertEquals("Distance is 1.0E18", m.withNumberExponent(intVal));
    assertEquals("Distance is 100.0E6", m.withNumberExponent(1e8f));
  }

  public void testShapesFamily() {
    Shapes shapes = GWT.create(Shapes.class);
    // test overload
    assertEquals("aya irclecay", shapes.circle());
    ColorsAndShapesAndConcepts s = GWT.create(ColorsAndShapesAndConcepts.class);
    assertEquals("aya irclecay", s.circle());
    // test converge
    assertEquals("any primary color", s.shapeColor());
    assertEquals("trees", s.green());
    assertEquals("Îñţérñåţîöñåļîžåţîöñ", s.internationalization());
  }

  public void testSpecialPlurals() {
    TestAnnotatedMessages m = GWT.create(TestAnnotatedMessages.class);
    assertEquals("No widgets", m.specialPlurals(0));
    assertEquals("A widget", m.specialPlurals(1));
    assertEquals("2 widgets", m.specialPlurals(2));
  }

  public void testTestMessages() {
    TestMessages s = GWT.create(TestMessages.class);
    assertEquals("no args", s.args0());
    assertEquals("a,b,c,d,e,f,g,h,i,j", s.args10("a", "b", "c", "d", "e", "f",
        "g", "h", "i", "j"));
    String shouldHave = "x,y, \"a\",\"b\", \"x\", \"y\", \'a\', b, {0}, \'y\'";
    assertEquals(shouldHave, s.argsWithQuotes("x", "y"));
    assertEquals("repeatedArgs: a, b, a, b, a, b, a, b",
        s.testLotsOfUsageOfArgs("a", "b"));
    assertEquals("\"~\" ~~ \"~~~~ \"\"", s.testWithXs());
    assertEquals("お好你好好", s.unicode("好", "好"));
    assertEquals("", s.empty());
    assertEquals("{quoted}", s.quotedBraces());
  }

  public void testTestMessagesAsSafeHtml() {
    // Duplicate of non-SafeHtml tests
    TestMessages m = (TestMessages) GWT.create(TestMessages.class);
    assertEquals("no args", m.args0AsSafeHtml().asString());
    assertEquals("a,b,c,d,e,f,g,h,i,j", m.args10AsSafeHtml("a", "b", "c", "d", "e", "f",
        "g", "h", "i", "j").asString());
    String shouldHave = "x,y, \"a\",\"b\", \"x\", \"y\", \'a\', b, {0}, \'y\'";
    assertEquals(shouldHave, m.argsWithQuotesAsSafeHtml("x", "y").asString());
    assertEquals("repeatedArgs: a, b, a, b, a, b, a, b",
        m.testLotsOfUsageOfArgsAsSafeHtml("a", "b").asString());
    assertEquals("\"~\" ~~ \"~~~~ \"\"", m.testWithXsAsSafeHtml().asString());
    assertEquals("お好你好好", m.unicodeAsSafeHtml("好", "好").asString());
    assertEquals("", m.emptyAsSafeHtml().asString());
    assertEquals("{quoted}", m.quotedBracesAsSafeHtml().asString());
  }

  public void testTypedMessages() {
    TestTypedMessages typed = GWT.create(TestTypedMessages.class);
    String expected = "int(0) float(1.5), long(0), boolean(true), Object([], char(a), byte(127), short(-32768);";
    assertEquals(expected, typed.testAllTypes(0, (float) 1.5, 0, true,
        new ArrayList<String>(), 'a', Byte.MAX_VALUE, Short.MIN_VALUE));
    String lotsOfInts = typed.testLotsOfInts(1, 2, 3, 4);
    assertEquals("1, 2,3,4 ", lotsOfInts);
    String oneFloat = typed.simpleMessageTest((float) 2.25);
    assertEquals("2.25", oneFloat);
    String singleQuotes = typed.testSingleQuotes("arg");
    assertEquals("'A', 'arg', ','", singleQuotes);
    String testSomeObjectTypes = typed.testSomeObjectTypes(
        new TestObjectToString(), new StringBuffer("hello"), new Integer("34"),
        null);
    assertEquals("obj(TestObjectToString), StringBuffer(hello), "
        + "Integer(34), " + "null(null);", testSomeObjectTypes);
  }

  public void testTypedMessagesAsSafeHtml() {
    // Duplicate of non-SafeHtml tests
    TestTypedMessages m = (TestTypedMessages) GWT.create(TestTypedMessages.class);
    String expected = "int(0) float(1.5), long(0), boolean(true), Object([],"
        + " char(a), byte(127), short(-32768);";
    assertEquals(expected, m.testAllTypesAsSafeHtml(0, (float) 1.5, 0, true,
        new ArrayList<String>(), 'a', Byte.MAX_VALUE,
        Short.MIN_VALUE).asString());
    String lotsOfInts = m.testLotsOfIntsAsSafeHtml(1, 2, 3, 4).asString();
    assertEquals("1, 2,3,4 ", lotsOfInts);
    String oneFloat = m.simpleMessageTestAsSafeHtml((float) 2.25).asString();
    assertEquals("2.25", oneFloat);
    String singleQuotes = m.testSingleQuotesAsSafeHtml("arg").asString();
    assertEquals("'A', 'arg', ','", singleQuotes);
    String testSomeObjectTypes = m.testSomeObjectTypesAsSafeHtml(
        new TestObjectToString(), new StringBuffer("hello"), new Integer("34"),
        null).asString();
    assertEquals("obj(TestObjectToString), StringBuffer(hello), "
        + "Integer(34), null(null);",
      testSomeObjectTypes);

    // Additional SafeHtml-specific tests
    Object someObject = new Object() {
      @Override
      public String toString() {
        return STRING_WITH_B_TAG;
      }
    };
    testSomeObjectTypes = m.testSomeObjectTypesAsSafeHtml(
        new TestObjectToString(), new StringBuffer(STRING_WITH_B_TAG),
        new Integer("34"), someObject).asString();
    assertEquals("obj(TestObjectToString), StringBuffer("
        + STRING_WITH_B_TAG_ESCAPED + "), Integer(34), null("
        + STRING_WITH_B_TAG_ESCAPED + ");", testSomeObjectTypes);
  }

  private void assertArrayEquals(String[] shouldBe, String[] test) {
    assertEquals(shouldBe.length, test.length);
    for (int i = 0; i < test.length; i++) {
      assertEquals(shouldBe[i], test[i]);
    }
  }

  private <T> boolean compare(Collection<T> collection1,
      Collection<T> collection2) {
    if (collection1 == null) {
      return (collection2 == null);
    }
    if (collection2 == null) {
      return false;
    }
    if (collection1.size() != collection2.size()) {
      return false;
    }
    for (T element1 : collection1) {
      boolean found = false;
      for (T element2 : collection2) {
        if (element1.equals(element2)) {
          found = true;
          break;
        }
      }
      if (!found) {
        return false;
      }
    }
    return true;
  }

  // compare the map, entrySet, keySet, and values
  private void compareMapsComprehensively(Map<String, String> map,
      Map<String, String> expectedMap) {
    // checking both directions to verify that the equals implementation is
    // correct both ways
    assertEquals(expectedMap, map);
    assertEquals(map, expectedMap);
    assertEquals(expectedMap.entrySet(), map.entrySet());
    assertEquals(map.entrySet(), expectedMap.entrySet());
    assertEquals(expectedMap.keySet(), map.keySet());
    assertEquals(map.keySet(), expectedMap.keySet());
    assertTrue(compare(expectedMap.values(), map.values()));
    assertTrue(compare(map.values(), expectedMap.values()));
  }

  private native void createDummyDictionaries() /*-{
    $wnd.testDic = new Object();
    $wnd.testDic.formattedMessage = "3 {2},{2},{2}, one {0}, two {1} {1}";
    $wnd.testDic.a="A";
    $wnd.testDic.b="B";
    $wnd.testDic.d=4;
    $wnd.emptyDic = new Object();
    $wnd.malformedDic = 4;
  }-*/;

  private Map<String, String> getMapFromArrayUsingASimpleRule(String array[]) {
    Map<String, String> map = new HashMap<String, String>();
    for (String str : array) {
      map.put("key" + str, "value" + str);
    }
    return map;
  }
}
