App Engine Python SDK version 1.9.13

git-svn-id: http://googleappengine.googlecode.com/svn/trunk/python@480 80f5ef21-4148-0410-bacc-cfb02402ada8
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 850c48f..3d9c59c 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -3,8 +3,25 @@
 
 App Engine SDK - Release Notes
 
+Version 1.9.13
+
+- No changes for 1.9.13
+
+
 Version 1.9.12
+
+Python
 ==============================
+- The libxslt library has been updated from v1.1.22 to v1.1.28
+- Fixed an issue with NDB where a user gets an error stating "_AugmentedQuery'
+  object has no attribute '_filter_predicate'" when running a query without a
+  filter predicate.
+
+PHP
+==============================
+- Fixed an issue where users are unable to read newly created files in Google
+  Cloud Storage.
+    https://code.google.com/p/googleappengine/issues/detail?id=10869
 
 Version 1.9.11
 
diff --git a/VERSION b/VERSION
index 8d39520..bd34a5a 100644
--- a/VERSION
+++ b/VERSION
@@ -1,5 +1,5 @@
-release: "1.9.12"
-timestamp: 1410473495
+release: "1.9.13"
+timestamp: 1411710077
 api_versions: ['1']
 supported_api_versions:
   python:
diff --git a/google/appengine/api/logservice/logservice_stub.py b/google/appengine/api/logservice/logservice_stub.py
index ecfce0a..b44d27e 100644
--- a/google/appengine/api/logservice/logservice_stub.py
+++ b/google/appengine/api/logservice/logservice_stub.py
@@ -351,8 +351,13 @@
       values += module_values
 
     if request.has_offset():
-      filters.append('RequestLogs.id < ?')
-      values.append(int(request.offset().request_id()))
+      try:
+        filters.append('RequestLogs.id < ?')
+        values.append(int(request.offset().request_id()))
+      except ValueError:
+        logging.error('Bad offset in log request: "%s"', request.offset())
+        raise apiproxy_errors.ApplicationError(
+            log_service_pb.LogServiceError.INVALID_REQUEST)
     if request.has_minimum_log_level():
       filters.append('AppLogs.level >= ?')
       values.append(request.minimum_log_level())
diff --git a/google/appengine/api/yaml_errors.py b/google/appengine/api/yaml_errors.py
index 4299ff9..9afd3a9 100644
--- a/google/appengine/api/yaml_errors.py
+++ b/google/appengine/api/yaml_errors.py
@@ -38,6 +38,10 @@
   """Tried to load configuration file with multiple objects."""
 
 
+class AmbiguousConfigurationFiles(Error):
+  """Both YAML and XML files exist for the same configuration information."""
+
+
 class UnexpectedAttribute(Error):
   """Raised when an unexpected attribute is encounted."""
 
diff --git a/google/appengine/client/services/port_manager.py b/google/appengine/client/services/port_manager.py
index e920825..3ed1bda 100644
--- a/google/appengine/client/services/port_manager.py
+++ b/google/appengine/client/services/port_manager.py
@@ -33,6 +33,9 @@
                          10001,  # Nanny stubby proxy endpoint
                         ]
 
+DEFAULT_CONTAINER_PORT = 8080
+VM_PORT_FOR_CONTAINER = 8080
+
 
 class InconsistentPortConfigurationError(vme_errors.PermanentAppError):
   """The port is already in use."""
@@ -44,17 +47,18 @@
   pass
 
 
-def CreatePortManager(forwarded_ports):
+def CreatePortManager(forwarded_ports, container_port):
   """Construct a PortManager object with port forwarding configured.
 
   Args:
     forwarded_ports: A dictionary containing desired mappings from VM host port
         to docker container port.
+    container_port: An integer port number for the container port.
 
   Returns:
     The PortManager instance.
   """
-  port_manager_obj = PortManager()
+  port_manager_obj = PortManager(container_port)
   ports_list = forwarded_ports if forwarded_ports else []
   logging.debug('setting forwarded ports %s', ports_list)
   port_manager_obj.Add(ports_list, 'forwarded')
@@ -64,9 +68,10 @@
 class PortManager(object):
   """A helper class for VmManager to deal with port mappings."""
 
-  def __init__(self):
+  def __init__(self, container_port=DEFAULT_CONTAINER_PORT):
     self.used_host_ports = {}
-    self.port_mappings = {}
+    self._port_mappings = {}
+    self.container_port = container_port
 
   def Add(self, ports, kind):
     """Load port configurations and adds them to an internal dict.
@@ -127,7 +132,7 @@
             'Failed to load %s port configuration: "%s" error: "%s"'
             % (kind, port, e))
     # At this point we know they are not destructive.
-    self.port_mappings.update(port_translations)
+    self._port_mappings.update(port_translations)
     return port_translations
 
   def GetAllMappedPorts(self):
@@ -136,4 +141,38 @@
     Returns:
       A dict of port mappings {host: docker}
     """
-    return self.port_mappings
+    if not self._port_mappings:
+      return {}
+    else:
+      return self._port_mappings
+
+  # TODO: look into moving this into a DockerManager.
+  def _BuildDockerPublishArgumentString(self):
+    """Generates a string of ports to expose to the Docker container.
+
+    Returns:
+      A string with --publish=host:docker pairs.
+    """
+    port_map = self.GetAllMappedPorts()
+    # Map container port to port 8080 on the VM (default to 8080 if not set)
+    port_map[VM_PORT_FOR_CONTAINER] = int(self.container_port)
+    result = ''
+    for k, v in port_map.iteritems():
+      result += '--publish=%d:%s ' % (k, v)
+    return result
+
+  def GetReplicaPoolParameters(self):
+    """Returns the contribution to the replica template."""
+    publish_ports = self._BuildDockerPublishArgumentString()
+    maps = {
+        'template': {
+            'vmParams': {
+                'metadata': {
+                    'items': [
+                        {'key': 'gae_publish_ports', 'value': publish_ports}
+                        ]
+                    }
+                }
+            }
+        }
+    return maps
diff --git a/google/appengine/client/services/vme_errors.py b/google/appengine/client/services/vme_errors.py
index 7193551..9d4644b 100644
--- a/google/appengine/client/services/vme_errors.py
+++ b/google/appengine/client/services/vme_errors.py
@@ -84,6 +84,14 @@
         'nor admin_config.default_bigstore_bucket is set. Deployment aborted.')
 
 
+class InvalidUserInstallItem(PermanentAppError):
+  """Thrown if one of the apt_get_install items is invalid."""
+
+  def __init__(self, bad_package):
+    msg = 'Invalid apt-get-install package in vm_settings:"%s"' % bad_package
+    PermanentAppError.__init__(self, msg)
+
+
 class InvalidScopeConfigurationError(PermanentAppError):
   """Thrown if there are incompatible storage scopes in vm_settings."""
 
diff --git a/google/appengine/datastore/datastore_index.py b/google/appengine/datastore/datastore_index.py
index fbfd8d8..7daa43d 100644
--- a/google/appengine/datastore/datastore_index.py
+++ b/google/appengine/datastore/datastore_index.py
@@ -16,8 +16,6 @@
 #
 
 
-
-
 """Primitives for dealing with datastore indexes.
 
 Example index.yaml file:
@@ -49,6 +47,8 @@
 
 - kind: Mountain
   properties:
+  - name: name
+    mode: segment
   - name: location
     mode: geospatial
 """
@@ -87,7 +87,7 @@
   Attributes:
     name: Name of attribute to sort by.
     direction: Direction of sort.
-    mode: How the property is indexed. Either 'geospatial'
+    mode: How the property is indexed. Either 'geospatial', 'segment'
         or None (unspecified).
   """
 
@@ -96,8 +96,8 @@
       'direction': validation.Options(('asc', ('ascending',)),
                                       ('desc', ('descending',)),
                                       default='asc'),
-      'mode': validation.Optional(['geospatial']),
-      }
+      'mode': validation.Optional(['geospatial', 'segment']),
+  }
 
   def __init__(self, **attributes):
 
@@ -112,9 +112,10 @@
     return self.direction != 'desc'
 
   def CheckInitialized(self):
-    if 'direction' in self._is_set and self.mode == 'geospatial':
-      raise validation.ValidationError('Direction on a geospatial-mode '
-                                       'property is not allowed.')
+    if ('direction' in self._is_set and
+        self.mode in ['geospatial', 'segment']):
+      raise validation.ValidationError('Direction on a %s-mode '
+                                       'property is not allowed.' % self.mode)
 
 
 def _PropertyPresenter(dumper, prop):
@@ -162,7 +163,7 @@
       'kind': validation.Type(str, convert=False),
       'ancestor': validation.Type(bool, convert=False, default=False),
       'properties': validation.Optional(validation.Repeated(Property)),
-      }
+  }
 
 
 class IndexDefinitions(validation.Validated):
@@ -175,7 +176,7 @@
   ATTRIBUTES = {
       appinfo.APPLICATION: validation.Optional(appinfo.APPLICATION_RE_STRING),
       'indexes': validation.Optional(validation.Repeated(Index)),
-      }
+  }
 
 
 def ParseIndexDefinitions(document, open_fn=None):
@@ -263,15 +264,12 @@
 DESCENDING = datastore_pb.Query_Order.DESCENDING
 
 
-EQUALITY_OPERATORS = set((datastore_pb.Query_Filter.EQUAL,
-                          ))
-INEQUALITY_OPERATORS = set((datastore_pb.Query_Filter.LESS_THAN,
+EQUALITY_OPERATORS = set([datastore_pb.Query_Filter.EQUAL])
+INEQUALITY_OPERATORS = set([datastore_pb.Query_Filter.LESS_THAN,
                             datastore_pb.Query_Filter.LESS_THAN_OR_EQUAL,
                             datastore_pb.Query_Filter.GREATER_THAN,
-                            datastore_pb.Query_Filter.GREATER_THAN_OR_EQUAL,
-                            ))
-EXISTS_OPERATORS = set((datastore_pb.Query_Filter.EXISTS,
-                        ))
+                            datastore_pb.Query_Filter.GREATER_THAN_OR_EQUAL])
+EXISTS_OPERATORS = set([datastore_pb.Query_Filter.EXISTS])
 
 
 def Normalize(filters, orders, exists):
@@ -384,7 +382,6 @@
       return (filters, orders)
 
 
-
   has_key_desc_order = False
   if orders and orders[-1].property() == datastore_types.KEY_SPECIAL_PROPERTY:
     if orders[-1].direction() == ASCENDING:
@@ -403,7 +400,8 @@
           f.property(0).name() != datastore_types.KEY_SPECIAL_PROPERTY):
         break
     else:
-      filters = [f for f in filters
+      filters = [
+          f for f in filters
           if f.property(0).name() != datastore_types.KEY_SPECIAL_PROPERTY]
 
   return (filters, orders)
@@ -763,6 +761,10 @@
   return False, kind, minimal_ancestor, props
 
 
+
+
+
+
 def IndexYamlForQuery(kind, ancestor, props):
   """Return the composite index definition YAML needed for a query.
 
@@ -815,12 +817,12 @@
 
 
   serialized_xml = []
-  serialized_xml.append('<datastore-index kind="%s" ancestor="%s">'
+  serialized_xml.append('  <datastore-index kind="%s" ancestor="%s">'
                         % (kind, 'true' if ancestor else 'false'))
   for name, direction in props:
-    serialized_xml.append('  <property name="%s" direction="%s" />'
+    serialized_xml.append('    <property name="%s" direction="%s" />'
                           % (name, 'asc' if direction == ASCENDING else 'desc'))
-  serialized_xml.append('</datastore-index>')
+  serialized_xml.append('  </datastore-index>')
   return '\n'.join(serialized_xml)
 
 
@@ -852,6 +854,8 @@
 
       if prop.mode == 'geospatial':
         prop_proto.set_mode(entity_pb.Index_Property.GEOSPATIAL)
+      elif prop.mode == 'segment':
+        prop_proto.set_mode(entity_pb.Index_Property.SEGMENT)
       elif prop.IsAscending():
         prop_proto.set_direction(entity_pb.Index_Property.ASCENDING)
       else:
@@ -891,6 +895,8 @@
 
     if prop_proto.mode() == entity_pb.Index_Property.GEOSPATIAL:
       prop_definition.mode = 'geospatial'
+    elif prop_proto.mode() == entity_pb.Index_Property.SEGMENT:
+      prop_definition.mode = 'segment'
     elif prop_proto.direction() == entity_pb.Index_Property.DESCENDING:
       prop_definition.direction = 'desc'
     elif prop_proto.direction() == entity_pb.Index_Property.ASCENDING:
diff --git a/google/appengine/datastore/datastore_index_xml.py b/google/appengine/datastore/datastore_index_xml.py
new file mode 100644
index 0000000..40d03dd
--- /dev/null
+++ b/google/appengine/datastore/datastore_index_xml.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+"""Directly processes text of datastore-indexes.xml.
+
+IndexesXmlParser is called with an XML string to produce an IndexXml object
+containing the data from the XML.
+
+IndexesXmlParser: converts XML to Index object.
+Index: describes a single index specified in datastore-indexes.xml
+"""
+
+from xml.etree import ElementTree
+
+from google.appengine.api.validation import ValidationError
+from google.appengine.datastore.datastore_index import Index
+from google.appengine.datastore.datastore_index import IndexDefinitions
+from google.appengine.datastore.datastore_index import Property
+
+MISSING_KIND = '<datastore-index> node has missing attribute "kind".'
+BAD_DIRECTION = ('<property> tag attribute "direction" must have value "asc"'
+                 ' or "desc", given "%s"')
+NAME_MISSING = ('<datastore-index> node with kind "%s" needs to have a name'
+                ' attribute specified for its <property> node')
+
+
+def IndexesXmlToIndexDefinitions(xml_str):
+  """Convert a <datastore-indexes> XML string into an IndexDefinitions objects.
+
+  Args:
+    xml_str: a string containing a complete XML document where the root node is
+      <datastore-indexes>.
+
+  Returns:
+    an IndexDefinitions object parsed out of the XML string.
+
+  Raises:
+    ValidationError: in case of malformed XML or illegal inputs.
+  """
+  parser = IndexesXmlParser()
+  return parser.Parse(xml_str)
+
+
+def IsAutoGenerated(xml_str):
+  """Test if the given datastore-indexes.xml string implies auto-generation."""
+  try:
+    xml_root = ElementTree.fromstring(xml_str)
+    return (xml_root.tag == 'datastore-indexes' and
+            _BooleanAttribute(xml_root.attrib.get('autoGenerate', 'false')))
+  except ElementTree.ParseError:
+    return False
+
+
+class IndexesXmlParser(object):
+  """Provides logic for walking down XML tree and pulling data."""
+
+  def Parse(self, xml_str):
+    """Parses XML string and returns object representation of relevant info.
+
+    Args:
+      xml_str: The XML string.
+    Returns:
+      An IndexDefinitions object containing the result of parsing the XML.
+    Raises:
+      ValidationError: In case of malformed XML or illegal inputs.
+    """
+
+    try:
+      self.indexes = []
+      self.errors = []
+      xml_root = ElementTree.fromstring(xml_str)
+      if xml_root.tag != 'datastore-indexes':
+        raise ValidationError('Root tag must be <datastore-indexes>')
+
+      for child in xml_root.getchildren():
+        self.ProcessIndexNode(child)
+
+      if self.errors:
+        raise ValidationError('\n'.join(self.errors))
+
+      return IndexDefinitions(indexes=self.indexes)
+    except ElementTree.ParseError, e:
+      raise ValidationError('Bad input -- not valid XML: %s' % e)
+
+  def ProcessIndexNode(self, node):
+    """Processes XML <datastore-index> nodes into Index objects.
+
+    The following information is parsed out:
+    kind: specifies the kind of entities to index.
+    ancestor: true if the index supports queries that filter by
+      ancestor-key to constraint results to a single entity group.
+    property: represents the entity properties to index, with a name
+      and direction attribute.
+
+    Args:
+      node: <datastore-index> XML node in datastore-indexes.xml.
+    """
+    if node.tag != 'datastore-index':
+      self.errors.append('Unrecognized node: <%s>' % node.tag)
+      return
+
+    index = Index()
+    index.kind = node.attrib.get('kind', '')
+    if not index.kind:
+      self.errors.append(MISSING_KIND)
+    ancestor = node.attrib.get('ancestor', 'false')
+    index.ancestor = _BooleanAttribute(ancestor)
+    if index.ancestor is None:
+      self.errors.append(
+          'Value for ancestor should be true or false, not "%s"' % ancestor)
+    properties = []
+    property_nodes = [n for n in node.getchildren() if n.tag == 'property']
+    for property_node in property_nodes:
+      name = property_node.attrib.get('name', '')
+      if not name:
+        self.errors.append(NAME_MISSING % index.kind)
+        continue
+
+      direction = property_node.attrib.get('direction', 'asc')
+      if direction not in ('asc', 'desc'):
+        self.errors.append(BAD_DIRECTION % direction)
+        continue
+      properties.append(Property(name=name, direction=direction))
+    index.properties = properties
+    self.indexes.append(index)
+
+
+def _BooleanAttribute(value):
+  """Parse the given attribute value as a Boolean value.
+
+  This follows the specification here:
+  http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/datatypes.html#boolean
+
+  Args:
+    value: the value to parse.
+
+  Returns:
+    True if the value parses as true, False if it parses as false, None if it
+    parses as neither.
+  """
+  if value in ['true', '1']:
+    return True
+  elif value in ['false', '0']:
+    return False
+  else:
+    return None
diff --git a/google/appengine/datastore/datastore_pbs.py b/google/appengine/datastore/datastore_pbs.py
index 87fe62a..323897f 100644
--- a/google/appengine/datastore/datastore_pbs.py
+++ b/google/appengine/datastore/datastore_pbs.py
@@ -443,6 +443,7 @@
       self.__v3_to_v4_user_entity(v3_property_value.uservalue(),
                                   v4_value.mutable_entity_value())
       v4_value.set_meaning(MEANING_PREDEFINED_ENTITY_USER)
+      v3_meaning = None
     else:
       pass
 
diff --git a/google/appengine/datastore/datastore_stub_index.py b/google/appengine/datastore/datastore_stub_index.py
index dda0810..e328bfd 100644
--- a/google/appengine/datastore/datastore_stub_index.py
+++ b/google/appengine/datastore/datastore_stub_index.py
@@ -20,6 +20,8 @@
 
 """Utilities for generating and updating index.yaml."""
 
+from __future__ import with_statement
+
 
 
 
@@ -30,12 +32,14 @@
            'IndexYamlUpdater',
           ]
 
-import os
 import logging
+import os
 
 from google.appengine.api import apiproxy_stub_map
+from google.appengine.api import validation
 from google.appengine.api import yaml_errors
 from google.appengine.datastore import datastore_index
+from google.appengine.datastore import datastore_index_xml
 
 import yaml
 
@@ -54,20 +58,25 @@
 '''
 
 
-def GenerateIndexFromHistory(query_history,
-                             all_indexes=None, manual_indexes=None):
-  """Generate most of the text for index.yaml from the query history.
+def GenerateIndexDictFromHistory(query_history,
+                                 all_indexes=None, manual_indexes=None):
+  """Generate a dict of automatic index entries from the query history.
 
   Args:
-    query_history: Query history, a dict mapping query
+    query_history: Query history, a dict mapping datastore_pb.Query to a count
+      of the number of times that query has been issued.
     all_indexes: Optional datastore_index.IndexDefinitions instance
       representing all the indexes found in the input file.  May be None.
     manual_indexes: Optional datastore_index.IndexDefinitions instance
       containing indexes for which we should not generate output.  May be None.
 
   Returns:
-    A string representation that can safely be appended to an existing
-    index.yaml file. Returns the empty string if it would generate no output.
+    A dict where each key is a tuple (kind, ancestor, properties) and the
+      corresponding value is a count of the number of times that query has been
+      issued. The dict contains no entries for keys that appear in manual_keys.
+      In the tuple, "properties" is itself a tuple of tuples, where each
+      contained tuple is (name, direction), with "name" being a string and
+      "direction" being datastore_index.ASCENDING or .DESCENDING.
   """
 
 
@@ -93,6 +102,28 @@
         else:
           indexes[key] = count
 
+  return indexes
+
+
+def GenerateIndexFromHistory(query_history,
+                             all_indexes=None, manual_indexes=None):
+  """Generate most of the text for index.yaml from the query history.
+
+  Args:
+    query_history: Query history, a dict mapping datastore_pb.Query to a count
+      of the number of times that query has been issued.
+    all_indexes: Optional datastore_index.IndexDefinitions instance
+      representing all the indexes found in the input file.  May be None.
+    manual_indexes: Optional datastore_index.IndexDefinitions instance
+      containing indexes for which we should not generate output.  May be None.
+
+  Returns:
+    A string representation that can safely be appended to an existing
+    index.yaml file. Returns the empty string if it would generate no output.
+  """
+  indexes = GenerateIndexDictFromHistory(
+      query_history, all_indexes, manual_indexes)
+
   if not indexes:
     return ''
 
@@ -100,7 +131,7 @@
 
 
   res = []
-  for (kind, ancestor, props), count in sorted(indexes.iteritems()):
+  for (kind, ancestor, props), _ in sorted(indexes.iteritems()):
 
     res.append('')
     res.append(datastore_index.IndexYamlForQuery(kind, ancestor, props))
@@ -130,6 +161,9 @@
     """
     self.root_path = root_path
 
+  def UpdateIndexConfig(self):
+    self.UpdateIndexYaml()
+
   def UpdateIndexYaml(self, openfile=open):
     """Update index.yaml.
 
@@ -277,3 +311,171 @@
     except os.error, err:
       logging.error('Can\'t stat index.yaml we just wrote: %s', err)
       self.index_yaml_mtime = None
+
+
+class DatastoreIndexesAutoXmlUpdater(object):
+  """Helper class for updating datastore-indexes-auto.xml.
+
+  This class maintains some state about the query history and the
+  datastore-indexes.xml and datastore-indexes-auto.xml files in order to
+  minimize the number of times datastore-indexes-auto.xml is rewritten.
+  """
+
+
+
+  auto_generated = True
+  datastore_indexes_xml = None
+  datastore_indexes_xml_mtime = None
+  datastore_indexes_auto_xml_mtime = None
+  last_history_size = 0
+
+  def __init__(self, root_path):
+    self.root_path = root_path
+
+  def UpdateIndexConfig(self):
+    self.UpdateDatastoreIndexesAutoXml()
+
+  def UpdateDatastoreIndexesAutoXml(self, openfile=open):
+    """Update datastore-indexes-auto.xml if appropriate."""
+
+
+
+
+    datastore_indexes_xml_file = os.path.join(
+        self.root_path, 'WEB-INF', 'datastore-indexes.xml')
+    try:
+      datastore_indexes_xml_mtime = os.path.getmtime(datastore_indexes_xml_file)
+    except os.error:
+      datastore_indexes_xml_mtime = None
+    if datastore_indexes_xml_mtime != self.datastore_indexes_xml_mtime:
+      self.datastore_indexes_xml_mtime = datastore_indexes_xml_mtime
+      if self.datastore_indexes_xml_mtime:
+        with openfile(datastore_indexes_xml_file) as f:
+          self.datastore_indexes_xml = f.read()
+          self.auto_generated = datastore_index_xml.IsAutoGenerated(
+              self.datastore_indexes_xml)
+      else:
+        self.auto_generated = True
+        self.datastore_indexes_xml = None
+
+    if not self.auto_generated:
+      logging.debug('Detected <datastore-indexes autoGenerated="false">,'
+                    ' will not update datastore-indexes-auto.xml')
+      return
+
+
+    datastore_stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
+    query_ci_history_len = datastore_stub._QueryCompositeIndexHistoryLength()
+    history_changed = (query_ci_history_len != self.last_history_size)
+    self.last_history_size = query_ci_history_len
+    if not history_changed:
+      logging.debug('No need to update datastore-indexes-auto.xml')
+      return
+
+    datastore_indexes_auto_xml_file = os.path.join(
+        self.root_path, 'WEB-INF', 'appengine-generated',
+        'datastore-indexes-auto.xml')
+    try:
+      with open(datastore_indexes_auto_xml_file) as f:
+        datastore_indexes_auto_xml = f.read()
+    except IOError, err:
+      datastore_indexes_auto_xml = None
+
+    if self.datastore_indexes_xml:
+      try:
+        manual_index_definitions = (
+            datastore_index_xml.IndexesXmlToIndexDefinitions(
+                self.datastore_indexes_xml))
+      except validation.ValidationError, e:
+        logging.error('Error parsing %s: %s',
+                      datastore_indexes_xml_file, e)
+        return
+    else:
+      manual_index_definitions = datastore_index.IndexDefinitions(indexes=[])
+
+    if datastore_indexes_auto_xml:
+      try:
+        prev_auto_index_definitions = (
+            datastore_index_xml.IndexesXmlToIndexDefinitions(
+                datastore_indexes_auto_xml))
+      except validation.ValidationError, e:
+        logging.error('Error parsing %s: %s',
+                      datastore_indexes_auto_xml_file, e)
+        return
+    else:
+      prev_auto_index_definitions = datastore_index.IndexDefinitions(indexes=[])
+
+    all_index_definitions = datastore_index.IndexDefinitions(
+        indexes=(manual_index_definitions.indexes +
+                 prev_auto_index_definitions.indexes))
+    query_history = datastore_stub.QueryHistory()
+    auto_index_dict = GenerateIndexDictFromHistory(
+        query_history, all_index_definitions, manual_index_definitions)
+    auto_indexes, counts = self._IndexesFromIndexDict(auto_index_dict)
+    auto_index_definitions = datastore_index.IndexDefinitions(
+        indexes=auto_indexes)
+    if auto_index_definitions == prev_auto_index_definitions:
+      return
+
+    try:
+      appengine_generated = os.path.dirname(datastore_indexes_auto_xml_file)
+      if not os.path.exists(appengine_generated):
+        os.mkdir(appengine_generated)
+      with open(datastore_indexes_auto_xml_file, 'w') as f:
+        f.write(self._IndexXmlFromIndexes(auto_indexes, counts))
+    except os.error, err:
+      logging.error(
+          'Could not update %s: %s', datastore_indexes_auto_xml_file, err)
+
+  def _IndexesFromIndexDict(self, index_dict):
+    """Convert a query dictionary into the corresponding required indexes.
+
+    Args:
+      index_dict: Query history, a dict mapping datastore_pb.Query to a count
+        of the number of times that query has been issued.
+
+    Returns:
+      a tuple (indexes, counts) where indexes and counts are lists of the same
+      size, with each entry in indexes being a datastore_index.Index and each
+      entry in indexes being the count of the number of times the corresponding
+      query appeared in the history.
+    """
+    indexes = []
+    counts = []
+    for (kind, ancestor, props), count in sorted(index_dict.iteritems()):
+      properties = []
+      for name, direction_code in props:
+        direction = (
+            'asc' if direction_code == datastore_index.ASCENDING else 'desc')
+        properties.append(
+            datastore_index.Property(name=name, direction=direction))
+
+      indexes.append(datastore_index.Index(
+          kind=kind, ancestor=bool(ancestor), properties=properties))
+      counts.append(count)
+
+    return indexes, counts
+
+  def _IndexXmlFromIndexes(self, indexes, counts):
+    """Create <datastore-indexes> XML for the given indexes and query counts.
+
+    Args:
+      indexes: a list of datastore_index.Index objects that are the required
+        indexes.
+      counts: a list of integers that are the corresponding counts.
+
+    Returns:
+      the corresponding XML, with root node <datastore-indexes>.
+    """
+    lines = ['<datastore-indexes>']
+    for index, count in zip(indexes, counts):
+      lines.append('  <!-- Used %d time%s in query history -->'
+                   % (count, 's' if count != 1 else ''))
+      lines.append('  <datastore-index kind="%s" ancestor="%s">'
+                   % (index.kind, 'true' if index.ancestor else 'false'))
+      for prop in index.properties:
+        lines.append('    <property name="%s" direction="%s" />'
+                     % (prop.name, prop.direction))
+      lines.append('  </datastore-index>')
+    lines.append('</datastore-indexes>')
+    return '\n'.join(lines) + '\n'
diff --git a/google/appengine/datastore/datastore_stub_util.py b/google/appengine/datastore/datastore_stub_util.py
index 42dcea3..3e459d9 100644
--- a/google/appengine/datastore/datastore_stub_util.py
+++ b/google/appengine/datastore/datastore_stub_util.py
@@ -58,6 +58,7 @@
 from google.appengine.api import datastore_admin
 from google.appengine.api import datastore_errors
 from google.appengine.api import datastore_types
+from google.appengine.api import yaml_errors
 from google.appengine.api.taskqueue import taskqueue_service_pb
 from google.appengine.datastore import datastore_index
 from google.appengine.datastore import datastore_pb
@@ -2889,6 +2890,7 @@
     self._app_id = datastore_types.ResolveAppId(app_id)
     self._trusted = trusted
     self._root_path = root_path
+    self._xml_configuration = self._XmlConfiguration()
 
 
     self.__query_history = {}
@@ -2902,14 +2904,53 @@
 
     if self._require_indexes or root_path is None:
 
-      self._index_yaml_updater = None
+      self._index_config_updater = None
     else:
 
-      self._index_yaml_updater = datastore_stub_index.IndexYamlUpdater(
-          root_path)
+
+      updater_class = (
+          datastore_stub_index.DatastoreIndexesAutoXmlUpdater
+          if self._xml_configuration else datastore_stub_index.IndexYamlUpdater)
+      self._index_config_updater = updater_class(root_path)
 
     DatastoreStub.Clear(self)
 
+  def _XmlConfiguration(self):
+    """Return True if the app at self._root_path uses XML configuration files.
+
+    An app uses XML configuration files if it has a WEB-INF subdirectory and it
+    does not have an index.yaml at its root. We assume this even if it doesn't
+    currently have any configuration files at all, because then we will want to
+    create a new datastore-indexes-auto.xml rather than create a new index.yaml.
+
+    Returns:
+      True if the app uses XML configuration files, False otherwise.
+
+    Raises:
+      yaml_errors.AmbiguousConfigurationFiles: if there is both an index.yaml
+        and either or both of the two possible XML configuration files.
+    """
+    if not self._root_path:
+      return False
+    index_yaml = os.path.join(self._root_path, 'index.yaml')
+    web_inf = os.path.join(self._root_path, 'WEB-INF')
+    datastore_indexes_xml = os.path.join(web_inf, 'datastore-indexes.xml')
+    datastore_indexes_auto_xml = os.path.join(
+        web_inf, 'appengine-generated', 'datastore-indexes-auto.xml')
+    existing = [
+        f for f in [
+            index_yaml, datastore_indexes_xml, datastore_indexes_auto_xml]
+        if os.path.isfile(f)]
+    if existing == [index_yaml]:
+      return False
+    elif index_yaml in existing:
+      raise yaml_errors.AmbiguousConfigurationFiles(
+          'App has both XML and YAML configuration files: %s' % existing)
+    else:
+      return os.path.isdir(web_inf)
+
+
+
   def Clear(self):
     """Clears out all stored values."""
     self._query_cursors = {}
@@ -3271,8 +3312,8 @@
                     created, deleted, len(requested))
 
   def _UpdateIndexes(self):
-    if self._index_yaml_updater is not None:
-      self._index_yaml_updater.UpdateIndexYaml()
+    if self._index_config_updater is not None:
+      self._index_config_updater.UpdateIndexConfig()
 
 
 class StubQueryConverter(object):
@@ -3730,10 +3771,6 @@
     if v3_req.has_count():
       v4_req.set_suggested_batch_size(v3_req.count())
 
-    datastore_pbs.check_conversion(
-        not (v3_req.has_transaction() and v3_req.has_failover_ms()),
-        'Cannot set failover and transaction handle.')
-
 
     if v3_req.has_transaction():
       v4_req.mutable_read_options().set_transaction(
@@ -3741,7 +3778,7 @@
     elif v3_req.strong():
       v4_req.mutable_read_options().set_read_consistency(
           datastore_v4_pb.ReadOptions.STRONG)
-    elif v3_req.has_failover_ms():
+    elif v3_req.has_strong():
       v4_req.mutable_read_options().set_read_consistency(
           datastore_v4_pb.ReadOptions.EVENTUAL)
     if v3_req.has_min_safe_time_seconds():
diff --git a/google/appengine/datastore/entity_pb.py b/google/appengine/datastore/entity_pb.py
index 00a4304..7d47dae 100644
--- a/google/appengine/datastore/entity_pb.py
+++ b/google/appengine/datastore/entity_pb.py
@@ -2737,10 +2737,12 @@
 
 
   MODE_UNSPECIFIED =    0
+  SEGMENT      =    2
   GEOSPATIAL   =    3
 
   _Mode_NAMES = {
     0: "MODE_UNSPECIFIED",
+    2: "SEGMENT",
     3: "GEOSPATIAL",
   }
 
diff --git a/google/appengine/ext/analytics/static/analytics_js.js b/google/appengine/ext/analytics/static/analytics_js.js
index c56e0ed..f22e50a 100644
--- a/google/appengine/ext/analytics/static/analytics_js.js
+++ b/google/appengine/ext/analytics/static/analytics_js.js
@@ -1,9 +1,9 @@
 /* Copyright 2008-9 Google Inc. All Rights Reserved. */ (function(){var l,m=this,n=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
 else if("function"==b&&"undefined"==typeof a.call)return"object";return b},q=function(a){return"string"==typeof a},r=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}},aa=Date.now||function(){return+new Date},s=function(a,b){var c=a.split("."),e=m;c[0]in e||!e.execScript||e.execScript("var "+c[0]);for(var d;c.length&&(d=c.shift());)c.length||void 0===b?e=e[d]?e[d]:e[d]={}:e[d]=b},t=function(a,b){function c(){}
-c.prototype=b.prototype;a.o=b.prototype;a.prototype=new c;a.u=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};var u=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,u);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};t(u,Error);var ba=function(a,b){for(var c=a.split("%s"),e="",d=Array.prototype.slice.call(arguments,1);d.length&&1<c.length;)e+=c.shift()+d.shift();return e+c.join("%s")},v=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},w=function(a){a=String(a);var b=a.indexOf(".");-1==b&&(b=a.length);b=Math.max(0,2-b);return Array(b+1).join("0")+a},y=function(a,b){return a<b?-1:a>b?1:0};var z=function(a,b){b.unshift(a);u.call(this,ba.apply(null,b));b.shift()};t(z,u);var A=function(a,b,c){if(!a){var e="Assertion failed";if(b)var e=e+(": "+b),d=Array.prototype.slice.call(arguments,2);throw new z(""+e,d||[]);}};var C=Array.prototype,D=C.indexOf?function(a,b,c){A(null!=a.length);return C.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(q(a))return q(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},ca=C.forEach?function(a,b,c){A(null!=a.length);C.forEach.call(a,b,c)}:function(a,b,c){for(var e=a.length,d=q(a)?a.split(""):a,f=0;f<e;f++)f in d&&b.call(c,d[f],f,a)},da=C.filter?function(a,b,c){A(null!=a.length);return C.filter.call(a,b,
-c)}:function(a,b,c){for(var e=a.length,d=[],f=0,g=q(a)?a.split(""):a,h=0;h<e;h++)if(h in g){var x=g[h];b.call(c,x,h,a)&&(d[f++]=x)}return d},ea=function(a){var b=a.length;if(0<b){for(var c=Array(b),e=0;e<b;e++)c[e]=a[e];return c}return[]},E=function(a,b,c){A(null!=a.length);return 2>=arguments.length?C.slice.call(a,b):C.slice.call(a,b,c)};var F;t:{var G=m.navigator;if(G){var H=G.userAgent;if(H){F=H;break t}}F=""}var I=function(a){return-1!=F.indexOf(a)};var J=I("Opera")||I("OPR"),K=I("Trident")||I("MSIE"),L=I("Gecko")&&-1==F.toLowerCase().indexOf("webkit")&&!(I("Trident")||I("MSIE")),M=-1!=F.toLowerCase().indexOf("webkit"),N=function(){var a=m.document;return a?a.documentMode:void 0},fa=function(){var a="",b;if(J&&m.opera)return a=m.opera.version,"function"==n(a)?a():a;L?b=/rv\:([^\);]+)(\)|;)/:K?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:M&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(F))?a[1]:"");return K&&(b=N(),b>parseFloat(a))?String(b):a}(),ga={},O=function(a){var b;
-if(!(b=ga[a])){b=0;for(var c=v(String(fa)).split("."),e=v(String(a)).split("."),d=Math.max(c.length,e.length),f=0;0==b&&f<d;f++){var g=c[f]||"",h=e[f]||"",x=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var k=x.exec(g)||["","",""],B=p.exec(h)||["","",""];if(0==k[0].length&&0==B[0].length)break;b=y(0==k[1].length?0:parseInt(k[1],10),0==B[1].length?0:parseInt(B[1],10))||y(0==k[2].length,0==B[2].length)||y(k[2],B[2])}while(0==b)}b=ga[a]=0<=b}return b},ha=m.document,ia=ha&&K?N()||("CSS1Compat"==
-ha.compatMode?parseInt(fa,10):5):void 0;!L&&!K||K&&K&&9<=ia||L&&O("1.9.1");K&&O("9");var P=function(a,b,c){var e=document;c=c||e;var d=a&&"*"!=a?a.toUpperCase():"";if(c.querySelectorAll&&c.querySelector&&(d||b))return c.querySelectorAll(d+(b?"."+b:""));if(b&&c.getElementsByClassName){a=c.getElementsByClassName(b);if(d){c={};for(var f=e=0,g;g=a[f];f++)d==g.nodeName&&(c[e++]=g);c.length=e;return c}return a}a=c.getElementsByTagName(d||"*");if(b){c={};for(f=e=0;g=a[f];f++){var d=g.className,h;if(h="function"==typeof d.split)h=0<=D(d.split(/\s+/),b);h&&(c[e++]=g)}c.length=e;return c}return a};var ja=function(a){a=a.className;return q(a)&&a.match(/\S+/g)||[]},ka=function(a,b){for(var c=ja(a),e=E(arguments,1),d=c,f=0;f<e.length;f++)0<=D(d,e[f])||d.push(e[f]);c=c.join(" ");a.className=c},ma=function(a,b){var c=ja(a),e=E(arguments,1),c=la(c,e).join(" ");a.className=c},la=function(a,b){return da(a,function(a){return!(0<=D(b,a))})};var Q=function(a){Q[" "](a);return a};Q[" "]=function(){};var na=!K||K&&9<=ia,oa=K&&!O("9");!M||O("528");L&&O("1.9b")||K&&O("8")||J&&O("9.5")||M&&O("528");L&&!O("8")||K&&O("9");var R=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.j=!1};R.prototype.preventDefault=function(){this.defaultPrevented=!0};L&&O(17);var S=function(a,b){R.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.k=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var e=a.relatedTarget;if(e){if(L){var d;t:{try{Q(e.nodeName);d=!0;break t}catch(f){}d=!1}d||(e=null)}}else"mouseover"==
+c.prototype=b.prototype;a.o=b.prototype;a.prototype=new c;a.u=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};var u=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,u);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};t(u,Error);var ba=function(a,b){for(var c=a.split("%s"),e="",d=Array.prototype.slice.call(arguments,1);d.length&&1<c.length;)e+=c.shift()+d.shift();return e+c.join("%s")},v=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},x=function(a){a=String(a);var b=a.indexOf(".");-1==b&&(b=a.length);b=Math.max(0,2-b);return Array(b+1).join("0")+a},y=function(a,b){return a<b?-1:a>b?1:0};var z=function(a,b){b.unshift(a);u.call(this,ba.apply(null,b));b.shift()};t(z,u);var A=function(a,b,c){if(!a){var e="Assertion failed";if(b)var e=e+(": "+b),d=Array.prototype.slice.call(arguments,2);throw new z(""+e,d||[]);}};var C=Array.prototype,D=C.indexOf?function(a,b,c){A(null!=a.length);return C.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(q(a))return q(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},ca=C.forEach?function(a,b,c){A(null!=a.length);C.forEach.call(a,b,c)}:function(a,b,c){for(var e=a.length,d=q(a)?a.split(""):a,f=0;f<e;f++)f in d&&b.call(c,d[f],f,a)},da=C.filter?function(a,b,c){A(null!=a.length);return C.filter.call(a,b,
+c)}:function(a,b,c){for(var e=a.length,d=[],f=0,g=q(a)?a.split(""):a,h=0;h<e;h++)if(h in g){var w=g[h];b.call(c,w,h,a)&&(d[f++]=w)}return d},ea=function(a){var b=a.length;if(0<b){for(var c=Array(b),e=0;e<b;e++)c[e]=a[e];return c}return[]},E=function(a,b,c){A(null!=a.length);return 2>=arguments.length?C.slice.call(a,b):C.slice.call(a,b,c)};var F;t:{var G=m.navigator;if(G){var H=G.userAgent;if(H){F=H;break t}}F=""}var I=function(a){return-1!=F.indexOf(a)};var J=I("Opera")||I("OPR"),K=I("Trident")||I("MSIE"),L=I("Gecko")&&-1==F.toLowerCase().indexOf("webkit")&&!(I("Trident")||I("MSIE")),M=-1!=F.toLowerCase().indexOf("webkit"),N=function(){var a=m.document;return a?a.documentMode:void 0},fa=function(){var a="",b;if(J&&m.opera)return a=m.opera.version,"function"==n(a)?a():a;L?b=/rv\:([^\);]+)(\)|;)/:K?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:M&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(F))?a[1]:"");return K&&(b=N(),b>parseFloat(a))?String(b):a}(),ga={},O=function(a){var b;
+if(!(b=ga[a])){b=0;for(var c=v(String(fa)).split("."),e=v(String(a)).split("."),d=Math.max(c.length,e.length),f=0;0==b&&f<d;f++){var g=c[f]||"",h=e[f]||"",w=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var k=w.exec(g)||["","",""],B=p.exec(h)||["","",""];if(0==k[0].length&&0==B[0].length)break;b=y(0==k[1].length?0:parseInt(k[1],10),0==B[1].length?0:parseInt(B[1],10))||y(0==k[2].length,0==B[2].length)||y(k[2],B[2])}while(0==b)}b=ga[a]=0<=b}return b},ha=m.document,ia=ha&&K?N()||("CSS1Compat"==
+ha.compatMode?parseInt(fa,10):5):void 0;!L&&!K||K&&K&&9<=ia||L&&O("1.9.1");K&&O("9");var P=function(a,b,c){var e=document;c=c||e;var d=a&&"*"!=a?a.toUpperCase():"";if(c.querySelectorAll&&c.querySelector&&(d||b))return c.querySelectorAll(d+(b?"."+b:""));if(b&&c.getElementsByClassName){a=c.getElementsByClassName(b);if(d){c={};for(var f=e=0,g;g=a[f];f++)d==g.nodeName&&(c[e++]=g);c.length=e;return c}return a}a=c.getElementsByTagName(d||"*");if(b){c={};for(f=e=0;g=a[f];f++){var d=g.className,h;if(h="function"==typeof d.split)h=0<=D(d.split(/\s+/),b);h&&(c[e++]=g)}c.length=e;return c}return a};var ja=function(a){a=a.className;return q(a)&&a.match(/\S+/g)||[]},ka=function(a,b){for(var c=ja(a),e=E(arguments,1),d=c,f=0;f<e.length;f++)0<=D(d,e[f])||d.push(e[f]);c=c.join(" ");a.className=c},ma=function(a,b){var c=ja(a),e=E(arguments,1),c=la(c,e).join(" ");a.className=c},la=function(a,b){return da(a,function(a){return!(0<=D(b,a))})};var Q=function(a){Q[" "](a);return a};Q[" "]=function(){};var na=!K||K&&9<=ia,oa=K&&!O("9");!M||O("528");L&&O("1.9b")||K&&O("8")||J&&O("9.5")||M&&O("528");L&&!O("8")||K&&O("9");var R=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.j=!1};R.prototype.preventDefault=function(){this.defaultPrevented=!0};var S=function(a,b){R.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.k=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var e=a.relatedTarget;if(e){if(L){var d;t:{try{Q(e.nodeName);d=!0;break t}catch(f){}d=!1}d||(e=null)}}else"mouseover"==
 c?e=a.fromElement:"mouseout"==c&&(e=a.toElement);this.relatedTarget=e;this.offsetX=M||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=M||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
 a.metaKey;this.state=a.state;this.k=a;a.defaultPrevented&&this.preventDefault()}};t(S,R);S.prototype.preventDefault=function(){S.o.preventDefault.call(this);var a=this.k;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,oa)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};var pa="closure_listenable_"+(1E6*Math.random()|0),qa=0;var ra=function(a,b,c,e,d){this.c=a;this.e=null;this.src=b;this.type=c;this.g=!!e;this.f=d;this.key=++qa;this.d=this.h=!1},sa=function(a){a.d=!0;a.c=null;a.e=null;a.src=null;a.f=null};var T=function(a){this.src=a;this.b={};this.i=0};T.prototype.add=function(a,b,c,e,d){var f=a.toString();a=this.b[f];a||(a=this.b[f]=[],this.i++);var g;t:{for(g=0;g<a.length;++g){var h=a[g];if(!h.d&&h.c==b&&h.g==!!e&&h.f==d)break t}g=-1}-1<g?(b=a[g],c||(b.h=!1)):(b=new ra(b,this.src,f,!!e,d),b.h=c,a.push(b));return b};var ta=function(a,b){var c=b.type;if(c in a.b){var e=a.b[c],d=D(e,b),f;if(f=0<=d)A(null!=e.length),C.splice.call(e,d,1);f&&(sa(b),0==a.b[c].length&&(delete a.b[c],a.i--))}};var U="closure_lm_"+(1E6*Math.random()|0),V={},ua=0,wa=function(){var a=va,b=na?function(c){return a.call(b.src,b.c,c)}:function(c){c=a.call(b.src,b.c,c);if(!c)return c};return b},xa=function(a,b,c,e,d){if("array"==n(b))for(var f=0;f<b.length;f++)xa(a,b[f],c,e,d);else if(c=ya(c),a&&a[pa])a.t(b,c,e,d);else{if(!b)throw Error("Invalid event type");var f=!!e,g=W(a);g||(a[U]=g=new T(a));c=g.add(b,c,!0,e,d);c.e||(e=wa(),c.e=e,e.src=a,e.c=c,a.addEventListener?a.addEventListener(b.toString(),e,f):a.attachEvent(za(b.toString()),
 e),ua++)}},za=function(a){return a in V?V[a]:V[a]="on"+a},Ba=function(a,b,c,e){var d=1;if(a=W(a))if(b=a.b[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.g==c&&!f.d&&(d&=!1!==Aa(f,e))}return Boolean(d)},Aa=function(a,b){var c=a.c,e=a.f||a.src;if(a.h&&"number"!=typeof a&&a&&!a.d){var d=a.src;if(d&&d[pa])ta(d.s,a);else{var f=a.type,g=a.e;d.removeEventListener?d.removeEventListener(f,g,a.g):d.detachEvent&&d.detachEvent(za(f),g);ua--;(f=W(d))?(ta(f,a),0==f.i&&(f.src=null,d[U]=null)):
@@ -11,7 +11,7 @@
 0;!c.j&&h<d.length;h++)c.currentTarget=d[h],e&=Ba(d[h],f,!1,c)}return e}return Aa(a,new S(b,this))},W=function(a){a=a[U];return a instanceof T?a:null},X="__closure_events_fn_"+(1E9*Math.random()>>>0),ya=function(a){A(a,"Listener can not be null.");if("function"==n(a))return a;A(a.handleEvent,"An object listener must have handleEvent method.");a[X]||(a[X]=function(b){return a.handleEvent(b)});return a[X]};var Z=function(a,b,c){"number"==typeof a?(this.a=Ca(a,b||0,c||1),Y(this,c||1)):(b=typeof a,"object"==b&&null!=a||"function"==b?(this.a=Ca(a.getFullYear(),a.getMonth(),a.getDate()),Y(this,a.getDate())):(this.a=new Date(aa()),this.a.setHours(0),this.a.setMinutes(0),this.a.setSeconds(0),this.a.setMilliseconds(0)))},Ca=function(a,b,c){b=new Date(a,b,c);0<=a&&100>a&&b.setFullYear(b.getFullYear()-1900);return b};l=Z.prototype;l.getFullYear=function(){return this.a.getFullYear()};l.getYear=function(){return this.getFullYear()};
 l.getMonth=function(){return this.a.getMonth()};l.getDate=function(){return this.a.getDate()};l.getTime=function(){return this.a.getTime()};l.getUTCHours=function(){return this.a.getUTCHours()};l.setFullYear=function(a){this.a.setFullYear(a)};l.setMonth=function(a){this.a.setMonth(a)};l.setDate=function(a){this.a.setDate(a)};
 l.add=function(a){if(a.p||a.n){var b=this.getMonth()+a.n+12*a.p,c=this.getYear()+Math.floor(b/12),b=b%12;0>b&&(b+=12);var e;t:{switch(b){case 1:e=0!=c%4||0==c%100&&0!=c%400?28:29;break t;case 5:case 8:case 10:case 3:e=30;break t}e=31}e=Math.min(e,this.getDate());this.setDate(1);this.setFullYear(c);this.setMonth(b);this.setDate(e)}a.m&&(b=new Date(this.getYear(),this.getMonth(),this.getDate(),12),a=new Date(b.getTime()+864E5*a.m),this.setDate(1),this.setFullYear(a.getFullYear()),this.setMonth(a.getMonth()),
-this.setDate(a.getDate()),Y(this,a.getDate()))};l.r=function(){return[this.getFullYear(),w(this.getMonth()+1),w(this.getDate())].join("")+""};l.toString=function(){return this.r()};var Y=function(a,b){if(a.getDate()!=b){var c=a.getDate()<b?1:-1;a.a.setUTCHours(a.a.getUTCHours()+c)}};Z.prototype.valueOf=function(){return this.a.valueOf()};var $=function(){};$.l=function(){$.q||($.q=new $)};$.l();new Z(0,0,1);new Z(9999,11,31);K||M&&O("525");$.l();s("ae.init",function(){Da();Ea();xa(window,"load",function(){});Fa()});
+this.setDate(a.getDate()),Y(this,a.getDate()))};l.r=function(){return[this.getFullYear(),x(this.getMonth()+1),x(this.getDate())].join("")+""};l.toString=function(){return this.r()};var Y=function(a,b){if(a.getDate()!=b){var c=a.getDate()<b?1:-1;a.a.setUTCHours(a.a.getUTCHours()+c)}};Z.prototype.valueOf=function(){return this.a.valueOf()};var $=function(){};$.l=function(){$.q||($.q=new $)};$.l();new Z(0,0,1);new Z(9999,11,31);K||M&&O("525");$.l();s("ae.init",function(){Da();Ea();xa(window,"load",function(){});Fa()});
 var Da=function(){var a;if(a=q("ae-content")?document.getElementById("ae-content"):"ae-content"){a=P("table","ae-table-striped",a);for(var b=0,c;c=a[b];b++){c=P("tbody",null,c);for(var e=0,d;d=c[e];e++){d=P("tr",null,d);for(var f=0,g;g=d[f];f++)f%2&&ka(g,"ae-even")}}}},Ea=function(){var a=P(null,"ae-noscript",void 0);ca(ea(a),function(a){ma(a,"ae-noscript")})},Fa=function(){m._gaq=m._gaq||[];m._gaq.push(function(){m._gaq._createAsyncTracker("UA-3739047-3","ae")._trackPageview()});(function(){var a=
 document.createElement("script");a.src=("https:"==document.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";a.setAttribute("async","true");document.documentElement.firstChild.appendChild(a)})()};s("ae.trackPageView",function(){m._gaq&&m._gaq._getAsyncTracker("ae")._trackPageview()});var Ha=function(a){if(void 0==a||null==a||0==a.length)return 0;a=Math.max.apply(Math,a);return Ga(a)},Ga=function(a){var b=5;2>b&&(b=2);b-=1;return Math.ceil(a/b)*b},Ia=function(a,b,c){a=a.getSelection();1==a.length&&(a=a[0],null!=a.row&&(null!=b.starttime&&(c+="&starttime="+b.starttime),null!=b.endtime&&(c+="&endtime="+b.endtime),null!=b.latency_lower&&(c+="&latency_lower="+b.latency_lower),null!=b.latency_upper&&(c+="&latency_upper="+b.latency_upper),b=c+"&detail="+a.row,window.location.href=b))},
 Ja=function(a,b,c,e,d){var f=new google.visualization.DataTable;f.addColumn("string","");f.addColumn("number","");f.addColumn({type:"string",role:"tooltip"});for(var g=0;g<b.length;g++)f.addRow(["",b[g],c[g]]);c=Math.max(10*b.length,200);b=Ha(b);a=new google.visualization.ColumnChart(document.getElementById("rpctime-"+a));a.draw(f,{height:100,width:c,legend:"none",chartArea:{left:40},fontSize:11,vAxis:{minValue:0,maxValue:b,gridlines:{count:5}}});google.visualization.events.addListener(a,"select",
@@ -21,4 +21,4 @@
 s("ae.Charts.entityCountBarChart",function(a,b,c,e){var d=new google.visualization.DataTable;d.addColumn("string","");d.addColumn("number","Reads");d.addColumn({type:"string",role:"tooltip"});d.addColumn("number","Misses");d.addColumn({type:"string",role:"tooltip"});d.addColumn("number","Writes");d.addColumn({type:"string",role:"tooltip"});var f=50;f>b.length&&(f=b.length);for(var g=0;g<f;g++)d.addRow(["",b[g][1]-b[g][3],b[g][0],b[g][3],b[g][0],b[g][2],b[g][0]]);b=20*f;f=b+130;a=new google.visualization.ColumnChart(document.getElementById(e+
 "-"+a));c=Ga(c);a.draw(d,{height:100,width:f,chartArea:{width:b},fontSize:10,isStacked:!0,vAxis:{minValue:0,maxValue:c,gridlines:{count:5}}})});
 s("ae.Charts.rpcVariationCandlestick",function(a){var b=new google.visualization.DataTable;b.addColumn("string","");b.addColumn("number","");b.addColumn("number","");b.addColumn("number","");b.addColumn("number","");b.addRows(a);(new google.visualization.CandlestickChart(document.getElementById("rpcvariation"))).draw(b,{vAxis:{title:"RPC Latency variation (milliseconds)"},hAxis:{textPosition:"out",slantedText:!0,slantedTextAngle:45,textStyle:{fontSize:13}},height:250,chartArea:{top:10,height:100},
-legend:"none",tooltip:{trigger:"none"}})});s("ae.Charts.totalTimeBarChart",function(a,b,c,e){for(var d=[],f=0;f<b.length;f++)d[f]=b[f]+" milliseconds";Ja(a,b,d,c,e)});s("ae.Charts.rpcTimeBarChart",function(a,b,c,e,d){var f=[],g=[],h=c.indices,x=c.times;c=c.stats;for(var p=0;p<b;p++)f[p]=0,g[p]=null;for(p=0;p<h.length;p++){f[h[p]]=x[p];b=c[p];var k="Calls: "+b[0];if(0<b[1]||0<b[2]||0<b[3])k+=" Entities";0<b[1]&&(k+=" R:"+b[1]);0<b[2]&&(k+=" W:"+b[2]);0<b[3]&&(k+=" M:"+b[3]);g[h[p]]=k}Ja(a,f,g,e,d)});})();
+legend:"none",tooltip:{trigger:"none"}})});s("ae.Charts.totalTimeBarChart",function(a,b,c,e){for(var d=[],f=0;f<b.length;f++)d[f]=b[f]+" milliseconds";Ja(a,b,d,c,e)});s("ae.Charts.rpcTimeBarChart",function(a,b,c,e,d){var f=[],g=[],h=c.indices,w=c.times;c=c.stats;for(var p=0;p<b;p++)f[p]=0,g[p]=null;for(p=0;p<h.length;p++){f[h[p]]=w[p];b=c[p];var k="Calls: "+b[0];if(0<b[1]||0<b[2]||0<b[3])k+=" Entities";0<b[1]&&(k+=" R:"+b[1]);0<b[2]&&(k+=" W:"+b[2]);0<b[3]&&(k+=" M:"+b[3]);g[h[p]]=k}Ja(a,f,g,e,d)});})();
diff --git a/google/appengine/ext/appstats/static/appstats_js.js b/google/appengine/ext/appstats/static/appstats_js.js
index b583924..38d7be6 100644
--- a/google/appengine/ext/appstats/static/appstats_js.js
+++ b/google/appengine/ext/appstats/static/appstats_js.js
@@ -6,15 +6,15 @@
 c)}:function(a,b,c){for(var d=a.length,e=[],g=0,h=m(a)?a.split(""):a,k=0;k<d;k++)if(k in h){var I=h[k];b.call(c,I,k,a)&&(e[g++]=I)}return e},Da=r.every?function(a,b,c){q(null!=a.length);return r.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=m(a)?a.split(""):a,g=0;g<d;g++)if(g in e&&!b.call(c,e[g],g,a))return!1;return!0},t=function(a,b){return 0<=Ba(a,b)},Ea=function(a,b){var c=Ba(a,b),d;if(d=0<=c)q(null!=a.length),r.splice.call(a,c,1);return d},Fa=function(a){var b=a.length;if(0<b){for(var c=
 Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]},Ha=function(a,b,c,d){q(null!=a.length);r.splice.apply(a,Ga(arguments,1))},Ga=function(a,b,c){q(null!=a.length);return 2>=arguments.length?r.slice.call(a,b):r.slice.call(a,b,c)};var Ia=function(a){a=a.className;return m(a)&&a.match(/\S+/g)||[]},Ja=function(a,b){for(var c=Ia(a),d=Ga(arguments,1),e=c,g=0;g<d.length;g++)t(e,d[g])||e.push(d[g]);a.className=c.join(" ")},La=function(a,b){var c=Ia(a),d=Ga(arguments,1),c=Ka(c,d);a.className=c.join(" ")},Ka=function(a,b){return Ca(a,function(a){return!t(b,a)})};var Ma=function(a,b){for(var c in a)b.call(void 0,a[c],c,a)},Na=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1},Oa=function(a,b,c){if(b in a)throw Error('The object already contains the key "'+b+'"');a[b]=c},Pa=function(a){var b={},c;for(c in a)b[a[c]]=c;return b},Qa="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Ra=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var g=0;g<Qa.length;g++)c=
 Qa[g],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};var Sa;t:{var Ta=l.navigator;if(Ta){var Ua=Ta.userAgent;if(Ua){Sa=Ua;break t}}Sa=""}var u=function(a){return-1!=Sa.indexOf(a)};var Va=u("Opera")||u("OPR"),v=u("Trident")||u("MSIE"),w=u("Gecko")&&-1==Sa.toLowerCase().indexOf("webkit")&&!(u("Trident")||u("MSIE")),x=-1!=Sa.toLowerCase().indexOf("webkit"),Wa=l.navigator||null,y=-1!=(Wa&&Wa.platform||"").indexOf("Mac"),Xa=function(){var a=l.document;return a?a.documentMode:void 0},Ya=function(){var a="",b;if(Va&&l.opera)return a=l.opera.version,n(a)?a():a;w?b=/rv\:([^\);]+)(\)|;)/:v?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:x&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(Sa))?a[1]:"");return v&&
-(b=Xa(),b>parseFloat(a))?String(b):a}(),Za={},z=function(a){var b;if(!(b=Za[a])){b=0;for(var c=oa(String(Ya)).split("."),d=oa(String(a)).split("."),e=Math.max(c.length,d.length),g=0;0==b&&g<e;g++){var h=c[g]||"",k=d[g]||"",I=RegExp("(\\d*)(\\D*)","g"),A=RegExp("(\\d*)(\\D*)","g");do{var K=I.exec(h)||["","",""],P=A.exec(k)||["","",""];if(0==K[0].length&&0==P[0].length)break;b=xa(0==K[1].length?0:parseInt(K[1],10),0==P[1].length?0:parseInt(P[1],10))||xa(0==K[2].length,0==P[2].length)||xa(K[2],P[2])}while(0==
-b)}b=Za[a]=0<=b}return b},$a=l.document,ab=$a&&v?Xa()||("CSS1Compat"==$a.compatMode?parseInt(Ya,10):5):void 0;var bb=!v||v&&9<=ab;!w&&!v||v&&v&&9<=ab||w&&z("1.9.1");var cb=v&&!z("9");var fb=function(a){return a?new db(eb(a)):ma||(ma=new db)},gb=function(a,b){return m(b)?a.getElementById(b):b},hb=function(a,b,c){var d=document;c=c||d;a=a&&"*"!=a?a.toUpperCase():"";if(c.querySelectorAll&&c.querySelector&&(a||b))return c.querySelectorAll(a+(b?"."+b:""));if(b&&c.getElementsByClassName){c=c.getElementsByClassName(b);if(a){for(var d={},e=0,g=0,h;h=c[g];g++)a==h.nodeName&&(d[e++]=h);d.length=e;return d}return c}c=c.getElementsByTagName(a||"*");if(b){d={};for(g=e=0;h=c[g];g++)a=h.className,
+(b=Xa(),b>parseFloat(a))?String(b):a}(),Za={},A=function(a){var b;if(!(b=Za[a])){b=0;for(var c=oa(String(Ya)).split("."),d=oa(String(a)).split("."),e=Math.max(c.length,d.length),g=0;0==b&&g<e;g++){var h=c[g]||"",k=d[g]||"",I=RegExp("(\\d*)(\\D*)","g"),z=RegExp("(\\d*)(\\D*)","g");do{var K=I.exec(h)||["","",""],P=z.exec(k)||["","",""];if(0==K[0].length&&0==P[0].length)break;b=xa(0==K[1].length?0:parseInt(K[1],10),0==P[1].length?0:parseInt(P[1],10))||xa(0==K[2].length,0==P[2].length)||xa(K[2],P[2])}while(0==
+b)}b=Za[a]=0<=b}return b},$a=l.document,ab=$a&&v?Xa()||("CSS1Compat"==$a.compatMode?parseInt(Ya,10):5):void 0;var bb=!v||v&&9<=ab;!w&&!v||v&&v&&9<=ab||w&&A("1.9.1");var cb=v&&!A("9");var fb=function(a){return a?new db(eb(a)):ma||(ma=new db)},gb=function(a,b){return m(b)?a.getElementById(b):b},hb=function(a,b,c){var d=document;c=c||d;a=a&&"*"!=a?a.toUpperCase():"";if(c.querySelectorAll&&c.querySelector&&(a||b))return c.querySelectorAll(a+(b?"."+b:""));if(b&&c.getElementsByClassName){c=c.getElementsByClassName(b);if(a){for(var d={},e=0,g=0,h;h=c[g];g++)a==h.nodeName&&(d[e++]=h);d.length=e;return d}return c}c=c.getElementsByTagName(a||"*");if(b){d={};for(g=e=0;h=c[g];g++)a=h.className,
 "function"==typeof a.split&&t(a.split(/\s+/),b)&&(d[e++]=h);d.length=e;return d}return c},jb=function(a,b){Ma(b,function(b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in ib?a.setAttribute(ib[d],b):0==d.lastIndexOf("aria-",0)||0==d.lastIndexOf("data-",0)?a.setAttribute(d,b):a[d]=b})},ib={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",
 valign:"vAlign",width:"width"},lb=function(a,b,c){return kb(document,arguments)},kb=function(a,b){var c=b[0],d=b[1];if(!bb&&d&&(d.name||d.type)){c=["<",c];d.name&&c.push(' name="',wa(d.name),'"');if(d.type){c.push(' type="',wa(d.type),'"');var e={};Ra(e,d);delete e.type;d=e}c.push(">");c=c.join("")}c=a.createElement(c);d&&(m(d)?c.className=d:da(d)?c.className=d.join(" "):jb(c,d));2<b.length&&mb(a,c,b);return c},mb=function(a,b,c){function d(c){c&&b.appendChild(m(c)?a.createTextNode(c):c)}for(var e=
 2;e<c.length;e++){var g=c[e];if(!ea(g)||fa(g)&&0<g.nodeType)d(g);else{var h;t:{if(g&&"number"==typeof g.length){if(fa(g)){h="function"==typeof g.item||"string"==typeof g.item;break t}if(n(g)){h="function"==typeof g.item;break t}}h=!1}s(h?Fa(g):g,d)}}},nb=function(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a},eb=function(a){q(a,"Node cannot be null or undefined.");
 return 9==a.nodeType?a:a.ownerDocument||a.document},ob=function(a,b){q(null!=a,"goog.dom.setTextContent expects a non-null value for node");if("textContent"in a)a.textContent=b;else if(3==a.nodeType)a.data=b;else if(a.firstChild&&3==a.firstChild.nodeType){for(;a.lastChild!=a.firstChild;)a.removeChild(a.lastChild);a.firstChild.data=b}else{for(var c;c=a.firstChild;)a.removeChild(c);c=eb(a);a.appendChild(c.createTextNode(String(b)))}},pb={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},qb={IMG:" ",BR:"\n"},
 tb=function(a){return rb(a)&&sb(a)},ub=function(a,b){b?a.tabIndex=0:(a.tabIndex=-1,a.removeAttribute("tabIndex"))},rb=function(a){a=a.getAttributeNode("tabindex");return null!=a&&a.specified},sb=function(a){a=a.tabIndex;return"number"==typeof a&&0<=a&&32768>a},vb=function(a,b,c){if(!(a.nodeName in pb))if(3==a.nodeType)c?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in qb)b.push(qb[a.nodeName]);else for(a=a.firstChild;a;)vb(a,b,c),a=a.nextSibling},db=
 function(a){this.Q=a||l.document||document};f=db.prototype;f.mb=fb;f.a=function(a){return gb(this.Q,a)};f.o=function(a,b,c){return kb(this.Q,arguments)};f.createElement=function(a){return this.Q.createElement(a)};f.createTextNode=function(a){return this.Q.createTextNode(String(a))};f.appendChild=function(a,b){a.appendChild(b)};f.contains=nb;
-f.I=function(a){var b;(b="A"==a.tagName||"INPUT"==a.tagName||"TEXTAREA"==a.tagName||"SELECT"==a.tagName||"BUTTON"==a.tagName?!a.disabled&&(!rb(a)||sb(a)):tb(a))&&v?(a=n(a.getBoundingClientRect)?a.getBoundingClientRect():{height:a.offsetHeight,width:a.offsetWidth},a=null!=a&&0<a.height&&0<a.width):a=b;return a};var wb=function(a){wb[" "](a);return a};wb[" "]=aa;var xb=!v||v&&9<=ab,yb=!v||v&&9<=ab,zb=v&&!z("9");!x||z("528");w&&z("1.9b")||v&&z("8")||Va&&z("9.5")||x&&z("528");w&&!z("8")||v&&z("9");var Ab=function(){this.eb=this.eb;this.ic=this.ic};Ab.prototype.eb=!1;var B=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.$=!1;this.wb=!0};B.prototype.stopPropagation=function(){this.$=!0};B.prototype.preventDefault=function(){this.defaultPrevented=!0;this.wb=!1};w&&z(17);var C=function(a,b){B.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.kb=!1;this.O=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(w){var e;t:{try{wb(d.nodeName);e=!0;break t}catch(g){}e=!1}e||(d=null)}}else"mouseover"==
+f.I=function(a){var b;(b="A"==a.tagName||"INPUT"==a.tagName||"TEXTAREA"==a.tagName||"SELECT"==a.tagName||"BUTTON"==a.tagName?!a.disabled&&(!rb(a)||sb(a)):tb(a))&&v?(a=n(a.getBoundingClientRect)?a.getBoundingClientRect():{height:a.offsetHeight,width:a.offsetWidth},a=null!=a&&0<a.height&&0<a.width):a=b;return a};var wb=function(a){wb[" "](a);return a};wb[" "]=aa;var xb=!v||v&&9<=ab,yb=!v||v&&9<=ab,zb=v&&!A("9");!x||A("528");w&&A("1.9b")||v&&A("8")||Va&&A("9.5")||x&&A("528");w&&!A("8")||v&&A("9");var Ab=function(){this.eb=this.eb;this.ic=this.ic};Ab.prototype.eb=!1;var B=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.$=!1;this.wb=!0};B.prototype.stopPropagation=function(){this.$=!0};B.prototype.preventDefault=function(){this.defaultPrevented=!0;this.wb=!1};var C=function(a,b){B.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.kb=!1;this.O=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(w){var e;t:{try{wb(d.nodeName);e=!0;break t}catch(g){}e=!1}e||(d=null)}}else"mouseover"==
 c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=x||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=x||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
 a.metaKey;this.kb=y?a.metaKey:a.ctrlKey;this.state=a.state;this.O=a;a.defaultPrevented&&this.preventDefault()}};p(C,B);var Bb=[1,4,2],Cb=function(a){return xb?0==a.O.button:"click"==a.type?!0:!!(a.O.button&Bb[0])};C.prototype.stopPropagation=function(){C.f.stopPropagation.call(this);this.O.stopPropagation?this.O.stopPropagation():this.O.cancelBubble=!0};
 C.prototype.preventDefault=function(){C.f.preventDefault.call(this);var a=this.O;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,zb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};var Db="closure_listenable_"+(1E6*Math.random()|0),Eb=0;var Fb=function(a,b,c,d,e){this.W=a;this.Ea=null;this.src=b;this.type=c;this.Fa=!!d;this.Ha=e;this.key=++Eb;this.ha=this.Ga=!1},Gb=function(a){a.ha=!0;a.W=null;a.Ea=null;a.src=null;a.Ha=null};var D=function(a){this.src=a;this.m={};this.ua=0};D.prototype.add=function(a,b,c,d,e){var g=a.toString();a=this.m[g];a||(a=this.m[g]=[],this.ua++);var h=Hb(a,b,d,e);-1<h?(b=a[h],c||(b.Ga=!1)):(b=new Fb(b,this.src,g,!!d,e),b.Ga=c,a.push(b));return b};D.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.m))return!1;var e=this.m[a];b=Hb(e,b,c,d);return-1<b?(Gb(e[b]),q(null!=e.length),r.splice.call(e,b,1),0==e.length&&(delete this.m[a],this.ua--),!0):!1};
@@ -36,20 +36,20 @@
 var M=function(a){return a.q?a.q.length:0},fc=function(a,b){var c;a.F&&b?(c=a.F,c=(b in c?c[b]:void 0)||null):c=null;return c},N=function(a,b){return a.q?a.q[b]||null:null},hc=function(a,b,c){a.q&&s(a.q,b,c)},jc=function(a,b){return a.q&&b?Ba(a.q,b):-1};
 L.prototype.removeChild=function(a,b){if(a){var c=m(a)?a:cc(a);a=fc(this,c);if(c&&a){var d=this.F;c in d&&delete d[c];Ea(this.q,a);b&&(a.ba(),a.d&&(c=a.d)&&c.parentNode&&c.parentNode.removeChild(c));gc(a,null)}}if(!a)throw Error("Child is not in parent component");return a};var kc,lc={oc:"activedescendant",tc:"atomic",uc:"autocomplete",wc:"busy",zc:"checked",Ec:"controls",Gc:"describedby",Jc:"disabled",Lc:"dropeffect",Mc:"expanded",Nc:"flowto",Pc:"grabbed",Tc:"haspopup",Vc:"hidden",Xc:"invalid",Yc:"label",Zc:"labelledby",$c:"level",ed:"live",pd:"multiline",qd:"multiselectable",ud:"orientation",vd:"owns",wd:"posinset",yd:"pressed",Cd:"readonly",Ed:"relevant",Fd:"required",Ld:"selected",Nd:"setsize",Pd:"sort",be:"valuemax",ce:"valuemin",de:"valuenow",ee:"valuetext"};var mc={pc:"alert",qc:"alertdialog",rc:"application",sc:"article",vc:"banner",xc:"button",yc:"checkbox",Ac:"columnheader",Bc:"combobox",Cc:"complementary",Dc:"contentinfo",Fc:"definition",Hc:"dialog",Ic:"directory",Kc:"document",Oc:"form",Qc:"grid",Rc:"gridcell",Sc:"group",Uc:"heading",Wc:"img",ad:"link",bd:"list",cd:"listbox",dd:"listitem",fd:"log",gd:"main",hd:"marquee",jd:"math",kd:"menu",ld:"menubar",md:"menuitem",nd:"menuitemcheckbox",od:"menuitemradio",rd:"navigation",sd:"note",td:"option",
 xd:"presentation",zd:"progressbar",Ad:"radio",Bd:"radiogroup",Dd:"region",Gd:"row",Hd:"rowgroup",Id:"rowheader",Jd:"scrollbar",Kd:"search",Md:"separator",Od:"slider",Qd:"spinbutton",Rd:"status",Sd:"tab",Td:"tablist",Ud:"tabpanel",Vd:"textbox",Wd:"timer",Xd:"toolbar",Yd:"tooltip",Zd:"tree",$d:"treegrid",ae:"treeitem"};var nc=function(a,b){b?(q(Na(mc,b),"No such ARIA role "+b),a.setAttribute("role",b)):a.removeAttribute("role")},pc=function(a,b,c){da(c)&&(c=c.join(" "));var d=oc(b);""===c||void 0==c?(kc||(kc={atomic:!1,autocomplete:"none",dropeffect:"none",haspopup:!1,live:"off",multiline:!1,multiselectable:!1,orientation:"vertical",readonly:!1,relevant:"additions text",required:!1,sort:"none",busy:!1,disabled:!1,hidden:!1,invalid:"false"}),c=kc,b in c?a.setAttribute(d,c[b]):a.removeAttribute(d)):a.setAttribute(d,
-c)},oc=function(a){q(a,"ARIA attribute cannot be empty.");q(Na(lc,a),"No such ARIA attribute "+a);return"aria-"+a};var sc=function(a,b,c,d,e){if(!(v||x&&z("525")))return!0;if(y&&e)return qc(a);if(e&&!d)return!1;"number"==typeof b&&(b=rc(b));if(!c&&(17==b||18==b||y&&91==b))return!1;if(x&&d&&c)switch(a){case 220:case 219:case 221:case 192:case 186:case 189:case 187:case 188:case 190:case 191:case 192:case 222:return!1}if(v&&d&&b==a)return!1;switch(a){case 13:return!0;case 27:return!x}return qc(a)},qc=function(a){if(48<=a&&57>=a||96<=a&&106>=a||65<=a&&90>=a||x&&0==a)return!0;switch(a){case 32:case 63:case 107:case 109:case 110:case 111:case 186:case 59:case 189:case 187:case 61:case 188:case 190:case 191:case 192:case 222:case 219:case 220:case 221:return!0;
+c)},oc=function(a){q(a,"ARIA attribute cannot be empty.");q(Na(lc,a),"No such ARIA attribute "+a);return"aria-"+a};var sc=function(a,b,c,d,e){if(!(v||x&&A("525")))return!0;if(y&&e)return qc(a);if(e&&!d)return!1;"number"==typeof b&&(b=rc(b));if(!c&&(17==b||18==b||y&&91==b))return!1;if(x&&d&&c)switch(a){case 220:case 219:case 221:case 192:case 186:case 189:case 187:case 188:case 190:case 191:case 192:case 222:return!1}if(v&&d&&b==a)return!1;switch(a){case 13:return!0;case 27:return!x}return qc(a)},qc=function(a){if(48<=a&&57>=a||96<=a&&106>=a||65<=a&&90>=a||x&&0==a)return!0;switch(a){case 32:case 63:case 107:case 109:case 110:case 111:case 186:case 59:case 189:case 187:case 61:case 188:case 190:case 191:case 192:case 222:case 219:case 220:case 221:return!0;
 default:return!1}},rc=function(a){if(w)a=tc(a);else if(y&&x)t:switch(a){case 93:a=91;break t}return a},tc=function(a){switch(a){case 61:return 187;case 59:return 186;case 173:return 189;case 224:return 91;case 0:return 224;default:return a}};var O=function(a,b){H.call(this);a&&uc(this,a,b)};p(O,H);f=O.prototype;f.d=null;f.Ia=null;f.Ya=null;f.Ja=null;f.r=-1;f.N=-1;f.lb=!1;
-var vc={3:13,12:144,63232:38,63233:40,63234:37,63235:39,63236:112,63237:113,63238:114,63239:115,63240:116,63241:117,63242:118,63243:119,63244:120,63245:121,63246:122,63247:123,63248:44,63272:46,63273:36,63275:35,63276:33,63277:34,63289:144,63302:45},wc={Up:38,Down:40,Left:37,Right:39,Enter:13,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"U+007F":46,Home:36,End:35,PageUp:33,PageDown:34,Insert:45},xc=v||x&&z("525"),yc=y&&w;
+var vc={3:13,12:144,63232:38,63233:40,63234:37,63235:39,63236:112,63237:113,63238:114,63239:115,63240:116,63241:117,63242:118,63243:119,63244:120,63245:121,63246:122,63247:123,63248:44,63272:46,63273:36,63275:35,63276:33,63277:34,63289:144,63302:45},wc={Up:38,Down:40,Left:37,Right:39,Enter:13,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"U+007F":46,Home:36,End:35,PageUp:33,PageDown:34,Insert:45},xc=v||x&&A("525"),yc=y&&w;
 O.prototype.Tb=function(a){x&&(17==this.r&&!a.ctrlKey||18==this.r&&!a.altKey||y&&91==this.r&&!a.metaKey)&&(this.N=this.r=-1);-1==this.r&&(a.ctrlKey&&17!=a.keyCode?this.r=17:a.altKey&&18!=a.keyCode?this.r=18:a.metaKey&&91!=a.keyCode&&(this.r=91));xc&&!sc(a.keyCode,this.r,a.shiftKey,a.ctrlKey,a.altKey)?this.handleEvent(a):(this.N=rc(a.keyCode),yc&&(this.lb=a.altKey))};O.prototype.Ub=function(a){this.N=this.r=-1;this.lb=a.altKey};
 O.prototype.handleEvent=function(a){var b=a.O,c,d,e=b.altKey;v&&"keypress"==a.type?(c=this.N,d=13!=c&&27!=c?b.keyCode:0):x&&"keypress"==a.type?(c=this.N,d=0<=b.charCode&&63232>b.charCode&&qc(c)?b.charCode:0):Va?(c=this.N,d=qc(c)?b.keyCode:0):(c=b.keyCode||this.N,d=b.charCode||0,yc&&(e=this.lb),y&&63==d&&224==c&&(c=191));var g=c=rc(c),h=b.keyIdentifier;c?63232<=c&&c in vc?g=vc[c]:25==c&&a.shiftKey&&(g=9):h&&h in wc&&(g=wc[h]);a=g==this.r;this.r=g;b=new zc(g,d,a,b);b.altKey=e;this.dispatchEvent(b)};
 O.prototype.a=function(){return this.d};var uc=function(a,b,c){a.Ja&&a.detach();a.d=b;a.Ia=E(a.d,"keypress",a,c);a.Ya=E(a.d,"keydown",a.Tb,c,a);a.Ja=E(a.d,"keyup",a.Ub,c,a)};O.prototype.detach=function(){this.Ia&&(F(this.Ia),F(this.Ya),F(this.Ja),this.Ja=this.Ya=this.Ia=null);this.d=null;this.N=this.r=-1};var zc=function(a,b,c,d){C.call(this,d);this.type="key";this.keyCode=a;this.charCode=b;this.repeat=c};p(zc,C);var Q=function(a){if(a.classList)return a.classList;a=a.className;return m(a)&&a.match(/\S+/g)||[]},Ac=function(a,b){return a.classList?a.classList.contains(b):t(Q(a),b)},Bc=function(a,b){a.classList?a.classList.add(b):Ac(a,b)||(a.className+=0<a.className.length?" "+b:b)},Cc=function(a,b){if(a.classList)s(b,function(b){Bc(a,b)});else{var c={};s(Q(a),function(a){c[a]=!0});s(b,function(a){c[a]=!0});a.className="";for(var d in c)a.className+=0<a.className.length?" "+d:d}},Dc=function(a,b){a.classList?
 a.classList.remove(b):Ac(a,b)&&(a.className=Ca(Q(a),function(a){return a!=b}).join(" "))},Ec=function(a,b){a.classList?s(b,function(b){Dc(a,b)}):a.className=Ca(Q(a),function(a){return!t(b,a)}).join(" ")};var Gc=function(a,b){if(!a)throw Error("Invalid class name "+a);if(!n(b))throw Error("Invalid decorator function "+b);Fc[a]=b},Hc={},Fc={};var R=function(a){this.Hb=a};ba(R);R.prototype.fa=function(){return this.Hb};var Ic=function(a,b){a&&(a.tabIndex=b?0:-1)};f=R.prototype;f.o=function(a){return a.mb().o("div",this.ta(a).join(" "))};f.C=function(a){return a};f.X=function(a){return"DIV"==a.tagName};f.K=function(a,b){b.id&&dc(a,b.id);var c=this.v(),d=!1,e=Q(b);e&&s(e,function(b){b==c?d=!0:b&&this.bb(a,b,c)},this);d||Bc(b,c);Jc(a,this.C(b));return b};
 f.bb=function(a,b,c){b==c+"-disabled"?a.ca(!1):b==c+"-horizontal"?Kc(a,"horizontal"):b==c+"-vertical"&&Kc(a,"vertical")};var Jc=function(a,b){if(b)for(var c=b.firstChild,d;c&&c.parentNode==b;){d=c.nextSibling;if(1==c.nodeType){var e;t:{var g=c;e=void 0;q(g);for(var g=Q(g),h=0,k=g.length;h<k;h++)if(e=g[h],e=e in Fc?Fc[e]():null)break t;e=null}e&&(e.d=c,a.isEnabled()||e.ca(!1),a.Da(e),e.K(c))}else c.nodeValue&&""!=oa(c.nodeValue)||b.removeChild(c);c=d}};
-R.prototype.Oa=function(a){a=a.a();q(a,"The container DOM element cannot be null.");Zb(a,!0,w);v&&(a.hideFocus=!0);var b=this.fa();b&&nc(a,b)};R.prototype.j=function(a){return a.a()};R.prototype.v=function(){return"goog-container"};R.prototype.ta=function(a){var b=this.v(),c=[b,"horizontal"==a.L?b+"-horizontal":b+"-vertical"];a.isEnabled()||c.push(b+"-disabled");return c};var S=function(){},Lc;ba(S);var Mc={button:"pressed",checkbox:"checked",menuitem:"selected",menuitemcheckbox:"checked",menuitemradio:"checked",radio:"checked",tab:"selected",treeitem:"selected"};f=S.prototype;f.fa=function(){};f.o=function(a){var b=a.mb().o("div",this.ta(a).join(" "),a.Ba);Nc(a,b);return b};f.C=function(a){return a};f.sa=function(a,b,c){if(a=a.a?a.a():a){var d=[b];v&&!z("7")&&(d=Oc(Q(a),b),d.push(b));(c?Cc:Ec)(a,d)}};f.X=function(){return!0};
-f.K=function(a,b){b.id&&dc(a,b.id);var c=this.C(b);c&&c.firstChild?Pc(a,c.firstChild.nextSibling?Fa(c.childNodes):c.firstChild):a.Ba=null;var d=0,e=this.v(),g=this.v(),h=!1,k=!1,I=!1,A=Fa(Q(b));s(A,function(a){h||a!=e?k||a!=g?d|=Qc(this,a):k=!0:(h=!0,g==e&&(k=!0));1==Qc(this,a)&&tb(c)&&ub(c,!1)},this);a.h=d;h||(A.push(e),g==e&&(k=!0));k||A.push(g);var K=a.G;K&&A.push.apply(A,K);if(v&&!z("7")){var P=Oc(A);0<P.length&&(A.push.apply(A,P),I=!0)}if(!h||!k||K||I)b.className=A.join(" ");Nc(a,b);return b};
+R.prototype.Oa=function(a){a=a.a();q(a,"The container DOM element cannot be null.");Zb(a,!0,w);v&&(a.hideFocus=!0);var b=this.fa();b&&nc(a,b)};R.prototype.j=function(a){return a.a()};R.prototype.v=function(){return"goog-container"};R.prototype.ta=function(a){var b=this.v(),c=[b,"horizontal"==a.L?b+"-horizontal":b+"-vertical"];a.isEnabled()||c.push(b+"-disabled");return c};var S=function(){},Lc;ba(S);var Mc={button:"pressed",checkbox:"checked",menuitem:"selected",menuitemcheckbox:"checked",menuitemradio:"checked",radio:"checked",tab:"selected",treeitem:"selected"};f=S.prototype;f.fa=function(){};f.o=function(a){var b=a.mb().o("div",this.ta(a).join(" "),a.Ba);Nc(a,b);return b};f.C=function(a){return a};f.sa=function(a,b,c){if(a=a.a?a.a():a){var d=[b];v&&!A("7")&&(d=Oc(Q(a),b),d.push(b));(c?Cc:Ec)(a,d)}};f.X=function(){return!0};
+f.K=function(a,b){b.id&&dc(a,b.id);var c=this.C(b);c&&c.firstChild?Pc(a,c.firstChild.nextSibling?Fa(c.childNodes):c.firstChild):a.Ba=null;var d=0,e=this.v(),g=this.v(),h=!1,k=!1,I=!1,z=Fa(Q(b));s(z,function(a){h||a!=e?k||a!=g?d|=Qc(this,a):k=!0:(h=!0,g==e&&(k=!0));1==Qc(this,a)&&tb(c)&&ub(c,!1)},this);a.h=d;h||(z.push(e),g==e&&(k=!0));k||z.push(g);var K=a.G;K&&z.push.apply(z,K);if(v&&!A("7")){var P=Oc(z);0<P.length&&(z.push.apply(z,P),I=!0)}if(!h||!k||K||I)b.className=z.join(" ");Nc(a,b);return b};
 f.Oa=function(a){ic(a)&&this.ra(a.a(),!0);a.isEnabled()&&this.oa(a,a.s())};var Rc=function(a,b,c){if(a=c||a.fa())q(b,"The element passed as a first parameter cannot be null."),c=b.getAttribute("role")||null,a!=c&&nc(b,a)},Nc=function(a,b){q(a);q(b);a.s()||pc(b,"hidden",!a.s());a.isEnabled()||Sc(b,1,!a.isEnabled());a.l&8&&Sc(b,8,!!(a.h&8));a.l&16&&Sc(b,16,!!(a.h&16));a.l&64&&Sc(b,64,!!(a.h&64))};f=S.prototype;f.za=function(a,b){Zb(a,!b,!v&&!Va)};f.ra=function(a,b){this.sa(a,this.v()+"-rtl",b)};
 f.I=function(a){var b;return a.l&32&&(b=a.j())?tb(b):!1};f.oa=function(a,b){var c;if(a.l&32&&(c=a.j())){if(!b&&a.h&32){try{c.blur()}catch(d){}a.h&32&&a.ma(null)}tb(c)!=b&&ub(c,b)}};f.ka=function(a,b){J(a,b);a&&pc(a,"hidden",!b)};f.t=function(a,b,c){var d=a.a();if(d){var e=Tc(this,b);e&&this.sa(a,e,c);Sc(d,b,c)}};
 var Sc=function(a,b,c){Lc||(Lc={1:"disabled",8:"selected",16:"checked",64:"expanded"});q(a,"The element passed as a first parameter cannot be null.");b=Lc[b];var d=a.getAttribute("role")||null;d&&(d=Mc[d]||b,b="checked"==b||"selected"==b?d:b);b&&pc(a,b,c)};S.prototype.j=function(a){return a.a()};S.prototype.v=function(){return"goog-control"};
-S.prototype.ta=function(a){var b=this.v(),c=[b],d=this.v();d!=b&&c.push(d);b=a.h;for(d=[];b;){var e=b&-b;d.push(Tc(this,e));b&=~e}c.push.apply(c,d);(a=a.G)&&c.push.apply(c,a);v&&!z("7")&&c.push.apply(c,Oc(c));return c};
+S.prototype.ta=function(a){var b=this.v(),c=[b],d=this.v();d!=b&&c.push(d);b=a.h;for(d=[];b;){var e=b&-b;d.push(Tc(this,e));b&=~e}c.push.apply(c,d);(a=a.G)&&c.push.apply(c,a);v&&!A("7")&&c.push.apply(c,Oc(c));return c};
 var Oc=function(a,b){var c=[];b&&(a=a.concat([b]));s([],function(d){!Da(d,ja(t,a))||b&&!t(d,b)||c.push(d.join("_"))});return c},Tc=function(a,b){a.Na||Uc(a);return a.Na[b]},Qc=function(a,b){a.Gb||(a.Na||Uc(a),a.Gb=Pa(a.Na));var c=parseInt(a.Gb[b],10);return isNaN(c)?0:c},Uc=function(a){var b=a.v(),c=b.replace(/\xa0|\s/g," ");q(-1==c.indexOf(" "),"ControlRenderer has an invalid css class: '"+b+"'");a.Na={1:b+"-disabled",2:b+"-hover",4:b+"-active",8:b+"-selected",16:b+"-checked",32:b+"-focused",64:b+
 "-open"}};var T=function(a,b,c){L.call(this,c);if(!b){b=this.constructor;for(var d;b;){d=ia(b);if(d=Hc[d])break;b=b.f?b.f.constructor:null}b=d?n(d.ia)?d.ia():new d:null}this.b=b;this.Ba=void 0!==a?a:null};p(T,L);f=T.prototype;f.Ba=null;f.h=0;f.l=39;f.ec=255;f.T=0;f.n=!0;f.G=null;f.Z=!0;f.xa=!1;f.sb=null;f.qb=function(){return this.Z};f.Pa=function(a){this.g&&a!=this.Z&&Vc(this,a);this.Z=a};f.j=function(){return this.b.j(this)};f.ya=function(){return this.ga||(this.ga=new O)};f.Ab=function(){return this.b};
 f.sa=function(a,b){b?a&&(this.G?t(this.G,a)||this.G.push(a):this.G=[a],this.b.sa(this,a,!0)):a&&this.G&&Ea(this.G,a)&&(0==this.G.length&&(this.G=null),this.b.sa(this,a,!1))};f.o=function(){var a=this.b.o(this);this.d=a;Rc(this.b,a,this.sb);this.xa||this.b.za(a,!1);this.s()||this.b.ka(a,!1)};f.C=function(){return this.b.C(this.a())};f.X=function(a){return this.b.X(a)};f.Za=function(a){this.d=a=this.b.K(this,a);Rc(this.b,a,this.sb);this.xa||this.b.za(a,!1);this.n="none"!=a.style.display};
diff --git a/google/appengine/ext/datastore_admin/static/js/compiled.js b/google/appengine/ext/datastore_admin/static/js/compiled.js
index 800e10c..9b86048 100644
--- a/google/appengine/ext/datastore_admin/static/js/compiled.js
+++ b/google/appengine/ext/datastore_admin/static/js/compiled.js
@@ -7,7 +7,7 @@
 Ha.compatMode?aa(Fa,10):5):void 0;var Ja=!Q||Q&&9<=Ia;!R&&!Q||Q&&Q&&9<=Ia||R&&T("1.9.1");Q&&T("9");var W=function(a,b){return L(b)?a.getElementById(b):b},Ka=function(a,b,c,d){a=d||a;var f=b&&"*"!=b?b.toUpperCase():"";if(a.querySelectorAll&&a.querySelector&&(f||c))return a.querySelectorAll(f+(c?"."+c:""));if(c&&a.getElementsByClassName){b=a.getElementsByClassName(c);if(f){a={};for(var e=d=0,h;h=b[e];e++)f==h.nodeName&&(a[d++]=h);a.length=d;return a}return b}b=a.getElementsByTagName(f||"*");if(c){a={};for(e=d=0;h=b[e];e++){var f=h.className,l;if(l="function"==typeof f[y])l=0<=va(f[y](/\s+/),c);l&&
 (a[d++]=h)}a.length=d;return a}return b},Ma=function(a,b){ya(b,function(b,d){"style"==d?a[z].cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in La?a.setAttribute(La[d],b):0==d.lastIndexOf("aria-",0)||0==d.lastIndexOf("data-",0)?a.setAttribute(d,b):a[d]=b})},La={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"},Oa=function(a,
 b,c){var d=arguments,f=d[0],e=d[1];if(!Ja&&e&&(e[ca]||e[E])){f=["<",f];e[ca]&&f[A](' name="',qa(e[ca]),'"');if(e[E]){f[A](' type="',qa(e[E]),'"');var h={};Aa(h,e);delete h[E];e=h}f[A](">");f=f.join("")}f=g.createElement(f);e&&(L(e)?f.className=e:"array"==K(e)?f.className=e.join(" "):Ma(f,e));2<d[F]&&Na(g,f,d,2);return f},Na=function(a,b,c,d){function f(c){c&&b.appendChild(L(c)?a.createTextNode(c):c)}for(;d<c[F];d++){var e=c[d];if(!ea(e)||fa(e)&&0<e.nodeType)f(e);else{var h;t:{if(e&&"number"==typeof e[F]){if(fa(e)){h=
-"function"==typeof e.item||"string"==typeof e.item;break t}if("function"==K(e)){h="function"==typeof e.item;break t}}h=!1}wa(h?xa(e):e,f)}}};var Pa=function(a){var b=a[E];if(void 0===b)return null;switch(b.toLowerCase()){case "checkbox":case "radio":return a[ba]?a[C]:null;case "select-one":return b=a.selectedIndex,0<=b?a.options[b][C]:null;case "select-multiple":for(var b=[],c,d=0;c=a.options[d];d++)c.selected&&b[A](c[C]);return b[F]?b:null;default:return void 0!==a[C]?a[C]:null}};var Qa=function(a){Qa[" "](a);return a};Qa[" "]=function(){};var Ra=!Q||Q&&9<=Ia,Sa=Q&&!T("9");!S||T("528");R&&T("1.9b")||Q&&T("8")||Da&&T("9.5")||S&&T("528");R&&!T("8")||Q&&T("9");var Ta=function(a,b){this.type=a;this.target=b;q(this,this[da]);this.defaultPrevented=this.o=!1};Ta[G].preventDefault=function(){this.defaultPrevented=!0};R&&T(17);var X=function(a,b){Ta[H](this,a?a[E]:"");this.target=null;q(this,null);this.relatedTarget=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;p(this,0);this.charCode=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.p=this.state=null;a&&this.u(a,b)};ga(X,Ta);
+"function"==typeof e.item||"string"==typeof e.item;break t}if("function"==K(e)){h="function"==typeof e.item;break t}}h=!1}wa(h?xa(e):e,f)}}};var Pa=function(a){var b=a[E];if(void 0===b)return null;switch(b.toLowerCase()){case "checkbox":case "radio":return a[ba]?a[C]:null;case "select-one":return b=a.selectedIndex,0<=b?a.options[b][C]:null;case "select-multiple":for(var b=[],c,d=0;c=a.options[d];d++)c.selected&&b[A](c[C]);return b[F]?b:null;default:return void 0!==a[C]?a[C]:null}};var Qa=function(a){Qa[" "](a);return a};Qa[" "]=function(){};var Ra=!Q||Q&&9<=Ia,Sa=Q&&!T("9");!S||T("528");R&&T("1.9b")||Q&&T("8")||Da&&T("9.5")||S&&T("528");R&&!T("8")||Q&&T("9");var Ta=function(a,b){this.type=a;this.target=b;q(this,this[da]);this.defaultPrevented=this.o=!1};Ta[G].preventDefault=function(){this.defaultPrevented=!0};var X=function(a,b){Ta[H](this,a?a[E]:"");this.target=null;q(this,null);this.relatedTarget=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;p(this,0);this.charCode=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.p=this.state=null;a&&this.u(a,b)};ga(X,Ta);
 X[G].u=function(a,b){var c=this.type=a[E];this.target=a[da]||a.srcElement;q(this,b);var d=a.relatedTarget;if(d){if(R){var f;t:{try{Qa(d.nodeName);f=!0;break t}catch(e){}f=!1}f||(d=null)}}else"mouseover"==c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=S||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=S||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||
 0;this.screenY=a.screenY||0;this.button=a.button;p(this,a[v]||0);this.charCode=a.charCode||("keypress"==c?a[v]:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.state=a.state;this.p=a;a.defaultPrevented&&this[u]()};X[G].preventDefault=function(){X.t[u][H](this);var a=this.p;if(a[u])a[u]();else if(a.returnValue=!1,Sa)try{(a.ctrlKey||112<=a[v]&&123>=a[v])&&p(a,-1)}catch(b){}};var Ua="closure_listenable_"+(1E6*Math.random()|0),Va=0;var Wa=function(a,b,c,d,f,e){this.c=a;this.g=b;this.src=c;this.type=d;this.k=!!f;this.j=e;this.key=++Va;this.e=this.l=!1};Wa[G].n=function(){this.e=!0;this.j=this.src=this.g=this.c=null};var Xa=function(a){this.src=a;this.a={};this.m=0};Xa[G].add=function(a,b,c,d,f){var e=a[w]();a=this.a[e];a||(a=this.a[e]=[],this.m++);var h;t:{for(h=0;h<a[F];++h){var l=a[h];if(!l.e&&l.c==b&&l.k==!!d&&l.j==f)break t}h=-1}-1<h?(b=a[h],c||(b.l=!1)):(b=new Wa(b,null,this.src,e,!!d,f),b.l=c,a[A](b));return b};Xa[G].q=function(a){var b=a[E];if(!(b in this.a))return!1;var c=this.a[b],d=va(c,a),f;if(f=0<=d)N(null!=c[F]),O.splice[H](c,d,1);f&&(a.n(),0==this.a[b][F]&&(delete this.a[b],this.m--));return f};var Ya="closure_lm_"+(1E6*Math.random()|0),Za={},$a=0,ab=function(a,b,c,d,f){if("array"==K(b)){for(var e=0;e<b[F];e++)ab(a,b[e],c,d,f);return null}c=bb(c);if(a&&a[Ua])a=a.w(b,c,d,f);else{if(!b)throw m("Invalid event type");var e=!!d,h=eb(a);h||(a[Ya]=h=new Xa(a));c=h.add(b,c,!1,d,f);c.g||(d=fb(),c.g=d,d.src=a,d.c=c,a.addEventListener?a.addEventListener(b[w](),d,e):a.attachEvent(gb(b[w]()),d),$a++);a=c}return a},fb=function(){var a=hb,b=Ra?function(c){return a[H](b.src,b.c,c)}:function(c){c=a[H](b.src,
 b.c,c);if(!c)return c};return b},gb=function(a){return a in Za?Za[a]:Za[a]="on"+a},jb=function(a,b,c,d){var f=1;if(a=eb(a))if(b=a.a[b[w]()])for(b=b.concat(),a=0;a<b[F];a++){var e=b[a];e&&e.k==c&&!e.e&&(f&=!1!==ib(e,d))}return Boolean(f)},ib=function(a,b){var c=a.c,d=a.j||a.src;if(a.l&&"number"!=typeof a&&a&&!a.e){var f=a.src;if(f&&f[Ua])f.v(a);else{var e=a[E],h=a.g;f.removeEventListener?f.removeEventListener(e,h,a.k):f.detachEvent&&f.detachEvent(gb(e),h);$a--;(e=eb(f))?(e.q(a),0==e.m&&(e.src=null,
diff --git a/google/appengine/tools/appcfg_java.py b/google/appengine/tools/appcfg_java.py
index 6045c22..c6b6e53 100644
--- a/google/appengine/tools/appcfg_java.py
+++ b/google/appengine/tools/appcfg_java.py
@@ -26,12 +26,13 @@
 import sys
 import tempfile
 
+from google.appengine.datastore import datastore_index
+from google.appengine.datastore import datastore_index_xml
 from google.appengine.tools import app_engine_web_xml_parser
 from google.appengine.tools import backends_xml_parser
 from google.appengine.tools import cron_xml_parser
 from google.appengine.tools import dispatch_xml_parser
 from google.appengine.tools import dos_xml_parser
-from google.appengine.tools import indexes_xml_parser
 from google.appengine.tools import jarfile
 from google.appengine.tools import queue_xml_parser
 from google.appengine.tools import web_xml_parser
@@ -281,10 +282,11 @@
       if os.path.exists(xml_name):
         with open(xml_name) as xml_file:
           xml_string = xml_file.read()
-        parser = indexes_xml_parser.IndexesXmlParser()
-        indexes += parser.ProcessXml(xml_string)
+        index_definitions = datastore_index_xml.IndexesXmlToIndexDefinitions(
+            xml_string)
+        indexes.extend(index_definitions.indexes)
     if indexes:
-      yaml_string = indexes_xml_parser.MakeIndexesListIntoYaml(indexes)
+      yaml_string = datastore_index.IndexDefinitions(indexes=indexes).ToYAML()
       yaml_file = os.path.join(appengine_generated, 'index.yaml')
       with open(yaml_file, 'w') as yaml:
         yaml.write(yaml_string)
diff --git a/google/appengine/tools/dev-channel-js.js b/google/appengine/tools/dev-channel-js.js
index ce3809f..db6866c 100644
--- a/google/appengine/tools/dev-channel-js.js
+++ b/google/appengine/tools/dev-channel-js.js
@@ -141,6 +141,13 @@
   var bootstrap = 'goog.retrieveAndExecModule_("' + src + '");';
   goog.importScript_("", bootstrap) && (goog.dependencies_.written[src] = !0);
 }, goog.queuedModules_ = [], goog.retrieveAndExecModule_ = function(src) {
+  for (var separator;-1 != (separator = src.indexOf("/./"));) {
+    src = src.substr(0, separator) + src.substr(separator + 2);
+  }
+  for (;-1 != (separator = src.indexOf("/../"));) {
+    var previousComponent = src.lastIndexOf("/", separator - 1);
+    src = src.substr(0, previousComponent) + src.substr(separator + 3);
+  }
   var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_, scriptText = null, xhr = new goog.global.XMLHttpRequest;
   xhr.onload = function() {
     scriptText = this.responseText;
@@ -2999,13 +3006,13 @@
 goog.events.getVendorPrefixedName_ = function(eventName) {
   return goog.userAgent.WEBKIT ? "webkit" + eventName : goog.userAgent.OPERA ? "o" + eventName.toLowerCase() : eventName.toLowerCase();
 };
-goog.events.EventType = {CLICK:"click", RIGHTCLICK:"rightclick", DBLCLICK:"dblclick", MOUSEDOWN:"mousedown", MOUSEUP:"mouseup", MOUSEOVER:"mouseover", MOUSEOUT:"mouseout", MOUSEMOVE:"mousemove", MOUSEENTER:"mouseenter", MOUSELEAVE:"mouseleave", MOUSEWHEEL:goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher(17) ? "DOMMouseScroll" : "mousewheel", SELECTSTART:"selectstart", WHEEL:"wheel", KEYPRESS:"keypress", KEYDOWN:"keydown", KEYUP:"keyup", BLUR:"blur", FOCUS:"focus", DEACTIVATE:"deactivate", 
-FOCUSIN:goog.userAgent.IE ? "focusin" : "DOMFocusIn", FOCUSOUT:goog.userAgent.IE ? "focusout" : "DOMFocusOut", CHANGE:"change", SELECT:"select", SUBMIT:"submit", INPUT:"input", PROPERTYCHANGE:"propertychange", DRAGSTART:"dragstart", DRAG:"drag", DRAGENTER:"dragenter", DRAGOVER:"dragover", DRAGLEAVE:"dragleave", DROP:"drop", DRAGEND:"dragend", TOUCHSTART:"touchstart", TOUCHMOVE:"touchmove", TOUCHEND:"touchend", TOUCHCANCEL:"touchcancel", BEFOREUNLOAD:"beforeunload", CONSOLEMESSAGE:"consolemessage", 
-CONTEXTMENU:"contextmenu", DOMCONTENTLOADED:"DOMContentLoaded", ERROR:"error", HELP:"help", LOAD:"load", LOSECAPTURE:"losecapture", ORIENTATIONCHANGE:"orientationchange", READYSTATECHANGE:"readystatechange", RESIZE:"resize", SCROLL:"scroll", UNLOAD:"unload", HASHCHANGE:"hashchange", PAGEHIDE:"pagehide", PAGESHOW:"pageshow", POPSTATE:"popstate", COPY:"copy", PASTE:"paste", CUT:"cut", BEFORECOPY:"beforecopy", BEFORECUT:"beforecut", BEFOREPASTE:"beforepaste", ONLINE:"online", OFFLINE:"offline", MESSAGE:"message", 
-CONNECT:"connect", ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"), ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"), ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"), TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"), POINTERDOWN:"pointerdown", POINTERUP:"pointerup", POINTERCANCEL:"pointercancel", POINTERMOVE:"pointermove", POINTEROVER:"pointerover", POINTEROUT:"pointerout", POINTERENTER:"pointerenter", POINTERLEAVE:"pointerleave", 
-GOTPOINTERCAPTURE:"gotpointercapture", LOSTPOINTERCAPTURE:"lostpointercapture", MSGESTURECHANGE:"MSGestureChange", MSGESTUREEND:"MSGestureEnd", MSGESTUREHOLD:"MSGestureHold", MSGESTURESTART:"MSGestureStart", MSGESTURETAP:"MSGestureTap", MSGOTPOINTERCAPTURE:"MSGotPointerCapture", MSINERTIASTART:"MSInertiaStart", MSLOSTPOINTERCAPTURE:"MSLostPointerCapture", MSPOINTERCANCEL:"MSPointerCancel", MSPOINTERDOWN:"MSPointerDown", MSPOINTERENTER:"MSPointerEnter", MSPOINTERHOVER:"MSPointerHover", MSPOINTERLEAVE:"MSPointerLeave", 
-MSPOINTERMOVE:"MSPointerMove", MSPOINTEROUT:"MSPointerOut", MSPOINTEROVER:"MSPointerOver", MSPOINTERUP:"MSPointerUp", TEXTINPUT:"textinput", COMPOSITIONSTART:"compositionstart", COMPOSITIONUPDATE:"compositionupdate", COMPOSITIONEND:"compositionend", EXIT:"exit", LOADABORT:"loadabort", LOADCOMMIT:"loadcommit", LOADREDIRECT:"loadredirect", LOADSTART:"loadstart", LOADSTOP:"loadstop", RESPONSIVE:"responsive", SIZECHANGED:"sizechanged", UNRESPONSIVE:"unresponsive", VISIBILITYCHANGE:"visibilitychange", 
-STORAGE:"storage", DOMSUBTREEMODIFIED:"DOMSubtreeModified", DOMNODEINSERTED:"DOMNodeInserted", DOMNODEREMOVED:"DOMNodeRemoved", DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument", DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument", DOMATTRMODIFIED:"DOMAttrModified", DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified"};
+goog.events.EventType = {CLICK:"click", RIGHTCLICK:"rightclick", DBLCLICK:"dblclick", MOUSEDOWN:"mousedown", MOUSEUP:"mouseup", MOUSEOVER:"mouseover", MOUSEOUT:"mouseout", MOUSEMOVE:"mousemove", MOUSEENTER:"mouseenter", MOUSELEAVE:"mouseleave", SELECTSTART:"selectstart", WHEEL:"wheel", KEYPRESS:"keypress", KEYDOWN:"keydown", KEYUP:"keyup", BLUR:"blur", FOCUS:"focus", DEACTIVATE:"deactivate", FOCUSIN:goog.userAgent.IE ? "focusin" : "DOMFocusIn", FOCUSOUT:goog.userAgent.IE ? "focusout" : "DOMFocusOut", 
+CHANGE:"change", SELECT:"select", SUBMIT:"submit", INPUT:"input", PROPERTYCHANGE:"propertychange", DRAGSTART:"dragstart", DRAG:"drag", DRAGENTER:"dragenter", DRAGOVER:"dragover", DRAGLEAVE:"dragleave", DROP:"drop", DRAGEND:"dragend", TOUCHSTART:"touchstart", TOUCHMOVE:"touchmove", TOUCHEND:"touchend", TOUCHCANCEL:"touchcancel", BEFOREUNLOAD:"beforeunload", CONSOLEMESSAGE:"consolemessage", CONTEXTMENU:"contextmenu", DOMCONTENTLOADED:"DOMContentLoaded", ERROR:"error", HELP:"help", LOAD:"load", LOSECAPTURE:"losecapture", 
+ORIENTATIONCHANGE:"orientationchange", READYSTATECHANGE:"readystatechange", RESIZE:"resize", SCROLL:"scroll", UNLOAD:"unload", HASHCHANGE:"hashchange", PAGEHIDE:"pagehide", PAGESHOW:"pageshow", POPSTATE:"popstate", COPY:"copy", PASTE:"paste", CUT:"cut", BEFORECOPY:"beforecopy", BEFORECUT:"beforecut", BEFOREPASTE:"beforepaste", ONLINE:"online", OFFLINE:"offline", MESSAGE:"message", CONNECT:"connect", ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"), ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"), 
+ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"), TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"), POINTERDOWN:"pointerdown", POINTERUP:"pointerup", POINTERCANCEL:"pointercancel", POINTERMOVE:"pointermove", POINTEROVER:"pointerover", POINTEROUT:"pointerout", POINTERENTER:"pointerenter", POINTERLEAVE:"pointerleave", GOTPOINTERCAPTURE:"gotpointercapture", LOSTPOINTERCAPTURE:"lostpointercapture", MSGESTURECHANGE:"MSGestureChange", MSGESTUREEND:"MSGestureEnd", 
+MSGESTUREHOLD:"MSGestureHold", MSGESTURESTART:"MSGestureStart", MSGESTURETAP:"MSGestureTap", MSGOTPOINTERCAPTURE:"MSGotPointerCapture", MSINERTIASTART:"MSInertiaStart", MSLOSTPOINTERCAPTURE:"MSLostPointerCapture", MSPOINTERCANCEL:"MSPointerCancel", MSPOINTERDOWN:"MSPointerDown", MSPOINTERENTER:"MSPointerEnter", MSPOINTERHOVER:"MSPointerHover", MSPOINTERLEAVE:"MSPointerLeave", MSPOINTERMOVE:"MSPointerMove", MSPOINTEROUT:"MSPointerOut", MSPOINTEROVER:"MSPointerOver", MSPOINTERUP:"MSPointerUp", TEXTINPUT:"textinput", 
+COMPOSITIONSTART:"compositionstart", COMPOSITIONUPDATE:"compositionupdate", COMPOSITIONEND:"compositionend", EXIT:"exit", LOADABORT:"loadabort", LOADCOMMIT:"loadcommit", LOADREDIRECT:"loadredirect", LOADSTART:"loadstart", LOADSTOP:"loadstop", RESPONSIVE:"responsive", SIZECHANGED:"sizechanged", UNRESPONSIVE:"unresponsive", VISIBILITYCHANGE:"visibilitychange", STORAGE:"storage", DOMSUBTREEMODIFIED:"DOMSubtreeModified", DOMNODEINSERTED:"DOMNodeInserted", DOMNODEREMOVED:"DOMNodeRemoved", DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument", 
+DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument", DOMATTRMODIFIED:"DOMAttrModified", DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified"};
 goog.events.BrowserEvent = function(opt_e, opt_currentTarget) {
   goog.events.Event.call(this, opt_e ? opt_e.type : "");
   this.relatedTarget = this.currentTarget = this.target = null;
diff --git a/google/appengine/tools/devappserver2/health_check_service.py b/google/appengine/tools/devappserver2/health_check_service.py
index aef0294..c6b98a4 100644
--- a/google/appengine/tools/devappserver2/health_check_service.py
+++ b/google/appengine/tools/devappserver2/health_check_service.py
@@ -58,7 +58,7 @@
       self.consecutive_healthy_responses = 0
       self.consecutive_unhealthy_responses += 1
 
-  def __repr__(self):
+  def __str__(self):
     """Outputs the state in a readable way for logging."""
     tmpl = '{number} consecutive {state} responses.'
     if self.consecutive_healthy_responses:
@@ -67,7 +67,7 @@
     else:
       number = self.consecutive_unhealthy_responses
       state = 'UNHEALTHY'
-    return tmpl.format(numer=number, state=state)
+    return tmpl.format(number=number, state=state)
 
 
 class HealthChecker(object):
@@ -114,7 +114,7 @@
       logging.debug('Performing health check for instance %s.',
                     self._instance.instance_id)
       self._do_health_check(state)
-      logging.debug('Health check state for instance: %s: %r',
+      logging.debug('Health check state for instance: %s: %s',
                     self._instance.instance_id, state)
       time.sleep(self._config.check_interval_sec)
 
diff --git a/google/net/proto2/proto/descriptor_pb2.py b/google/net/proto2/proto/descriptor_pb2.py
index 0cac5d7..c8ae767 100644
--- a/google/net/proto2/proto/descriptor_pb2.py
+++ b/google/net/proto2/proto/descriptor_pb2.py
@@ -33,7 +33,7 @@
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='net/proto2/proto/descriptor.proto',
   package='proto2',
-  serialized_pb=_b('\n!net/proto2/proto/descriptor.proto\x12\x06proto2\">\n\x11\x46ileDescriptorSet\x12)\n\x04\x66ile\x18\x01 \x03(\x0b\x32\x1b.proto2.FileDescriptorProto\"\xa5\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12-\n\x0cmessage_type\x18\x04 \x03(\x0b\x32\x17.proto2.DescriptorProto\x12.\n\tenum_type\x18\x05 \x03(\x0b\x32\x1b.proto2.EnumDescriptorProto\x12/\n\x07service\x18\x06 \x03(\x0b\x32\x1e.proto2.ServiceDescriptorProto\x12/\n\textension\x18\x07 \x03(\x0b\x32\x1c.proto2.FieldDescriptorProto\x12$\n\x07options\x18\x08 \x01(\x0b\x32\x13.proto2.FileOptions\x12\x30\n\x10source_code_info\x18\t \x01(\x0b\x32\x16.proto2.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xa5\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x05\x66ield\x18\x02 \x03(\x0b\x32\x1c.proto2.FieldDescriptorProto\x12/\n\textension\x18\x06 \x03(\x0b\x32\x1c.proto2.FieldDescriptorProto\x12,\n\x0bnested_type\x18\x03 \x03(\x0b\x32\x17.proto2.DescriptorProto\x12.\n\tenum_type\x18\x04 \x03(\x0b\x32\x1b.proto2.EnumDescriptorProto\x12?\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32&.proto2.DescriptorProto.ExtensionRange\x12\x30\n\noneof_decl\x18\x08 \x03(\x0b\x32\x1c.proto2.OneofDescriptorProto\x12\'\n\x07options\x18\x07 \x01(\x0b\x32\x16.proto2.MessageOptions\x1a,\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\x8e\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12\x31\n\x05label\x18\x04 \x01(\x0e\x32\".proto2.FieldDescriptorProto.Label\x12/\n\x04type\x18\x05 \x01(\x0e\x32!.proto2.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12%\n\x07options\x18\x08 \x01(\x0b\x32\x14.proto2.FieldOptions\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"$\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\"z\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12/\n\x05value\x18\x02 \x03(\x0b\x32 .proto2.EnumValueDescriptorProto\x12$\n\x07options\x18\x03 \x01(\x0b\x32\x13.proto2.EnumOptions\"c\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12)\n\x07options\x18\x03 \x01(\x0b\x32\x18.proto2.EnumValueOptions\"\xad\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x06method\x18\x02 \x03(\x0b\x32\x1d.proto2.MethodDescriptorProto\x12-\n\x06stream\x18\x04 \x03(\x0b\x32\x1d.proto2.StreamDescriptorProto\x12\'\n\x07options\x18\x03 \x01(\x0b\x32\x16.proto2.ServiceOptions\"v\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12&\n\x07options\x18\x04 \x01(\x0b\x32\x15.proto2.MethodOptions\"\x87\x01\n\x15StreamDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1b\n\x13\x63lient_message_type\x18\x02 \x01(\t\x12\x1b\n\x13server_message_type\x18\x03 \x01(\t\x12&\n\x07options\x18\x04 \x01(\x0b\x32\x15.proto2.StreamOptions\"\xa5\n\n\x0b\x46ileOptions\x12\x19\n\x0e\x63\x63_api_version\x18\x02 \x01(\x05:\x01\x32\x12V\n\x14\x63\x63_api_compatibility\x18\x0f \x01(\x0e\x32&.proto2.FileOptions.CompatibilityLevel:\x10NO_COMPATIBILITY\x12\'\n\x19\x63\x63_proto_array_compatible\x18\x16 \x01(\x08:\x04true\x12\"\n\x14\x63\x63_utf8_verification\x18\x18 \x01(\x08:\x04true\x12$\n\x15\x63\x63_proto1_text_format\x18\x19 \x01(\x08:\x05\x66\x61lse\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x19\n\x0epy_api_version\x18\x04 \x01(\x05:\x01\x32\x12\x1b\n\x10java_api_version\x18\x05 \x01(\x05:\x01\x32\x12!\n\x13java_use_javaproto2\x18\x06 \x01(\x08:\x04true\x12\x1e\n\x10java_java5_enums\x18\x07 \x01(\x08:\x04true\x12)\n\x1ajava_generate_rpc_baseimpl\x18\r \x01(\x08:\x05\x66\x61lse\x12#\n\x14java_use_javastrings\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14java_alt_api_package\x18\x13 \x01(\t\x12\x34\n%java_enable_dual_generate_mutable_api\x18\x1a \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12,\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08:\x05\x66\x61lse\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10java_mutable_api\x18\x1c \x01(\x08:\x05\x66\x61lse\x12+\n#java_multiple_files_mutable_package\x18\x1d \x01(\t\x12=\n\x0coptimize_for\x18\t \x01(\x0e\x32 .proto2.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\x1a\n\x12javascript_package\x18\x0c \x01(\t\x12\x1a\n\x0fszl_api_version\x18\x0e \x01(\x05:\x01\x31\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x12\x65xperimental_style\x18\x1e \x01(\t\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\"c\n\x12\x43ompatibilityLevel\x12\x14\n\x10NO_COMPATIBILITY\x10\x00\x12\x15\n\x11PROTO1_COMPATIBLE\x10\x64\x12 \n\x1c\x44\x45PRECATED_PROTO1_COMPATIBLE\x10\x32\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xe4\x02\n\x0eMessageOptions\x12+\n#experimental_java_message_interface\x18\x04 \x03(\t\x12+\n#experimental_java_builder_interface\x18\x05 \x03(\t\x12+\n#experimental_java_interface_extends\x18\x06 \x03(\t\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x82\x05\n\x0c\x46ieldOptions\x12\x31\n\x05\x63type\x18\x01 \x01(\x0e\x32\x1a.proto2.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x31\n\x05jtype\x18\x04 \x01(\x0e\x32\x1a.proto2.FieldOptions.JType:\x06NORMAL\x12\x36\n\x06jstype\x18\x06 \x01(\x0e\x32\x1b.proto2.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12<\n\x0fupgraded_option\x18\x0b \x03(\x0b\x32#.proto2.FieldOptions.UpgradedOption\x12%\n\x16\x64\x65precated_raw_message\x18\x0c \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\x1a-\n\x0eUpgradedOption\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"<\n\x05JType\x12\n\n\x06NORMAL\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\x1c\n\x18\x45XPERIMENTAL_BYTE_BUFFER\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x99\x01\n\x0b\x45numOptions\x12\x13\n\x0bproto1_name\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"t\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xb6\x01\n\x0eServiceOptions\x12\x1d\n\x0emulticast_stub\x18\x14 \x01(\x08:\x05\x66\x61lse\x12#\n\x17\x66\x61ilure_detection_delay\x18\x10 \x01(\x01:\x02-1\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd3\t\n\rMethodOptions\x12\x35\n\x08protocol\x18\x07 \x01(\x0e\x32\x1e.proto2.MethodOptions.Protocol:\x03TCP\x12\x14\n\x08\x64\x65\x61\x64line\x18\x08 \x01(\x01:\x02-1\x12$\n\x15\x64uplicate_suppression\x18\t \x01(\x08:\x05\x66\x61lse\x12\x18\n\tfail_fast\x18\n \x01(\x08:\x05\x66\x61lse\x12\'\n\x18\x65nd_user_creds_requested\x18\x1a \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0e\x63lient_logging\x18\x0b \x01(\x11:\x03\x32\x35\x36\x12\x1b\n\x0eserver_logging\x18\x0c \x01(\x11:\x03\x32\x35\x36\x12\x41\n\x0esecurity_level\x18\r \x01(\x0e\x32#.proto2.MethodOptions.SecurityLevel:\x04NONE\x12\x43\n\x0fresponse_format\x18\x0f \x01(\x0e\x32\x1c.proto2.MethodOptions.Format:\x0cUNCOMPRESSED\x12\x42\n\x0erequest_format\x18\x11 \x01(\x0e\x32\x1c.proto2.MethodOptions.Format:\x0cUNCOMPRESSED\x12\x13\n\x0bstream_type\x18\x12 \x01(\t\x12\x16\n\x0esecurity_label\x18\x13 \x01(\t\x12\x18\n\x10\x63lient_streaming\x18\x14 \x01(\x08\x12\x18\n\x10server_streaming\x18\x15 \x01(\x08\x12\x1a\n\x12legacy_stream_type\x18\x16 \x01(\t\x12\x1a\n\x12legacy_result_type\x18\x17 \x01(\t\x12(\n\x1clegacy_client_initial_tokens\x18\x18 \x01(\x03:\x02-1\x12(\n\x1clegacy_server_initial_tokens\x18\x19 \x01(\x03:\x02-1\x12^\n\tlog_level\x18\x1b \x01(\x0e\x32\x1e.proto2.MethodOptions.LogLevel:+LOG_HEADER_AND_NON_PRIVATE_PAYLOAD_INTERNAL\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\"\x1c\n\x08Protocol\x12\x07\n\x03TCP\x10\x00\x12\x07\n\x03UDP\x10\x01\"e\n\rSecurityLevel\x12\x08\n\x04NONE\x10\x00\x12\r\n\tINTEGRITY\x10\x01\x12\x19\n\x15PRIVACY_AND_INTEGRITY\x10\x02\x12 \n\x1cSTRONG_PRIVACY_AND_INTEGRITY\x10\x03\"0\n\x06\x46ormat\x12\x10\n\x0cUNCOMPRESSED\x10\x00\x12\x14\n\x10ZIPPY_COMPRESSED\x10\x01\"\x9f\x01\n\x08LogLevel\x12\x0c\n\x08LOG_NONE\x10\x00\x12\x13\n\x0fLOG_HEADER_ONLY\x10\x01\x12/\n+LOG_HEADER_AND_NON_PRIVATE_PAYLOAD_INTERNAL\x10\x02\x12#\n\x1fLOG_HEADER_AND_FILTERED_PAYLOAD\x10\x03\x12\x1a\n\x16LOG_HEADER_AND_PAYLOAD\x10\x04*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xe7\x04\n\rStreamOptions\x12!\n\x15\x63lient_initial_tokens\x18\x01 \x01(\x03:\x02-1\x12!\n\x15server_initial_tokens\x18\x02 \x01(\x03:\x02-1\x12<\n\ntoken_unit\x18\x03 \x01(\x0e\x32\x1f.proto2.StreamOptions.TokenUnit:\x07MESSAGE\x12\x41\n\x0esecurity_level\x18\x04 \x01(\x0e\x32#.proto2.MethodOptions.SecurityLevel:\x04NONE\x12\x16\n\x0esecurity_label\x18\x05 \x01(\t\x12\x1b\n\x0e\x63lient_logging\x18\x06 \x01(\x05:\x03\x32\x35\x36\x12\x1b\n\x0eserver_logging\x18\x07 \x01(\x05:\x03\x32\x35\x36\x12\x14\n\x08\x64\x65\x61\x64line\x18\x08 \x01(\x01:\x02-1\x12\x18\n\tfail_fast\x18\t \x01(\x08:\x05\x66\x61lse\x12\'\n\x18\x65nd_user_creds_requested\x18\n \x01(\x08:\x05\x66\x61lse\x12^\n\tlog_level\x18\x0b \x01(\x0e\x32\x1e.proto2.MethodOptions.LogLevel:+LOG_HEADER_AND_NON_PRIVATE_PAYLOAD_INTERNAL\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\"\"\n\tTokenUnit\x12\x0b\n\x07MESSAGE\x10\x00\x12\x08\n\x04\x42YTE\x10\x01*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x95\x02\n\x13UninterpretedOption\x12\x32\n\x04name\x18\x02 \x03(\x0b\x32$.proto2.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xa8\x01\n\x0eSourceCodeInfo\x12\x31\n\x08location\x18\x01 \x03(\x0b\x32\x1f.proto2.SourceCodeInfo.Location\x1a\x63\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\tB,\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01\xe0\x01\x01')
+  serialized_pb=_b('\n!net/proto2/proto/descriptor.proto\x12\x06proto2\">\n\x11\x46ileDescriptorSet\x12)\n\x04\x66ile\x18\x01 \x03(\x0b\x32\x1b.proto2.FileDescriptorProto\"\xa5\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12-\n\x0cmessage_type\x18\x04 \x03(\x0b\x32\x17.proto2.DescriptorProto\x12.\n\tenum_type\x18\x05 \x03(\x0b\x32\x1b.proto2.EnumDescriptorProto\x12/\n\x07service\x18\x06 \x03(\x0b\x32\x1e.proto2.ServiceDescriptorProto\x12/\n\textension\x18\x07 \x03(\x0b\x32\x1c.proto2.FieldDescriptorProto\x12$\n\x07options\x18\x08 \x01(\x0b\x32\x13.proto2.FileOptions\x12\x30\n\x10source_code_info\x18\t \x01(\x0b\x32\x16.proto2.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xa5\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x05\x66ield\x18\x02 \x03(\x0b\x32\x1c.proto2.FieldDescriptorProto\x12/\n\textension\x18\x06 \x03(\x0b\x32\x1c.proto2.FieldDescriptorProto\x12,\n\x0bnested_type\x18\x03 \x03(\x0b\x32\x17.proto2.DescriptorProto\x12.\n\tenum_type\x18\x04 \x03(\x0b\x32\x1b.proto2.EnumDescriptorProto\x12?\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32&.proto2.DescriptorProto.ExtensionRange\x12\x30\n\noneof_decl\x18\x08 \x03(\x0b\x32\x1c.proto2.OneofDescriptorProto\x12\'\n\x07options\x18\x07 \x01(\x0b\x32\x16.proto2.MessageOptions\x1a,\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\x8e\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12\x31\n\x05label\x18\x04 \x01(\x0e\x32\".proto2.FieldDescriptorProto.Label\x12/\n\x04type\x18\x05 \x01(\x0e\x32!.proto2.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12%\n\x07options\x18\x08 \x01(\x0b\x32\x14.proto2.FieldOptions\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"$\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\"z\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12/\n\x05value\x18\x02 \x03(\x0b\x32 .proto2.EnumValueDescriptorProto\x12$\n\x07options\x18\x03 \x01(\x0b\x32\x13.proto2.EnumOptions\"c\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12)\n\x07options\x18\x03 \x01(\x0b\x32\x18.proto2.EnumValueOptions\"\xad\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x06method\x18\x02 \x03(\x0b\x32\x1d.proto2.MethodDescriptorProto\x12-\n\x06stream\x18\x04 \x03(\x0b\x32\x1d.proto2.StreamDescriptorProto\x12\'\n\x07options\x18\x03 \x01(\x0b\x32\x16.proto2.ServiceOptions\"v\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12&\n\x07options\x18\x04 \x01(\x0b\x32\x15.proto2.MethodOptions\"\x87\x01\n\x15StreamDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1b\n\x13\x63lient_message_type\x18\x02 \x01(\t\x12\x1b\n\x13server_message_type\x18\x03 \x01(\t\x12&\n\x07options\x18\x04 \x01(\x0b\x32\x15.proto2.StreamOptions\"\xc6\n\n\x0b\x46ileOptions\x12\x19\n\x0e\x63\x63_api_version\x18\x02 \x01(\x05:\x01\x32\x12V\n\x14\x63\x63_api_compatibility\x18\x0f \x01(\x0e\x32&.proto2.FileOptions.CompatibilityLevel:\x10NO_COMPATIBILITY\x12\'\n\x19\x63\x63_proto_array_compatible\x18\x16 \x01(\x08:\x04true\x12\"\n\x14\x63\x63_utf8_verification\x18\x18 \x01(\x08:\x04true\x12$\n\x15\x63\x63_proto1_text_format\x18\x19 \x01(\x08:\x05\x66\x61lse\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x19\n\x0epy_api_version\x18\x04 \x01(\x05:\x01\x32\x12\x1b\n\x10java_api_version\x18\x05 \x01(\x05:\x01\x32\x12!\n\x13java_use_javaproto2\x18\x06 \x01(\x08:\x04true\x12\x1e\n\x10java_java5_enums\x18\x07 \x01(\x08:\x04true\x12)\n\x1ajava_generate_rpc_baseimpl\x18\r \x01(\x08:\x05\x66\x61lse\x12#\n\x14java_use_javastrings\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14java_alt_api_package\x18\x13 \x01(\t\x12\x34\n%java_enable_dual_generate_mutable_api\x18\x1a \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12,\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08:\x05\x66\x61lse\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10java_mutable_api\x18\x1c \x01(\x08:\x05\x66\x61lse\x12+\n#java_multiple_files_mutable_package\x18\x1d \x01(\t\x12=\n\x0coptimize_for\x18\t \x01(\x0e\x32 .proto2.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\x1a\n\x12javascript_package\x18\x0c \x01(\t\x12\x1a\n\x0fszl_api_version\x18\x0e \x01(\x05:\x01\x31\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x12\x65xperimental_style\x18\x1e \x01(\t\x12\x1f\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\"c\n\x12\x43ompatibilityLevel\x12\x14\n\x10NO_COMPATIBILITY\x10\x00\x12\x15\n\x11PROTO1_COMPATIBLE\x10\x64\x12 \n\x1c\x44\x45PRECATED_PROTO1_COMPATIBLE\x10\x32\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xe4\x02\n\x0eMessageOptions\x12+\n#experimental_java_message_interface\x18\x04 \x03(\t\x12+\n#experimental_java_builder_interface\x18\x05 \x03(\t\x12+\n#experimental_java_interface_extends\x18\x06 \x03(\t\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x82\x05\n\x0c\x46ieldOptions\x12\x31\n\x05\x63type\x18\x01 \x01(\x0e\x32\x1a.proto2.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x31\n\x05jtype\x18\x04 \x01(\x0e\x32\x1a.proto2.FieldOptions.JType:\x06NORMAL\x12\x36\n\x06jstype\x18\x06 \x01(\x0e\x32\x1b.proto2.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12<\n\x0fupgraded_option\x18\x0b \x03(\x0b\x32#.proto2.FieldOptions.UpgradedOption\x12%\n\x16\x64\x65precated_raw_message\x18\x0c \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\x1a-\n\x0eUpgradedOption\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"<\n\x05JType\x12\n\n\x06NORMAL\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\x1c\n\x18\x45XPERIMENTAL_BYTE_BUFFER\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x99\x01\n\x0b\x45numOptions\x12\x13\n\x0bproto1_name\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"t\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xb6\x01\n\x0eServiceOptions\x12\x1d\n\x0emulticast_stub\x18\x14 \x01(\x08:\x05\x66\x61lse\x12#\n\x17\x66\x61ilure_detection_delay\x18\x10 \x01(\x01:\x02-1\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd3\t\n\rMethodOptions\x12\x35\n\x08protocol\x18\x07 \x01(\x0e\x32\x1e.proto2.MethodOptions.Protocol:\x03TCP\x12\x14\n\x08\x64\x65\x61\x64line\x18\x08 \x01(\x01:\x02-1\x12$\n\x15\x64uplicate_suppression\x18\t \x01(\x08:\x05\x66\x61lse\x12\x18\n\tfail_fast\x18\n \x01(\x08:\x05\x66\x61lse\x12\'\n\x18\x65nd_user_creds_requested\x18\x1a \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0e\x63lient_logging\x18\x0b \x01(\x11:\x03\x32\x35\x36\x12\x1b\n\x0eserver_logging\x18\x0c \x01(\x11:\x03\x32\x35\x36\x12\x41\n\x0esecurity_level\x18\r \x01(\x0e\x32#.proto2.MethodOptions.SecurityLevel:\x04NONE\x12\x43\n\x0fresponse_format\x18\x0f \x01(\x0e\x32\x1c.proto2.MethodOptions.Format:\x0cUNCOMPRESSED\x12\x42\n\x0erequest_format\x18\x11 \x01(\x0e\x32\x1c.proto2.MethodOptions.Format:\x0cUNCOMPRESSED\x12\x13\n\x0bstream_type\x18\x12 \x01(\t\x12\x16\n\x0esecurity_label\x18\x13 \x01(\t\x12\x18\n\x10\x63lient_streaming\x18\x14 \x01(\x08\x12\x18\n\x10server_streaming\x18\x15 \x01(\x08\x12\x1a\n\x12legacy_stream_type\x18\x16 \x01(\t\x12\x1a\n\x12legacy_result_type\x18\x17 \x01(\t\x12(\n\x1clegacy_client_initial_tokens\x18\x18 \x01(\x03:\x02-1\x12(\n\x1clegacy_server_initial_tokens\x18\x19 \x01(\x03:\x02-1\x12^\n\tlog_level\x18\x1b \x01(\x0e\x32\x1e.proto2.MethodOptions.LogLevel:+LOG_HEADER_AND_NON_PRIVATE_PAYLOAD_INTERNAL\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\"\x1c\n\x08Protocol\x12\x07\n\x03TCP\x10\x00\x12\x07\n\x03UDP\x10\x01\"e\n\rSecurityLevel\x12\x08\n\x04NONE\x10\x00\x12\r\n\tINTEGRITY\x10\x01\x12\x19\n\x15PRIVACY_AND_INTEGRITY\x10\x02\x12 \n\x1cSTRONG_PRIVACY_AND_INTEGRITY\x10\x03\"0\n\x06\x46ormat\x12\x10\n\x0cUNCOMPRESSED\x10\x00\x12\x14\n\x10ZIPPY_COMPRESSED\x10\x01\"\x9f\x01\n\x08LogLevel\x12\x0c\n\x08LOG_NONE\x10\x00\x12\x13\n\x0fLOG_HEADER_ONLY\x10\x01\x12/\n+LOG_HEADER_AND_NON_PRIVATE_PAYLOAD_INTERNAL\x10\x02\x12#\n\x1fLOG_HEADER_AND_FILTERED_PAYLOAD\x10\x03\x12\x1a\n\x16LOG_HEADER_AND_PAYLOAD\x10\x04*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xe7\x04\n\rStreamOptions\x12!\n\x15\x63lient_initial_tokens\x18\x01 \x01(\x03:\x02-1\x12!\n\x15server_initial_tokens\x18\x02 \x01(\x03:\x02-1\x12<\n\ntoken_unit\x18\x03 \x01(\x0e\x32\x1f.proto2.StreamOptions.TokenUnit:\x07MESSAGE\x12\x41\n\x0esecurity_level\x18\x04 \x01(\x0e\x32#.proto2.MethodOptions.SecurityLevel:\x04NONE\x12\x16\n\x0esecurity_label\x18\x05 \x01(\t\x12\x1b\n\x0e\x63lient_logging\x18\x06 \x01(\x05:\x03\x32\x35\x36\x12\x1b\n\x0eserver_logging\x18\x07 \x01(\x05:\x03\x32\x35\x36\x12\x14\n\x08\x64\x65\x61\x64line\x18\x08 \x01(\x01:\x02-1\x12\x18\n\tfail_fast\x18\t \x01(\x08:\x05\x66\x61lse\x12\'\n\x18\x65nd_user_creds_requested\x18\n \x01(\x08:\x05\x66\x61lse\x12^\n\tlog_level\x18\x0b \x01(\x0e\x32\x1e.proto2.MethodOptions.LogLevel:+LOG_HEADER_AND_NON_PRIVATE_PAYLOAD_INTERNAL\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12:\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32\x1b.proto2.UninterpretedOption\"\"\n\tTokenUnit\x12\x0b\n\x07MESSAGE\x10\x00\x12\x08\n\x04\x42YTE\x10\x01*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x95\x02\n\x13UninterpretedOption\x12\x32\n\x04name\x18\x02 \x03(\x0b\x32$.proto2.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xa8\x01\n\x0eSourceCodeInfo\x12\x31\n\x08location\x18\x01 \x03(\x0b\x32\x1f.proto2.SourceCodeInfo.Location\x1a\x63\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\tB,\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01\xe0\x01\x01')
 )
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -172,8 +172,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=3459,
-  serialized_end=3558,
+  serialized_start=3492,
+  serialized_end=3591,
 )
 _sym_db.RegisterEnumDescriptor(_FILEOPTIONS_COMPATIBILITYLEVEL)
 
@@ -198,8 +198,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=3560,
-  serialized_end=3618,
+  serialized_start=3593,
+  serialized_end=3651,
 )
 _sym_db.RegisterEnumDescriptor(_FILEOPTIONS_OPTIMIZEMODE)
 
@@ -224,8 +224,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=4458,
-  serialized_end=4505,
+  serialized_start=4491,
+  serialized_end=4538,
 )
 _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_CTYPE)
 
@@ -250,8 +250,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=4507,
-  serialized_end=4567,
+  serialized_start=4540,
+  serialized_end=4600,
 )
 _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JTYPE)
 
@@ -276,8 +276,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=4569,
-  serialized_end=4622,
+  serialized_start=4602,
+  serialized_end=4655,
 )
 _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JSTYPE)
 
@@ -298,8 +298,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=5976,
-  serialized_end=6004,
+  serialized_start=6009,
+  serialized_end=6037,
 )
 _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_PROTOCOL)
 
@@ -328,8 +328,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=6006,
-  serialized_end=6107,
+  serialized_start=6039,
+  serialized_end=6140,
 )
 _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_SECURITYLEVEL)
 
@@ -350,8 +350,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=6109,
-  serialized_end=6157,
+  serialized_start=6142,
+  serialized_end=6190,
 )
 _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_FORMAT)
 
@@ -384,8 +384,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=6160,
-  serialized_end=6319,
+  serialized_start=6193,
+  serialized_end=6352,
 )
 _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_LOGLEVEL)
 
@@ -406,8 +406,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=6903,
-  serialized_end=6937,
+  serialized_start=6936,
+  serialized_end=6970,
 )
 _sym_db.RegisterEnumDescriptor(_STREAMOPTIONS_TOKENUNIT)
 
@@ -1234,7 +1234,14 @@
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='proto2.FileOptions.uninterpreted_option', index=29,
+      name='cc_enable_arenas', full_name='proto2.FileOptions.cc_enable_arenas', index=29,
+      number=31, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='proto2.FileOptions.uninterpreted_option', index=30,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -1254,7 +1261,7 @@
   oneofs=[
   ],
   serialized_start=2312,
-  serialized_end=3629,
+  serialized_end=3662,
 )
 
 
@@ -1332,8 +1339,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=3632,
-  serialized_end=3988,
+  serialized_start=3665,
+  serialized_end=4021,
 )
 
 
@@ -1369,8 +1376,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=4411,
-  serialized_end=4456,
+  serialized_start=4444,
+  serialized_end=4489,
 )
 
 _FIELDOPTIONS = _descriptor.Descriptor(
@@ -1464,8 +1471,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=3991,
-  serialized_end=4633,
+  serialized_start=4024,
+  serialized_end=4666,
 )
 
 
@@ -1515,8 +1522,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=4636,
-  serialized_end=4789,
+  serialized_start=4669,
+  serialized_end=4822,
 )
 
 
@@ -1552,8 +1559,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=4791,
-  serialized_end=4907,
+  serialized_start=4824,
+  serialized_end=4940,
 )
 
 
@@ -1603,8 +1610,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=4910,
-  serialized_end=5092,
+  serialized_start=4943,
+  serialized_end=5125,
 )
 
 
@@ -1777,8 +1784,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=5095,
-  serialized_end=6330,
+  serialized_start=5128,
+  serialized_end=6363,
 )
 
 
@@ -1892,8 +1899,8 @@
   extension_ranges=[(1000, 536870912), ],
   oneofs=[
   ],
-  serialized_start=6333,
-  serialized_end=6948,
+  serialized_start=6366,
+  serialized_end=6981,
 )
 
 
@@ -1929,8 +1936,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=7177,
-  serialized_end=7228,
+  serialized_start=7210,
+  serialized_end=7261,
 )
 
 _UNINTERPRETEDOPTION = _descriptor.Descriptor(
@@ -2000,8 +2007,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=6951,
-  serialized_end=7228,
+  serialized_start=6984,
+  serialized_end=7261,
 )
 
 
@@ -2051,8 +2058,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=7300,
-  serialized_end=7399,
+  serialized_start=7333,
+  serialized_end=7432,
 )
 
 _SOURCECODEINFO = _descriptor.Descriptor(
@@ -2080,8 +2087,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=7231,
-  serialized_end=7399,
+  serialized_start=7264,
+  serialized_end=7432,
 )
 
 _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO
diff --git a/php/sdk/google/appengine/datastore/entity_pb.php b/php/sdk/google/appengine/datastore/entity_pb.php
index 2d16645..52d1c18 100644
--- a/php/sdk/google/appengine/datastore/entity_pb.php
+++ b/php/sdk/google/appengine/datastore/entity_pb.php
@@ -2669,6 +2669,7 @@
 namespace storage_onestore_v3\Index\Property {
   class Mode {
     const MODE_UNSPECIFIED = 0;
+    const SEGMENT = 2;
     const GEOSPATIAL = 3;
   }
 }