Merge "Fix possible NPE"
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 3fba39d..245e685 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -190,7 +190,7 @@
     <string name="dictionary_downloading" msgid="2982650524622620983">"Hiện đang tải xuống"</string>
     <string name="dictionary_installed" msgid="8081558343559342962">"Đã cài đặt"</string>
     <string name="dictionary_disabled" msgid="8950383219564621762">"Đã cài đặt, bị tắt"</string>
-    <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Lỗi knối d.vụ t.điển"</string>
+    <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Lỗi kết nối DV từ điển"</string>
     <string name="no_dictionaries_available" msgid="8039920716566132611">"Không có từ điển nào"</string>
     <string name="check_for_updates_now" msgid="8087688440916388581">"Làm mới"</string>
     <string name="last_update" msgid="730467549913588780">"Cập nhật lần cuối"</string>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index fd9edec..9997ff4 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -301,8 +301,8 @@
             final int xmlId = mResources.getIdentifier(keyboardLayoutSetName, "xml", packageName);
             try {
                 parseKeyboardLayoutSet(mResources, xmlId);
-            } catch (Exception e) {
-                throw new RuntimeException(e.getMessage() + " in " + keyboardLayoutSetName);
+            } catch (final Exception e) {
+                throw new RuntimeException(e.getMessage() + " in " + keyboardLayoutSetName, e);
             }
             return new KeyboardLayoutSet(mContext, mParams);
         }
@@ -318,7 +318,7 @@
                         if (TAG_KEYBOARD_SET.equals(tag)) {
                             parseKeyboardLayoutSetContent(parser);
                         } else {
-                            throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
+                            throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD_SET);
                         }
                     }
                 }
@@ -336,14 +336,14 @@
                     if (TAG_ELEMENT.equals(tag)) {
                         parseKeyboardLayoutSetElement(parser);
                     } else {
-                        throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
+                        throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD_SET);
                     }
                 } else if (event == XmlPullParser.END_TAG) {
                     final String tag = parser.getName();
                     if (TAG_KEYBOARD_SET.equals(tag)) {
                         break;
                     } else {
-                        throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEYBOARD_SET);
+                        throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_KEYBOARD_SET);
                     }
                 }
             }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 8ae1b88..34f26bc 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -220,7 +220,7 @@
                     parseKeyboardContent(parser, false);
                     break;
                 } else {
-                    throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD);
+                    throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD);
                 }
             }
         }
@@ -321,7 +321,7 @@
                 } else if (TAG_KEY_STYLE.equals(tag)) {
                     parseKeyStyle(parser, skip);
                 } else {
-                    throw new XmlParseUtils.IllegalStartTag(parser, TAG_ROW);
+                    throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_ROW);
                 }
             } else if (event == XmlPullParser.END_TAG) {
                 final String tag = parser.getName();
@@ -333,7 +333,7 @@
                         || TAG_MERGE.equals(tag)) {
                     break;
                 } else {
-                    throw new XmlParseUtils.IllegalEndTag(parser, TAG_ROW);
+                    throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_ROW);
                 }
             }
         }
@@ -345,10 +345,10 @@
                 R.styleable.Keyboard);
         try {
             if (a.hasValue(R.styleable.Keyboard_horizontalGap)) {
-                throw new XmlParseUtils.IllegalAttribute(parser, "horizontalGap");
+                throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "horizontalGap");
             }
             if (a.hasValue(R.styleable.Keyboard_verticalGap)) {
-                throw new XmlParseUtils.IllegalAttribute(parser, "verticalGap");
+                throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "verticalGap");
             }
             return new KeyboardRow(mResources, mParams, parser, mCurrentY);
         } finally {
@@ -373,7 +373,7 @@
                 } else if (TAG_KEY_STYLE.equals(tag)) {
                     parseKeyStyle(parser, skip);
                 } else {
-                    throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY);
+                    throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_ROW);
                 }
             } else if (event == XmlPullParser.END_TAG) {
                 final String tag = parser.getName();
@@ -387,7 +387,7 @@
                         || TAG_MERGE.equals(tag)) {
                     break;
                 } else {
-                    throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
+                    throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_ROW);
                 }
             }
         }
@@ -548,7 +548,7 @@
                 } else if (TAG_DEFAULT.equals(tag)) {
                     selected |= parseDefault(parser, row, selected ? true : skip);
                 } else {
-                    throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY);
+                    throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_SWITCH);
                 }
             } else if (event == XmlPullParser.END_TAG) {
                 final String tag = parser.getName();
@@ -556,7 +556,7 @@
                     if (DEBUG) endTag("</%s>", TAG_SWITCH);
                     break;
                 } else {
-                    throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
+                    throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_SWITCH);
                 }
             }
         }
diff --git a/java/src/com/android/inputmethod/latin/XmlParseUtils.java b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
index f01d4c5..48e5ed3 100644
--- a/java/src/com/android/inputmethod/latin/XmlParseUtils.java
+++ b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
@@ -30,50 +30,53 @@
 
     @SuppressWarnings("serial")
     public static class ParseException extends XmlPullParserException {
-        public ParseException(String msg, XmlPullParser parser) {
+        public ParseException(final String msg, final XmlPullParser parser) {
             super(msg + " at " + parser.getPositionDescription());
         }
     }
 
     @SuppressWarnings("serial")
     public static final class IllegalStartTag extends ParseException {
-        public IllegalStartTag(XmlPullParser parser, String parent) {
-            super("Illegal start tag " + parser.getName() + " in " + parent, parser);
+        public IllegalStartTag(final XmlPullParser parser, final String tag, final String parent) {
+            super("Illegal start tag " + tag + " in " + parent, parser);
         }
     }
 
     @SuppressWarnings("serial")
     public static final class IllegalEndTag extends ParseException {
-        public IllegalEndTag(XmlPullParser parser, String parent) {
-            super("Illegal end tag " + parser.getName() + " in " + parent, parser);
+        public IllegalEndTag(final XmlPullParser parser, final String tag, final String parent) {
+            super("Illegal end tag " + tag + " in " + parent, parser);
         }
     }
 
     @SuppressWarnings("serial")
     public static final class IllegalAttribute extends ParseException {
-        public IllegalAttribute(XmlPullParser parser, String attribute) {
-            super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser);
+        public IllegalAttribute(final XmlPullParser parser, final String tag,
+                final String attribute) {
+            super("Tag " + tag + " has illegal attribute " + attribute, parser);
         }
     }
 
     @SuppressWarnings("serial")
     public static final class NonEmptyTag extends ParseException{
-        public NonEmptyTag(String tag, XmlPullParser parser) {
+        public NonEmptyTag(final XmlPullParser parser, final String tag) {
             super(tag + " must be empty tag", parser);
         }
     }
 
-    public static void checkEndTag(String tag, XmlPullParser parser)
+    public static void checkEndTag(final String tag, final XmlPullParser parser)
             throws XmlPullParserException, IOException {
         if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName()))
             return;
-        throw new NonEmptyTag(tag, parser);
+        throw new NonEmptyTag(parser, tag);
     }
 
-    public static void checkAttributeExists(TypedArray attr, int attrId, String attrName,
-            String tag, XmlPullParser parser) throws XmlPullParserException {
-        if (attr.hasValue(attrId))
+    public static void checkAttributeExists(final TypedArray attr, final int attrId,
+            final String attrName, final String tag, final XmlPullParser parser)
+                    throws XmlPullParserException {
+        if (attr.hasValue(attrId)) {
             return;
+        }
         throw new ParseException(
                 "No " + attrName + " attribute found in <" + tag + "/>", parser);
     }