Update libphonenumber to an unmodified copy of v7.0.1

Copied from upstream commit eb7f783d2fd7d222a10283a72d9e7 with no
local modifications and a cherry-pick of commit 5b00cb5b2dc0582c29
(JAVA/JS: Documentation fix and added missing licences.) from upstream
master.

Added Android.mk to build the code for platform and unbundled use.

Note that while we rename packages, we don't rename resources to make
sure they're found.

Change-Id: Idb886f1b5d7bca491b9f7f8d18574a88f08593ba
diff --git a/demo/README b/demo/README
new file mode 100644
index 0000000..29a46a1
--- /dev/null
+++ b/demo/README
@@ -0,0 +1,16 @@
+How to install the Appengine SDK to the Maven local repository?
+Note that this needs to be done only once.
+  $ mvn gae:unpack
+  Note that you don't need to manually download any SDK.
+
+How to generate the WAR?
+  $ mvn package
+  $ mvn war:war
+  Note that this must be done before running the webapp locally and before
+  deploying it to Appengine.
+
+How to run the webapp locally?
+  $ mvn gae:run
+
+How to deploy the webapp to Appengine?
+  $ mvn gae:update
diff --git a/demo/build.xml b/demo/build.xml
new file mode 100644
index 0000000..b9ed0cb
--- /dev/null
+++ b/demo/build.xml
@@ -0,0 +1,59 @@
+<project>
+  <property name="appengine-sdk.dir" location="../../appengine-java-sdk" />
+
+  <import file="${appengine-sdk.dir}/config/user/ant-macros.xml" />
+
+  <path id="project.classpath">
+    <pathelement path="war/WEB-INF/classes" />
+    <fileset dir="war/WEB-INF/lib">
+      <include name="**/*.jar" />
+    </fileset>
+    <fileset dir="${appengine-sdk.dir}/lib">
+      <include name="shared/**/*.jar" />
+    </fileset>
+  </path>
+
+  <target name="copyjars" description="Copies the App Engine JARs to the WAR.">
+    <copy todir="war/WEB-INF/lib" flatten="true">
+      <fileset dir="${appengine-sdk.dir}/lib/user">
+        <include name="**/*.jar" />
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="compile" depends="copyjars"
+          description="Compiles Java source and copies other source files to the WAR.">
+    <mkdir dir="war/WEB-INF/classes" />
+    <copy todir="war/WEB-INF/classes">
+      <fileset dir="src">
+        <exclude name="**/*.java" />
+      </fileset>
+    </copy>
+    <javac srcdir="src" destdir="war/WEB-INF/classes" classpathref="project.classpath" debug="on"
+           includeAntRuntime="false"/>
+  </target>
+
+  <target name="runserver" depends="compile" description="Starts the development server.">
+    <dev_appserver war="war" />
+  </target>
+
+  <target name="update" depends="compile" description="Uploads the application to App Engine.">
+    <appcfg action="update" war="war" />
+  </target>
+
+  <target name="rollback" depends="compile"
+          description="Rolls back an interrupted application update.">
+    <appcfg action="rollback" war="war" />
+  </target>
+
+  <target name="request_logs" description="Downloads log data from App Engine for the application.">
+    <appcfg action="request_logs" war="war">
+      <options>
+        <arg value="--num_days=5"/>
+      </options>
+      <args>
+        <arg value="logs.txt"/>
+      </args>
+    </appcfg>
+  </target>
+</project>
diff --git a/demo/pom.xml b/demo/pom.xml
new file mode 100644
index 0000000..63bc842
--- /dev/null
+++ b/demo/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>libphonenumber-parent</artifactId>
+    <groupId>com.googlecode.libphonenumber</groupId>
+    <version>7.0.1</version>
+  </parent>
+  <groupId>com.googlecode.libphonenumber</groupId>
+  <artifactId>demo</artifactId>
+  <version>7.0.1</version>
+
+  <properties>
+    <gae.version>1.5.4</gae.version>
+  </properties>
+
+  <repositories>
+    <repository>
+      <id>mvnrepository</id>
+      <url>http://mvnrepository.com/artifact/</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.5</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>1.3.2</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+      <version>1.2</version>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode.libphonenumber</groupId>
+      <artifactId>libphonenumber</artifactId>
+      <version>7.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode.libphonenumber</groupId>
+      <artifactId>geocoder</artifactId>
+      <version>2.18</version>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode.libphonenumber</groupId>
+      <artifactId>carrier</artifactId>
+      <version>1.8</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>net.kindleit</groupId>
+        <artifactId>maven-gae-plugin</artifactId>
+        <version>0.9.1</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>2.1.1</version>
+        <configuration>
+          <warSourceDirectory>war</warSourceDirectory>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.mortbay.jetty</groupId>
+        <artifactId>maven-jetty-plugin</artifactId>
+        <version>6.1.10</version>
+        <configuration>
+          <webAppSourceDirectory>webapp</webAppSourceDirectory>
+          <scanIntervalSeconds>10</scanIntervalSeconds>
+          <webAppConfig>
+            <contextPath>/</contextPath>
+          </webAppConfig>
+          <connectors>
+            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+              <port>8080</port>
+              <maxIdleTime>60000</maxIdleTime>
+            </connector>
+          </connectors>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java b/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java
new file mode 100644
index 0000000..4a329ba
--- /dev/null
+++ b/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2011 The Libphonenumber Authors
+ *
+ * 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.
+ *
+ * @author Shaopeng Jia
+ */
+
+package com.google.phonenumbers;
+
+import com.google.i18n.phonenumbers.AsYouTypeFormatter;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
+import com.google.i18n.phonenumbers.PhoneNumberToTimeZonesMapper;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
+
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.fileupload.util.Streams;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * A servlet that accepts requests that contain strings representing a phone number and a default
+ * country, and responds with results from parsing, validating and formatting the number. The
+ * default country is a two-letter region code representing the country that we are expecting the
+ * number to be from.
+ */
+@SuppressWarnings("serial")
+public class PhoneNumberParserServlet extends HttpServlet {
+  private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
+  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+    String phoneNumber = null;
+    String defaultCountry = null;
+    String languageCode = "en";  // Default languageCode to English if nothing is entered.
+    String regionCode = "";
+    String fileContents = null;
+    ServletFileUpload upload = new ServletFileUpload();
+    upload.setSizeMax(50000);
+    try {
+      FileItemIterator iterator = upload.getItemIterator(req);
+      while (iterator.hasNext()) {
+        FileItemStream item = iterator.next();
+        InputStream in = item.openStream();
+        if (item.isFormField()) {
+          String fieldName = item.getFieldName();
+          if (fieldName.equals("phoneNumber")) {
+            phoneNumber = Streams.asString(in, "UTF-8");
+          } else if (fieldName.equals("defaultCountry")) {
+            defaultCountry = Streams.asString(in).toUpperCase();
+          } else if (fieldName.equals("languageCode")) {
+            String languageEntered = Streams.asString(in).toLowerCase();
+            if (languageEntered.length() > 0) {
+              languageCode = languageEntered;
+            }
+          } else if (fieldName.equals("regionCode")) {
+            regionCode = Streams.asString(in).toUpperCase();
+          }
+        } else {
+          try {
+            fileContents = IOUtils.toString(in);
+          } finally {
+            IOUtils.closeQuietly(in);
+          }
+        }
+      }
+    } catch (FileUploadException e1) {
+      e1.printStackTrace();
+    }
+
+    StringBuilder output;
+    if (fileContents.length() == 0) {
+      output = getOutputForSingleNumber(phoneNumber, defaultCountry, languageCode, regionCode);
+      resp.setContentType("text/html");
+      resp.setCharacterEncoding("UTF-8");
+      resp.getWriter().println("<html><head>");
+      resp.getWriter().println(
+          "<link type=\"text/css\" rel=\"stylesheet\" href=\"/stylesheets/main.css\" />");
+      resp.getWriter().println("</head>");
+      resp.getWriter().println("<body>");
+      resp.getWriter().println("Phone Number entered: " + phoneNumber + "<br>");
+      resp.getWriter().println("defaultCountry entered: " + defaultCountry + "<br>");
+      resp.getWriter().println(
+          "Language entered: " + languageCode +
+              (regionCode.length() == 0 ? "" : " (" + regionCode + ")" + "<br>"));
+    } else {
+      output = getOutputForFile(defaultCountry, fileContents);
+      resp.setContentType("text/html");
+    }
+    resp.getWriter().println(output);
+    resp.getWriter().println("</body></html>");
+  }
+
+  private StringBuilder getOutputForFile(String defaultCountry, String fileContents) {
+    StringBuilder output = new StringBuilder();
+    output.append("<HTML><HEAD><TITLE>Results generated from phone numbers in the file provided:"
+        + "</TITLE></HEAD><BODY>");
+    output.append("<TABLE align=center border=1>");
+    output.append("<TH align=center>ID</TH>");
+    output.append("<TH align=center>Raw phone number</TH>");
+    output.append("<TH align=center>Pretty formatting</TH>");
+    output.append("<TH align=center>International format</TH>");
+
+    int phoneNumberId = 0;
+    StringTokenizer tokenizer = new StringTokenizer(fileContents, ",");
+    while (tokenizer.hasMoreTokens()) {
+      String numberStr = tokenizer.nextToken();
+      phoneNumberId++;
+      output.append("<TR>");
+      output.append("<TD align=center>").append(phoneNumberId).append(" </TD> \n");
+      output.append("<TD align=center>").append(numberStr).append(" </TD> \n");
+      try {
+        PhoneNumber number = phoneUtil.parseAndKeepRawInput(numberStr, defaultCountry);
+        boolean isNumberValid = phoneUtil.isValidNumber(number);
+        String prettyFormat = isNumberValid
+            ? phoneUtil.formatInOriginalFormat(number, defaultCountry)
+            : "invalid";
+        String internationalFormat = isNumberValid
+            ? phoneUtil.format(number, PhoneNumberFormat.INTERNATIONAL)
+            : "invalid";
+
+        output.append("<TD align=center>").append(prettyFormat).append(" </TD> \n");
+        output.append("<TD align=center>").append(internationalFormat).append(" </TD> \n");
+      } catch (NumberParseException e) {
+        output.append("<TD align=center colspan=2>").append(e.toString()).append(" </TD> \n");
+      }
+      output.append("</TR>");
+    }
+    output.append("</BODY></HTML>");
+    return output;
+  }
+
+  private void appendLine(String title, String data, StringBuilder output) {
+    output.append("<TR>");
+    output.append("<TH>").append(title).append("</TH>");
+    output.append("<TD>").append(data.length() > 0 ? data : "&nbsp;").append("</TD>");
+    output.append("</TR>");
+  }
+
+  /**
+   * The defaultCountry here is used for parsing phoneNumber. The languageCode and regionCode are
+   * used to specify the language used for displaying the area descriptions generated from phone
+   * number geocoding.
+   */
+  private StringBuilder getOutputForSingleNumber(
+      String phoneNumber, String defaultCountry, String languageCode, String regionCode) {
+    StringBuilder output = new StringBuilder();
+    try {
+      PhoneNumber number = phoneUtil.parseAndKeepRawInput(phoneNumber, defaultCountry);
+      output.append("<DIV>");
+      output.append("<TABLE border=1>");
+      output.append("<TR><TD colspan=2>Parsing Result</TD></TR>");
+
+      appendLine("country_code", Integer.toString(number.getCountryCode()), output);
+      appendLine("national_number", Long.toString(number.getNationalNumber()), output);
+      appendLine("extension", number.getExtension(), output);
+      appendLine("country_code_source", number.getCountryCodeSource().toString(), output);
+      appendLine("italian_leading_zero", Boolean.toString(number.isItalianLeadingZero()), output);
+      appendLine("raw_input", number.getRawInput(), output);
+      output.append("</TABLE>");
+      output.append("</DIV>");
+
+      boolean isPossible = phoneUtil.isPossibleNumber(number);
+      boolean isNumberValid = phoneUtil.isValidNumber(number);
+      PhoneNumberType numberType = phoneUtil.getNumberType(number);
+
+      output.append("<DIV>");
+      output.append("<TABLE border=1>");
+      output.append("<TR><TD colspan=2>Validation Results</TD></TR>");
+      appendLine("Result from isPossibleNumber()", Boolean.toString(isPossible), output);
+      if (!isPossible) {
+        appendLine("Result from isPossibleNumberWithReason()",
+                   phoneUtil.isPossibleNumberWithReason(number).toString(), output);
+        output.append("<TR><TD colspan=2>Note: numbers that are not possible have type " +
+                      "UNKNOWN, an unknown region, and are considered invalid.</TD></TR>");
+      } else {
+        appendLine("Result from isValidNumber()", Boolean.toString(isNumberValid), output);
+        if (isNumberValid) {
+          if (!defaultCountry.isEmpty() && defaultCountry != "ZZ") {
+            appendLine(
+                "Result from isValidNumberForRegion()",
+                Boolean.toString(phoneUtil.isValidNumberForRegion(number, defaultCountry)),
+                output);
+          }
+        }
+        String region = phoneUtil.getRegionCodeForNumber(number);
+        appendLine("Phone Number region", region == null ? "" : region, output);
+        appendLine("Result from getNumberType()", numberType.toString(), output);
+      }
+      output.append("</TABLE>");
+      output.append("</DIV>");
+
+      output.append("<DIV>");
+      output.append("<TABLE border=1>");
+      output.append("<TR><TD colspan=2>Formatting Results</TD></TR>");
+      appendLine("E164 format",
+                 isNumberValid ? phoneUtil.format(number, PhoneNumberFormat.E164) : "invalid",
+                 output);
+      appendLine("Original format",
+                 phoneUtil.formatInOriginalFormat(number, defaultCountry), output);
+      appendLine("National format", phoneUtil.format(number, PhoneNumberFormat.NATIONAL), output);
+      appendLine(
+          "International format",
+          isNumberValid ? phoneUtil.format(number, PhoneNumberFormat.INTERNATIONAL) : "invalid",
+          output);
+      appendLine(
+          "Out-of-country format from US",
+          isNumberValid ? phoneUtil.formatOutOfCountryCallingNumber(number, "US") : "invalid",
+          output);
+      appendLine(
+          "Out-of-country format from CH",
+          isNumberValid ? phoneUtil.formatOutOfCountryCallingNumber(number, "CH") : "invalid",
+          output);
+      output.append("</TABLE>");
+      output.append("</DIV>");
+
+      AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(defaultCountry);
+      int rawNumberLength = phoneNumber.length();
+      output.append("<DIV>");
+      output.append("<TABLE border=1>");
+      output.append("<TR><TD colspan=2>AsYouTypeFormatter Results</TD></TR>");
+      for (int i = 0; i < rawNumberLength; i++) {
+        // Note this doesn't handle supplementary characters, but it shouldn't be a big deal as
+        // there are no dial-pad characters in the supplementary range.
+        char inputChar = phoneNumber.charAt(i);
+        appendLine("Char entered: '" + inputChar + "' Output: ",
+                   formatter.inputDigit(inputChar), output);
+      }
+      output.append("</TABLE>");
+      output.append("</DIV>");
+
+      if (isNumberValid) {
+        output.append("<DIV>");
+        output.append("<TABLE border=1>");
+        output.append("<TR><TD colspan=2>PhoneNumberOfflineGeocoder Results</TD></TR>");
+        appendLine(
+            "Location",
+            PhoneNumberOfflineGeocoder.getInstance().getDescriptionForNumber(
+                number, new Locale(languageCode, regionCode)),
+            output);
+        output.append("</TABLE>");
+        output.append("</DIV>");
+
+        output.append("<DIV>");
+        output.append("<TABLE border=1>");
+        output.append("<TR><TD colspan=2>PhoneNumberToTimeZonesMapper Results</TD></TR>");
+        appendLine(
+            "Time zone(s)",
+            PhoneNumberToTimeZonesMapper.getInstance().getTimeZonesForNumber(number).toString(),
+            output);
+        output.append("</TABLE>");
+        output.append("</DIV>");
+
+        if (numberType == PhoneNumberType.MOBILE ||
+            numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE ||
+            numberType == PhoneNumberType.PAGER) {
+          output.append("<DIV>");
+          output.append("<TABLE border=1>");
+          output.append("<TR><TD colspan=2>PhoneNumberToCarrierMapper Results</TD></TR>");
+          appendLine(
+              "Carrier",
+              PhoneNumberToCarrierMapper.getInstance().getNameForNumber(
+                  number, new Locale(languageCode, regionCode)),
+              output);
+          output.append("</TABLE>");
+          output.append("</DIV>");
+        }
+      }
+    } catch (NumberParseException e) {
+      output.append(e.toString());
+    }
+    return output;
+  }
+}
diff --git a/demo/war/WEB-INF/appengine-web.xml b/demo/war/WEB-INF/appengine-web.xml
new file mode 100644
index 0000000..9a56cfa
--- /dev/null
+++ b/demo/war/WEB-INF/appengine-web.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+  <application>libphonenumber</application>
+  <version>1</version>
+  <threadsafe>true</threadsafe>
+
+  <!-- Configure java.util.logging -->
+  <system-properties>
+    <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
+  </system-properties>
+</appengine-web-app>
diff --git a/demo/war/WEB-INF/lib/commons-fileupload-1.2.1.jar b/demo/war/WEB-INF/lib/commons-fileupload-1.2.1.jar
new file mode 100644
index 0000000..aa209b3
--- /dev/null
+++ b/demo/war/WEB-INF/lib/commons-fileupload-1.2.1.jar
Binary files differ
diff --git a/demo/war/WEB-INF/lib/commons-io-1.4.jar b/demo/war/WEB-INF/lib/commons-io-1.4.jar
new file mode 100644
index 0000000..133dc6c
--- /dev/null
+++ b/demo/war/WEB-INF/lib/commons-io-1.4.jar
Binary files differ
diff --git a/demo/war/WEB-INF/logging.properties b/demo/war/WEB-INF/logging.properties
new file mode 100644
index 0000000..a172066
--- /dev/null
+++ b/demo/war/WEB-INF/logging.properties
@@ -0,0 +1,13 @@
+# A default java.util.logging configuration.
+# (All App Engine logging is through java.util.logging by default).
+#
+# To use this configuration, copy it into your application's WEB-INF
+# folder and add the following to your appengine-web.xml:
+# 
+# <system-properties>
+#   <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
+# </system-properties>
+#
+
+# Set the default logging level for all loggers to WARNING
+.level = WARNING
diff --git a/demo/war/WEB-INF/web.xml b/demo/war/WEB-INF/web.xml
new file mode 100644
index 0000000..5a4ba5c
--- /dev/null
+++ b/demo/war/WEB-INF/web.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns="http://java.sun.com/xml/ns/javaee"
+  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+  <servlet>
+    <servlet-name>PhoneNumberParser</servlet-name>
+    <servlet-class>com.google.phonenumbers.PhoneNumberParserServlet</servlet-class>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>PhoneNumberParser</servlet-name>
+    <url-pattern>/phonenumberparser</url-pattern>
+  </servlet-mapping>
+  <welcome-file-list>
+    <welcome-file>phonenumberparser.jsp</welcome-file>
+  </welcome-file-list>
+</web-app>
diff --git a/demo/war/favicon.ico b/demo/war/favicon.ico
new file mode 100644
index 0000000..789f24f
--- /dev/null
+++ b/demo/war/favicon.ico
Binary files differ
diff --git a/demo/war/phonenumberparser.jsp b/demo/war/phonenumberparser.jsp
new file mode 100644
index 0000000..e40ca55
--- /dev/null
+++ b/demo/war/phonenumberparser.jsp
@@ -0,0 +1,39 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<html>
+  <head>
+    <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
+  </head>
+  <body>
+    <h2>Phone Number Parser Demo</h2>
+    <form action="/phonenumberparser" method="post" accept-charset="UTF-8"
+          enctype="multipart/form-data">
+      <h2>Step 1</h2>
+      <p>
+      Specify a Phone Number: <input type="text" name="phoneNumber" size="25">
+      <p>
+      <b>Or</b> Upload a file containing phone numbers separated by comma.
+      <p>
+      <input type="file" name="numberFile" size="30">
+      <p>
+      <h2>Step 2</h2>
+      <p>
+      Specify a Default Country:
+      <input type="text" name="defaultCountry" size="2">
+          (<a href="http://www.iso.org/iso/english_country_names_and_code_elements">
+          ISO 3166-1 two-letter country code</a>)
+      <h2>Step 3</h2>
+      <p>
+      Specify a locale for phone number geocoding (Optional, defaults to en):
+      <p>
+      <input type="text" name="languageCode" size="2">-<input type="text" name="regionCode"
+                                                              size="2">
+          (<a href="http://download.oracle.com/javase/6/docs/api/java/util/Locale.html">A valid ISO
+              Language Code and optionally a region to more precisely define the language.</a>)
+      <p></p>
+      <input type="submit" value="Submit">
+      <input type="reset" value="Reset">
+      <p></p>
+      <a href="http://code.google.com/p/libphonenumber/">Back to libphonenumber</a>
+    </form>
+  </body>
+</html>
diff --git a/demo/war/stylesheets/main.css b/demo/war/stylesheets/main.css
new file mode 100644
index 0000000..80b8361
--- /dev/null
+++ b/demo/war/stylesheets/main.css
@@ -0,0 +1,26 @@
+body {
+  font-family: "Trebuchet MS", Arial, sans-serif;
+}
+table, th, td {
+  border: 1px solid #D4E0EE;
+  border-collapse: collapse;
+  color: #555;
+}
+
+td, th {
+  padding: 4px;
+}
+
+thead {
+  text-align: center;
+  background: #E6EDF5;
+  color: #4F76A3
+}
+
+th {
+  text-align: left;
+}
+
+div {
+  padding: 10px;
+}