Repository: google/closure-compiler
Pull request #1271 (2015-11-25 13:20:03)

Switch the --json_streams flag to an enumeration
I realize we just merged this feature yesterday, but it has worked so well for the gulp plugin that I also would like to use it for the grunt plugin as it completely mitigates problems with windows command length restrictions.

However, if both stdin and stdout are json streams, the plugin has to recreate much of the functionality of the CommandLineRunner in regards to smartly parsing sourcemap, module and output file flags. This is further complicated if a flagfile is used.

By allowing control of input/output streams independently, build systems can choose to allow the compiler to handle these tasks.

ChadKillingsworth: Done. Commits squashed.

Patch:
diff --git a/contrib/externs/angular-1.4-mocks.js b/contrib/externs/angular-1.4-mocks.js
index d3ce87e98..0460e2ffd 100644
--- a/contrib/externs/angular-1.4-mocks.js
+++ b/contrib/externs/angular-1.4-mocks.js
@@ -31,6 +31,7 @@
  *     $httpBackendDecorator
  *     $RootScopeDecorator
  *     angular.mock.module
+ *     angular.mock.inject
  */
 
 angular.mock = {};
@@ -244,7 +245,3 @@ angular.mock.animate.prototype.flush = function() {};
 
 /** @typedef {function((!Function|string), !Object, Object=): !Object} */
 angular.mock.$controller;
-
-
-/** @param {!Array|!Function} injectable */
-angular.mock.inject = function(injectable) {};
diff --git a/contrib/externs/angular-material.js b/contrib/externs/angular-material.js
index a05198200..0f6ac0c6d 100644
--- a/contrib/externs/angular-material.js
+++ b/contrib/externs/angular-material.js
@@ -394,7 +394,7 @@ md.$mdThemingProvider.prototype.setDefaultTheme = function(name) {};
 /**
  * @param {string} name
  * @param {string=} opt_parentTheme
- * @return {!md.$mdThemingProvider.Theme}
+ * @return {md.$mdThemingProvider.Theme}
  */
 md.$mdThemingProvider.prototype.theme = function(name, opt_parentTheme) {};
 
diff --git a/contrib/externs/chrome_extensions.js b/contrib/externs/chrome_extensions.js
index 884e1d590..6cdf5807f 100644
--- a/contrib/externs/chrome_extensions.js
+++ b/contrib/externs/chrome_extensions.js
@@ -387,14 +387,14 @@ chrome.app.window.AppWindow.prototype.hide = function() {};
 
 
 /**
- * @return {!chrome.app.window.ContentBounds} The current window bounds.
+ * @return {!chrome.app.window.Bounds} The current window bounds.
  * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow
  */
 chrome.app.window.AppWindow.prototype.getBounds = function() {};
 
 
 /**
- * @param {!chrome.app.window.ContentBounds} bounds The new window bounds.
+ * @param {!chrome.app.window.Bounds} bounds The new window bounds.
  * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow
  */
 chrome.app.window.AppWindow.prototype.setBounds = function(bounds) {};
@@ -415,24 +415,6 @@ chrome.app.window.AppWindow.prototype.isAlwaysOnTop = function() {};
 chrome.app.window.AppWindow.prototype.setAlwaysOnTop = function(alwaysOnTop) {};
 
 
-/**
- * @param {boolean} alwaysVisible Set whether the window is visible on all
- *     workspaces.
- * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow
- */
-chrome.app.window.AppWindow.prototype.setVisibleOnAllWorkspaces =
-    function(alwaysVisible) {};
-
-
-/**
- * @param {boolean} wantAllKeys Set whether the window should get all keyboard
- *     events including system keys that are usually not sent.
- * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow
- */
-chrome.app.window.AppWindow.prototype.setInterceptAllKeys =
-    function(wantAllKeys) {};
-
-
 /** @type {!ChromeEvent} */
 chrome.app.window.AppWindow.prototype.onBoundsChanged;
 
@@ -461,18 +443,6 @@ chrome.app.window.AppWindow.prototype.onRestored;
 chrome.app.window.AppWindow.prototype.contentWindow;
 
 
-/** @type {string} */
-chrome.app.window.AppWindow.prototype.id;
-
-
-/** @type {!chrome.app.window.Bounds} */
-chrome.app.window.AppWindow.prototype.innerBounds;
-
-
-/** @type {!chrome.app.window.Bounds} */
-chrome.app.window.AppWindow.prototype.outerBounds;
-
-
 /**
  * @typedef {?{
  *   left: number,
diff --git a/contrib/externs/jquery-1.9.js b/contrib/externs/jquery-1.9.js
index 38667eb48..49975b1c4 100644
--- a/contrib/externs/jquery-1.9.js
+++ b/contrib/externs/jquery-1.9.js
@@ -596,14 +596,11 @@ jQuery.Event.prototype.bubbles;
 /** @type {number} */
 jQuery.Event.prototype.button;
 
-/** @type {number} */
-jQuery.Event.prototype.buttons;
-
 /** @type {boolean} */
 jQuery.Event.prototype.cancelable;
 
-/** @type {number} */
-jQuery.Event.prototype.charCode;
+/** @type {string} */
+jQuery.Event.prototype.charChode;
 
 /** @type {number} */
 jQuery.Event.prototype.clientX;
@@ -647,9 +644,6 @@ jQuery.Event.prototype.isImmediatePropagationStopped = function() {};
  */
 jQuery.Event.prototype.isPropagationStopped = function() {};
 
-/** @type {number} */
-jQuery.Event.prototype.keyCode;
-
 /** @type {boolean} */
 jQuery.Event.prototype.metaKey;
 
@@ -707,9 +701,6 @@ jQuery.Event.prototype.target;
 /** @type {number} */
 jQuery.Event.prototype.timeStamp;
 
-/** @type {Element} */
-jQuery.Event.prototype.toElement;
-
 /** @type {string} */
 jQuery.Event.prototype.type;
 
diff --git a/contrib/externs/maps/google_maps_api_v3_10.js b/contrib/externs/maps/google_maps_api_v3_10.js
index 4b4afb1d4..76a9b0b8e 100644
--- a/contrib/externs/maps/google_maps_api_v3_10.js
+++ b/contrib/externs/maps/google_maps_api_v3_10.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -198,21 +198,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -524,16 +524,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -618,12 +618,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -729,15 +729,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -796,13 +796,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1094,13 +1094,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1154,15 +1154,15 @@ google.maps.GeocoderResult.prototype.geometry;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1601,17 +1601,17 @@ google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 google.maps.KmlLayerOptions.prototype.url;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2353,22 +2353,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2758,11 +2758,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3344,10 +3344,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3674,12 +3674,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3712,12 +3712,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -3804,14 +3804,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4036,21 +4036,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4069,38 +4069,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -4403,13 +4403,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -5119,14 +5119,14 @@ google.maps.places.PlacesService.prototype.nearbySearch = function(request, call
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -5211,11 +5211,11 @@ google.maps.places.QueryAutocompletionRequest.prototype.offset;
 google.maps.places.QueryAutocompletionRequest.prototype.radius;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -5384,19 +5384,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -5595,11 +5595,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_11.js b/contrib/externs/maps/google_maps_api_v3_11.js
index ac916850d..5d7205a74 100644
--- a/contrib/externs/maps/google_maps_api_v3_11.js
+++ b/contrib/externs/maps/google_maps_api_v3_11.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -546,16 +546,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -640,12 +640,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -751,15 +751,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -818,13 +818,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1116,13 +1116,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1176,15 +1176,15 @@ google.maps.GeocoderResult.prototype.geometry;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1623,17 +1623,17 @@ google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 google.maps.KmlLayerOptions.prototype.url;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2375,22 +2375,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2780,11 +2780,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3417,10 +3417,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3778,12 +3778,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3816,12 +3816,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -3908,14 +3908,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4140,21 +4140,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4173,38 +4173,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -4507,13 +4507,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -5291,14 +5291,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -5418,11 +5418,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -5887,12 +5887,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -5932,19 +5932,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -6143,11 +6143,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_12.js b/contrib/externs/maps/google_maps_api_v3_12.js
index 8eadca379..5cdd02619 100644
--- a/contrib/externs/maps/google_maps_api_v3_12.js
+++ b/contrib/externs/maps/google_maps_api_v3_12.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -546,16 +546,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -640,12 +640,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -751,15 +751,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -818,13 +818,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1116,13 +1116,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1181,15 +1181,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1628,17 +1628,17 @@ google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 google.maps.KmlLayerOptions.prototype.url;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2385,22 +2385,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2795,11 +2795,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3432,10 +3432,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3793,12 +3793,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3831,12 +3831,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -3923,14 +3923,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4155,21 +4155,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4188,38 +4188,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -4527,13 +4527,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -5326,14 +5326,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -5453,11 +5453,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -5932,12 +5932,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -5977,19 +5977,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -6188,11 +6188,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_13.js b/contrib/externs/maps/google_maps_api_v3_13.js
index f6ab9ee4d..bbf97a0dd 100644
--- a/contrib/externs/maps/google_maps_api_v3_13.js
+++ b/contrib/externs/maps/google_maps_api_v3_13.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -551,16 +551,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -645,12 +645,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -761,15 +761,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -828,13 +828,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1156,13 +1156,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1226,15 +1226,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1678,17 +1678,17 @@ google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 google.maps.KmlLayerOptions.prototype.url;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2435,22 +2435,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2845,11 +2845,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3482,10 +3482,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3848,12 +3848,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3886,12 +3886,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -3978,14 +3978,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4210,21 +4210,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4243,38 +4243,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -4582,13 +4582,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -5381,14 +5381,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -5508,11 +5508,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6191,12 +6191,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -6236,19 +6236,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -6447,11 +6447,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_14.js b/contrib/externs/maps/google_maps_api_v3_14.js
index d92b02259..4b57af27c 100644
--- a/contrib/externs/maps/google_maps_api_v3_14.js
+++ b/contrib/externs/maps/google_maps_api_v3_14.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -551,16 +551,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -645,12 +645,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -761,15 +761,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -828,13 +828,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1156,13 +1156,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1226,15 +1226,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1733,17 +1733,17 @@ google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 google.maps.KmlLayerOptions.prototype.url;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2485,22 +2485,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2895,11 +2895,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3532,10 +3532,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3898,12 +3898,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3936,12 +3936,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4078,14 +4078,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4310,21 +4310,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4343,38 +4343,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -4682,13 +4682,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -5481,14 +5481,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -5608,11 +5608,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6108,12 +6108,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -6153,19 +6153,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -6364,11 +6364,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_15.js b/contrib/externs/maps/google_maps_api_v3_15.js
index 7661777c7..ab37a3773 100644
--- a/contrib/externs/maps/google_maps_api_v3_15.js
+++ b/contrib/externs/maps/google_maps_api_v3_15.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -551,16 +551,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -645,12 +645,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -761,15 +761,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -828,13 +828,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1156,13 +1156,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1226,15 +1226,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1752,17 +1752,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2504,22 +2504,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2914,11 +2914,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3551,10 +3551,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3924,12 +3924,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3962,12 +3962,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4104,14 +4104,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4336,21 +4336,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4369,38 +4369,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -4708,13 +4708,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -5512,14 +5512,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -5639,11 +5639,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6196,12 +6196,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -6241,19 +6241,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -6452,11 +6452,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_16.js b/contrib/externs/maps/google_maps_api_v3_16.js
index 7f2bb945e..2808591ef 100644
--- a/contrib/externs/maps/google_maps_api_v3_16.js
+++ b/contrib/externs/maps/google_maps_api_v3_16.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1159,16 +1159,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1253,12 +1253,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1374,15 +1374,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1441,13 +1441,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1769,13 +1769,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1839,15 +1839,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2365,17 +2365,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3137,22 +3137,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3525,11 +3525,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4157,10 +4157,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4536,12 +4536,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -4574,12 +4574,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4716,14 +4716,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4948,21 +4948,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4981,38 +4981,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5320,13 +5320,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6119,14 +6119,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6246,11 +6246,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6803,12 +6803,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -6848,19 +6848,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -7059,11 +7059,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_17.js b/contrib/externs/maps/google_maps_api_v3_17.js
index 445304dd6..6d69d725d 100644
--- a/contrib/externs/maps/google_maps_api_v3_17.js
+++ b/contrib/externs/maps/google_maps_api_v3_17.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -215,21 +215,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1176,16 +1176,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1270,12 +1270,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1391,15 +1391,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1458,13 +1458,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1786,13 +1786,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1856,15 +1856,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2382,17 +2382,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3144,22 +3144,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3532,11 +3532,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4164,10 +4164,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4560,12 +4560,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -4598,12 +4598,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4740,14 +4740,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -4972,21 +4972,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5005,38 +5005,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5344,13 +5344,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6158,14 +6158,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6285,11 +6285,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6843,12 +6843,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -6888,19 +6888,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -7099,11 +7099,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_18.js b/contrib/externs/maps/google_maps_api_v3_18.js
index 3e24acbe6..eae33ee1a 100644
--- a/contrib/externs/maps/google_maps_api_v3_18.js
+++ b/contrib/externs/maps/google_maps_api_v3_18.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -235,21 +235,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1196,16 +1196,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1290,12 +1290,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1411,15 +1411,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1478,13 +1478,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1806,13 +1806,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1881,15 +1881,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2407,17 +2407,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3169,22 +3169,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3591,11 +3591,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4295,10 +4295,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4691,12 +4691,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -4729,12 +4729,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4871,14 +4871,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5103,21 +5103,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5136,38 +5136,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5475,13 +5475,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6264,14 +6264,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6396,11 +6396,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6954,12 +6954,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -6999,19 +6999,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -7210,11 +7210,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_19.js b/contrib/externs/maps/google_maps_api_v3_19.js
index 4629ff8a8..f55fca8c5 100644
--- a/contrib/externs/maps/google_maps_api_v3_19.js
+++ b/contrib/externs/maps/google_maps_api_v3_19.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -235,21 +235,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1202,16 +1202,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1296,12 +1296,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1427,15 +1427,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1494,13 +1494,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1822,13 +1822,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1897,15 +1897,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2423,17 +2423,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3185,22 +3185,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3607,11 +3607,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4311,10 +4311,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4707,12 +4707,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -4745,12 +4745,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4887,14 +4887,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5069,13 +5069,13 @@ google.maps.TransitLine.prototype.url;
 google.maps.TransitLine.prototype.vehicle;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitMode = {
-  BUS: '1',
-  RAIL: '2',
-  SUBWAY: '3',
-  TRAIN: '4',
+  BUS: '',
+  RAIL: '',
+  SUBWAY: '',
+  TRAIN: '',
   TRAM: ''
 };
 
@@ -5105,11 +5105,11 @@ google.maps.TransitOptions.prototype.modes;
 google.maps.TransitOptions.prototype.routingPreference;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitRoutePreference = {
-  FEWER_TRANSFERS: '1',
-  LESS_WALKING: '2'
+  FEWER_TRANSFERS: '',
+  LESS_WALKING: ''
 };
 
 /**
@@ -5153,21 +5153,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5186,38 +5186,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5525,13 +5525,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6315,14 +6315,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6447,11 +6447,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -7005,12 +7005,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -7050,19 +7050,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -7261,11 +7261,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_20.js b/contrib/externs/maps/google_maps_api_v3_20.js
index f367c9456..2614b2a31 100644
--- a/contrib/externs/maps/google_maps_api_v3_20.js
+++ b/contrib/externs/maps/google_maps_api_v3_20.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -235,21 +235,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1268,16 +1268,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1362,12 +1362,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1493,15 +1493,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1560,13 +1560,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1888,13 +1888,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1963,15 +1963,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2487,17 +2487,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3249,22 +3249,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3671,11 +3671,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4375,10 +4375,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4770,12 +4770,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -4808,12 +4808,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -4950,14 +4950,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5132,13 +5132,13 @@ google.maps.TransitLine.prototype.url;
 google.maps.TransitLine.prototype.vehicle;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitMode = {
-  BUS: '1',
-  RAIL: '2',
-  SUBWAY: '3',
-  TRAIN: '4',
+  BUS: '',
+  RAIL: '',
+  SUBWAY: '',
+  TRAIN: '',
   TRAM: ''
 };
 
@@ -5168,11 +5168,11 @@ google.maps.TransitOptions.prototype.modes;
 google.maps.TransitOptions.prototype.routingPreference;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitRoutePreference = {
-  FEWER_TRANSFERS: '1',
-  LESS_WALKING: '2'
+  FEWER_TRANSFERS: '',
+  LESS_WALKING: ''
 };
 
 /**
@@ -5216,21 +5216,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5249,38 +5249,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5588,13 +5588,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6378,14 +6378,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6510,11 +6510,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -7074,12 +7074,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -7119,19 +7119,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -7330,11 +7330,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_21.js b/contrib/externs/maps/google_maps_api_v3_21.js
index b55ed9fe1..cfb08394f 100644
--- a/contrib/externs/maps/google_maps_api_v3_21.js
+++ b/contrib/externs/maps/google_maps_api_v3_21.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -235,21 +235,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1293,16 +1293,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1387,12 +1387,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1518,15 +1518,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1585,13 +1585,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1913,13 +1913,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1998,15 +1998,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2527,17 +2527,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3289,22 +3289,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3778,11 +3778,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4482,10 +4482,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4892,11 +4892,11 @@ google.maps.StreetViewPov.prototype.heading;
 google.maps.StreetViewPov.prototype.pitch;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewPreference = {
-  BEST: '1',
-  NEAREST: '2'
+  BEST: '',
+  NEAREST: ''
 };
 
 /**
@@ -4912,20 +4912,20 @@ google.maps.StreetViewService = function() {};
 google.maps.StreetViewService.prototype.getPanorama = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewSource = {
-  DEFAULT: '1',
-  OUTDOOR: '2'
+  DEFAULT: '',
+  OUTDOOR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -4958,12 +4958,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -5105,14 +5105,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5287,13 +5287,13 @@ google.maps.TransitLine.prototype.url;
 google.maps.TransitLine.prototype.vehicle;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitMode = {
-  BUS: '1',
-  RAIL: '2',
-  SUBWAY: '3',
-  TRAIN: '4',
+  BUS: '',
+  RAIL: '',
+  SUBWAY: '',
+  TRAIN: '',
   TRAM: ''
 };
 
@@ -5323,11 +5323,11 @@ google.maps.TransitOptions.prototype.modes;
 google.maps.TransitOptions.prototype.routingPreference;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitRoutePreference = {
-  FEWER_TRANSFERS: '1',
-  LESS_WALKING: '2'
+  FEWER_TRANSFERS: '',
+  LESS_WALKING: ''
 };
 
 /**
@@ -5371,21 +5371,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5404,38 +5404,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5743,13 +5743,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6401,14 +6401,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6533,11 +6533,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -7097,12 +7097,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
diff --git a/contrib/externs/maps/google_maps_api_v3_22.js b/contrib/externs/maps/google_maps_api_v3_22.js
index cd2261056..46a440479 100644
--- a/contrib/externs/maps/google_maps_api_v3_22.js
+++ b/contrib/externs/maps/google_maps_api_v3_22.js
@@ -30,11 +30,11 @@ var google = {};
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -242,21 +242,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1300,16 +1300,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1394,12 +1394,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1530,15 +1530,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1612,13 +1612,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1940,13 +1940,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -2025,15 +2025,15 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -2554,17 +2554,17 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -3341,22 +3341,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3830,11 +3830,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4535,10 +4535,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -4945,11 +4945,11 @@ google.maps.StreetViewPov.prototype.heading;
 google.maps.StreetViewPov.prototype.pitch;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewPreference = {
-  BEST: '1',
-  NEAREST: '2'
+  BEST: '',
+  NEAREST: ''
 };
 
 /**
@@ -4965,20 +4965,20 @@ google.maps.StreetViewService = function() {};
 google.maps.StreetViewService.prototype.getPanorama = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewSource = {
-  DEFAULT: '1',
-  OUTDOOR: '2'
+  DEFAULT: '',
+  OUTDOOR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -5011,12 +5011,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 1,
-  INSIDE: 2,
-  OUTSIDE: 3
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -5158,14 +5158,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5207,12 +5207,12 @@ google.maps.TrafficLayer.prototype.getMap = function() {};
 google.maps.TrafficLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TrafficModel = {
-  BEST_GUESS: '1',
-  OPTIMISTIC: '2',
-  PESSIMISTIC: '3'
+  BEST_GUESS: '',
+  OPTIMISTIC: '',
+  PESSIMISTIC: ''
 };
 
 /**
@@ -5349,13 +5349,13 @@ google.maps.TransitLine.prototype.url;
 google.maps.TransitLine.prototype.vehicle;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitMode = {
-  BUS: '1',
-  RAIL: '2',
-  SUBWAY: '3',
-  TRAIN: '4',
+  BUS: '',
+  RAIL: '',
+  SUBWAY: '',
+  TRAIN: '',
   TRAM: ''
 };
 
@@ -5385,11 +5385,11 @@ google.maps.TransitOptions.prototype.modes;
 google.maps.TransitOptions.prototype.routingPreference;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitRoutePreference = {
-  FEWER_TRANSFERS: '1',
-  LESS_WALKING: '2'
+  FEWER_TRANSFERS: '',
+  LESS_WALKING: ''
 };
 
 /**
@@ -5433,21 +5433,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5466,38 +5466,38 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 /** @const */
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_HORIZONTAL_LINK_UNIT: '4',
-  LARGE_RECTANGLE: '5',
-  LARGE_VERTICAL_LINK_UNIT: '6',
-  LEADERBOARD: '7',
-  MEDIUM_RECTANGLE: '8',
-  MEDIUM_VERTICAL_LINK_UNIT: '9',
-  SKYSCRAPER: '10',
-  SMALL_HORIZONTAL_LINK_UNIT: '11',
-  SMALL_RECTANGLE: '12',
-  SMALL_SQUARE: '13',
-  SMALL_VERTICAL_LINK_UNIT: '14',
-  SQUARE: '15',
-  VERTICAL_BANNER: '16',
-  WIDE_SKYSCRAPER: '17',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
   X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
@@ -5805,13 +5805,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -6463,14 +6463,14 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -6595,11 +6595,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -7159,12 +7159,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '1',
-  OK: '2',
-  UNKNOWN_ERROR: '3'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
diff --git a/contrib/externs/maps/google_maps_api_v3_23.js b/contrib/externs/maps/google_maps_api_v3_23.js
index 0dfa09373..de65c6172 100644
--- a/contrib/externs/maps/google_maps_api_v3_23.js
+++ b/contrib/externs/maps/google_maps_api_v3_23.js
@@ -30,11 +30,11 @@ var google = {};
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 0,
-  DROP: 1
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -242,21 +242,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 0,
-  BOTTOM_LEFT: 1,
-  BOTTOM_RIGHT: 2,
-  LEFT_BOTTOM: 3,
-  LEFT_CENTER: 4,
-  LEFT_TOP: 5,
-  RIGHT_BOTTOM: 6,
-  RIGHT_CENTER: 7,
-  RIGHT_TOP: 8,
-  TOP_CENTER: 9,
-  TOP_LEFT: 10,
-  TOP_RIGHT: 11
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1300,17 +1300,17 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '0',
-  MAX_WAYPOINTS_EXCEEDED: '1',
-  NOT_FOUND: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
-  ZERO_RESULTS: '7'
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1394,12 +1394,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '0',
-  OK: '1',
-  ZERO_RESULTS: '2'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1530,16 +1530,16 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '0',
-  MAX_DIMENSIONS_EXCEEDED: '1',
-  MAX_ELEMENTS_EXCEEDED: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6'
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -1612,14 +1612,14 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '0',
-  OK: '1',
-  OVER_QUERY_LIMIT: '2',
-  REQUEST_DENIED: '3',
-  UNKNOWN_ERROR: '4'
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -1940,13 +1940,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '0',
-  GEOMETRIC_CENTER: '1',
-  RANGE_INTERPOLATED: '2',
-  ROOFTOP: '3'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -2025,16 +2025,16 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '0',
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
-  ZERO_RESULTS: '6'
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -2554,18 +2554,18 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '0',
-  DOCUMENT_TOO_LARGE: '1',
-  FETCH_ERROR: '2',
-  INVALID_DOCUMENT: '3',
-  INVALID_REQUEST: '4',
-  LIMITS_EXCEEDED: '5',
-  OK: '6',
-  TIMED_OUT: '7',
-  UNKNOWN: '8'
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
+  UNKNOWN: ''
 };
 
 /**
@@ -2612,11 +2612,6 @@ google.maps.LatLng.prototype.lat = function() {};
  */
 google.maps.LatLng.prototype.lng = function() {};
 
-/**
- * @return {google.maps.LatLngLiteral}
- */
-google.maps.LatLng.prototype.toJSON = function() {};
-
 /**
  * @return {string}
  */
@@ -2682,11 +2677,6 @@ google.maps.LatLngBounds.prototype.intersects = function(other) {};
  */
 google.maps.LatLngBounds.prototype.isEmpty = function() {};
 
-/**
- * @return {google.maps.LatLngBoundsLiteral}
- */
-google.maps.LatLngBounds.prototype.toJSON = function() {};
-
 /**
  * @return {google.maps.LatLng}
  */
@@ -3351,22 +3341,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 0,
-  DROPDOWN_MENU: 1,
-  HORIZONTAL_BAR: 2
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '0',
-  ROADMAP: '1',
-  SATELLITE: '2',
-  TERRAIN: '3'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3840,11 +3830,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '0',
-  OK: '1'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4545,10 +4535,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 0
+  DEFAULT: ''
 };
 
 /**
@@ -4955,11 +4945,11 @@ google.maps.StreetViewPov.prototype.heading;
 google.maps.StreetViewPov.prototype.pitch;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewPreference = {
-  BEST: '0',
-  NEAREST: '1'
+  BEST: '',
+  NEAREST: ''
 };
 
 /**
@@ -4975,20 +4965,20 @@ google.maps.StreetViewService = function() {};
 google.maps.StreetViewService.prototype.getPanorama = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewSource = {
-  DEFAULT: '0',
-  OUTDOOR: '1'
+  DEFAULT: '',
+  OUTDOOR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '0',
-  UNKNOWN_ERROR: '1',
-  ZERO_RESULTS: '2'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -5021,12 +5011,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 0,
-  INSIDE: 1,
-  OUTSIDE: 2
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -5168,14 +5158,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 0,
-  BACKWARD_OPEN_ARROW: 1,
-  CIRCLE: 2,
-  FORWARD_CLOSED_ARROW: 3,
-  FORWARD_OPEN_ARROW: 4
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5217,12 +5207,12 @@ google.maps.TrafficLayer.prototype.getMap = function() {};
 google.maps.TrafficLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TrafficModel = {
-  BEST_GUESS: '0',
-  OPTIMISTIC: '1',
-  PESSIMISTIC: '2'
+  BEST_GUESS: '',
+  OPTIMISTIC: '',
+  PESSIMISTIC: ''
 };
 
 /**
@@ -5359,14 +5349,14 @@ google.maps.TransitLine.prototype.url;
 google.maps.TransitLine.prototype.vehicle;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitMode = {
-  BUS: '0',
-  RAIL: '1',
-  SUBWAY: '2',
-  TRAIN: '3',
-  TRAM: '4'
+  BUS: '',
+  RAIL: '',
+  SUBWAY: '',
+  TRAIN: '',
+  TRAM: ''
 };
 
 /**
@@ -5395,11 +5385,11 @@ google.maps.TransitOptions.prototype.modes;
 google.maps.TransitOptions.prototype.routingPreference;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitRoutePreference = {
-  FEWER_TRANSFERS: '0',
-  LESS_WALKING: '1'
+  FEWER_TRANSFERS: '',
+  LESS_WALKING: ''
 };
 
 /**
@@ -5443,21 +5433,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '0',
-  DRIVING: '1',
-  TRANSIT: '2',
-  WALKING: '3'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 0,
-  METRIC: 1
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5476,14 +5466,49 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 0,
-  LARGE: 1,
-  SMALL: 2
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
+};
+
+/** @const */
+google.maps.adsense = {};
+
+/**
+ * @enum {number|string}
+ */
+google.maps.adsense.AdFormat = {
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
+  X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
+/**
+ * @param {*} container
+ * @param {Object} opts
+ * @extends {google.maps.MVCObject}
+ * @constructor
+ */
+google.maps.adsense.AdUnit = function(container, opts) {};
+
 /** @const */
 google.maps.drawing = {};
 
@@ -5605,14 +5630,14 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '0',
-  MARKER: '1',
-  POLYGON: '2',
-  POLYLINE: '3',
-  RECTANGLE: '4'
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
+  RECTANGLE: ''
 };
 
 /** @const */
@@ -6263,15 +6288,15 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '0',
-  OK: '1',
-  OVER_QUERY_LIMIT: '2',
-  REQUEST_DENIED: '3',
-  UNKNOWN_ERROR: '4',
-  ZERO_RESULTS: '5'
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -6395,11 +6420,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 0,
-  PROMINENCE: 1
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6959,12 +6984,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '0',
-  OK: '1',
-  UNKNOWN_ERROR: '2'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
diff --git a/contrib/externs/maps/google_maps_api_v3_4.js b/contrib/externs/maps/google_maps_api_v3_4.js
index 21d8a7cd0..3bccaa0bb 100644
--- a/contrib/externs/maps/google_maps_api_v3_4.js
+++ b/contrib/externs/maps/google_maps_api_v3_4.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.Animation = {
-  DROP: 1,
-  BOUNCE: 2
+  DROP: '',
+  BOUNCE: ''
 };
 
 /**
@@ -159,21 +159,21 @@ google.maps.CircleOptions.prototype.strokeWeight;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  TOP_RIGHT: 2,
-  RIGHT_BOTTOM: 3,
-  BOTTOM_RIGHT: 4,
-  LEFT_TOP: 5,
-  LEFT_BOTTOM: 6,
-  TOP_LEFT: 7,
-  TOP_CENTER: 8,
-  LEFT_CENTER: 9,
-  RIGHT_CENTER: 10,
-  RIGHT_TOP: 11,
-  BOTTOM_LEFT: 12
+  BOTTOM_CENTER: '',
+  TOP_RIGHT: '',
+  RIGHT_BOTTOM: '',
+  BOTTOM_RIGHT: '',
+  LEFT_TOP: '',
+  LEFT_BOTTOM: '',
+  TOP_LEFT: '',
+  TOP_CENTER: '',
+  LEFT_CENTER: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  BOTTOM_LEFT: ''
 };
 
 /**
@@ -473,13 +473,13 @@ google.maps.DirectionsService.prototype.route = function(request, callback) {};
  * @enum {string}
  */
 google.maps.DirectionsStatus = {
-  MAX_WAYPOINTS_EXCEEDED: '1',
-  OK: '2',
-  ZERO_RESULTS: '3',
-  INVALID_REQUEST: '4',
-  UNKNOWN_ERROR: '5',
-  REQUEST_DENIED: '6',
-  NOT_FOUND: '7',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  NOT_FOUND: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -557,9 +557,9 @@ google.maps.Distance.prototype.value;
  * @enum {string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  ZERO_RESULTS: '1',
-  NOT_FOUND: '2',
-  OK: '3'
+  ZERO_RESULTS: '',
+  NOT_FOUND: '',
+  OK: ''
 };
 
 /**
@@ -668,12 +668,12 @@ google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request
  * @enum {string}
  */
 google.maps.DistanceMatrixStatus = {
-  OK: '1',
-  INVALID_REQUEST: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  MAX_DIMENSIONS_EXCEEDED: '6',
+  OK: '',
+  INVALID_REQUEST: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -730,10 +730,10 @@ google.maps.ElevationService.prototype.getElevationForLocations = function(reque
  * @enum {string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  UNKNOWN_ERROR: '2',
-  OK: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  OK: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -918,10 +918,10 @@ google.maps.GeocoderGeometry.prototype.viewport;
  * @enum {string}
  */
 google.maps.GeocoderLocationType = {
-  RANGE_INTERPOLATED: '1',
-  ROOFTOP: '2',
-  APPROXIMATE: '3',
-  GEOMETRIC_CENTER: '4'
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: '',
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: ''
 };
 
 /**
@@ -978,12 +978,12 @@ google.maps.GeocoderResult.prototype.types;
  * @enum {string}
  */
 google.maps.GeocoderStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  ERROR: '6',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  ERROR: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -2039,22 +2039,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  HORIZONTAL_BAR: 2,
-  DROPDOWN_MENU: 3
+  DEFAULT: '',
+  HORIZONTAL_BAR: '',
+  DROPDOWN_MENU: ''
 };
 
 /**
  * @enum {string}
  */
 google.maps.MapTypeId = {
-  TERRAIN: '1',
-  SATELLITE: '2',
-  HYBRID: '3',
-  ROADMAP: '4'
+  TERRAIN: '',
+  SATELLITE: '',
+  HYBRID: '',
+  ROADMAP: ''
 };
 
 /**
@@ -2452,8 +2452,8 @@ google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callb
  * @enum {string}
  */
 google.maps.MaxZoomStatus = {
-  OK: '1',
-  ERROR: '2'
+  OK: '',
+  ERROR: ''
 };
 
 /**
@@ -2892,10 +2892,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3220,9 +3220,9 @@ google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng,
  * @enum {string}
  */
 google.maps.StreetViewStatus = {
-  UNKNOWN_ERROR: '1',
-  ZERO_RESULTS: '2',
-  OK: '3'
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: '',
+  OK: ''
 };
 
 /**
@@ -3314,17 +3314,17 @@ google.maps.TrafficLayer.prototype.setMap = function(map) {};
  * @enum {string}
  */
 google.maps.TravelMode = {
-  WALKING: '1',
-  DRIVING: '2',
-  BICYCLING: '3'
+  WALKING: '',
+  DRIVING: '',
+  BICYCLING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.UnitSystem = {
-  METRIC: 1,
-  IMPERIAL: 2
+  METRIC: '',
+  IMPERIAL: ''
 };
 
 /**
@@ -3343,12 +3343,12 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
@@ -3358,17 +3358,17 @@ google.maps.adsense = {};
  * @enum {string}
  */
 google.maps.adsense.AdFormat = {
-  SMALL_RECTANGLE: '1',
-  SMALL_SQUARE: '2',
-  SQUARE: '3',
-  BUTTON: '4',
-  VERTICAL_BANNER: '5',
-  WIDE_SKYSCRAPER: '6',
-  HALF_BANNER: '7',
-  SKYSCRAPER: '8',
-  MEDIUM_RECTANGLE: '9',
-  LARGE_RECTANGLE: '10',
-  BANNER: '11',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SQUARE: '',
+  BUTTON: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
+  HALF_BANNER: '',
+  SKYSCRAPER: '',
+  MEDIUM_RECTANGLE: '',
+  LARGE_RECTANGLE: '',
+  BANNER: '',
   LEADERBOARD: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_5.js b/contrib/externs/maps/google_maps_api_v3_5.js
index 2c19ddf1c..a517a9012 100644
--- a/contrib/externs/maps/google_maps_api_v3_5.js
+++ b/contrib/externs/maps/google_maps_api_v3_5.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.Animation = {
-  DROP: 1,
-  BOUNCE: 2
+  DROP: '',
+  BOUNCE: ''
 };
 
 /**
@@ -159,21 +159,21 @@ google.maps.CircleOptions.prototype.strokeWeight;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  TOP_RIGHT: 2,
-  RIGHT_BOTTOM: 3,
-  BOTTOM_RIGHT: 4,
-  LEFT_TOP: 5,
-  LEFT_BOTTOM: 6,
-  TOP_LEFT: 7,
-  TOP_CENTER: 8,
-  LEFT_CENTER: 9,
-  RIGHT_CENTER: 10,
-  RIGHT_TOP: 11,
-  BOTTOM_LEFT: 12
+  BOTTOM_CENTER: '',
+  TOP_RIGHT: '',
+  RIGHT_BOTTOM: '',
+  BOTTOM_RIGHT: '',
+  LEFT_TOP: '',
+  LEFT_BOTTOM: '',
+  TOP_LEFT: '',
+  TOP_CENTER: '',
+  LEFT_CENTER: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  BOTTOM_LEFT: ''
 };
 
 /**
@@ -473,13 +473,13 @@ google.maps.DirectionsService.prototype.route = function(request, callback) {};
  * @enum {string}
  */
 google.maps.DirectionsStatus = {
-  MAX_WAYPOINTS_EXCEEDED: '1',
-  OK: '2',
-  ZERO_RESULTS: '3',
-  INVALID_REQUEST: '4',
-  UNKNOWN_ERROR: '5',
-  REQUEST_DENIED: '6',
-  NOT_FOUND: '7',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  NOT_FOUND: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -557,9 +557,9 @@ google.maps.Distance.prototype.value;
  * @enum {string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  ZERO_RESULTS: '1',
-  NOT_FOUND: '2',
-  OK: '3'
+  ZERO_RESULTS: '',
+  NOT_FOUND: '',
+  OK: ''
 };
 
 /**
@@ -668,12 +668,12 @@ google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request
  * @enum {string}
  */
 google.maps.DistanceMatrixStatus = {
-  OK: '1',
-  INVALID_REQUEST: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  MAX_DIMENSIONS_EXCEEDED: '6',
+  OK: '',
+  INVALID_REQUEST: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -730,10 +730,10 @@ google.maps.ElevationService.prototype.getElevationForLocations = function(reque
  * @enum {string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  UNKNOWN_ERROR: '2',
-  OK: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  OK: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -1013,10 +1013,10 @@ google.maps.GeocoderGeometry.prototype.viewport;
  * @enum {string}
  */
 google.maps.GeocoderLocationType = {
-  RANGE_INTERPOLATED: '1',
-  ROOFTOP: '2',
-  APPROXIMATE: '3',
-  GEOMETRIC_CENTER: '4'
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: '',
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: ''
 };
 
 /**
@@ -1073,12 +1073,12 @@ google.maps.GeocoderResult.prototype.types;
  * @enum {string}
  */
 google.maps.GeocoderStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  ERROR: '6',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  ERROR: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -2134,22 +2134,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  HORIZONTAL_BAR: 2,
-  DROPDOWN_MENU: 3
+  DEFAULT: '',
+  HORIZONTAL_BAR: '',
+  DROPDOWN_MENU: ''
 };
 
 /**
  * @enum {string}
  */
 google.maps.MapTypeId = {
-  TERRAIN: '1',
-  SATELLITE: '2',
-  HYBRID: '3',
-  ROADMAP: '4'
+  TERRAIN: '',
+  SATELLITE: '',
+  HYBRID: '',
+  ROADMAP: ''
 };
 
 /**
@@ -2194,7 +2194,7 @@ google.maps.MapTypeStyleElementType = {
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeStyleFeatureType = {
 
@@ -2576,8 +2576,8 @@ google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callb
  * @enum {string}
  */
 google.maps.MaxZoomStatus = {
-  OK: '1',
-  ERROR: '2'
+  OK: '',
+  ERROR: ''
 };
 
 /**
@@ -3016,10 +3016,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3344,9 +3344,9 @@ google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng,
  * @enum {string}
  */
 google.maps.StreetViewStatus = {
-  UNKNOWN_ERROR: '1',
-  ZERO_RESULTS: '2',
-  OK: '3'
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: '',
+  OK: ''
 };
 
 /**
@@ -3438,17 +3438,17 @@ google.maps.TrafficLayer.prototype.setMap = function(map) {};
  * @enum {string}
  */
 google.maps.TravelMode = {
-  WALKING: '1',
-  DRIVING: '2',
-  BICYCLING: '3'
+  WALKING: '',
+  DRIVING: '',
+  BICYCLING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.UnitSystem = {
-  METRIC: 1,
-  IMPERIAL: 2
+  METRIC: '',
+  IMPERIAL: ''
 };
 
 /**
@@ -3467,12 +3467,12 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
@@ -3482,17 +3482,17 @@ google.maps.adsense = {};
  * @enum {string}
  */
 google.maps.adsense.AdFormat = {
-  SMALL_RECTANGLE: '1',
-  SMALL_SQUARE: '2',
-  SQUARE: '3',
-  BUTTON: '4',
-  VERTICAL_BANNER: '5',
-  WIDE_SKYSCRAPER: '6',
-  HALF_BANNER: '7',
-  SKYSCRAPER: '8',
-  MEDIUM_RECTANGLE: '9',
-  LARGE_RECTANGLE: '10',
-  BANNER: '11',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SQUARE: '',
+  BUTTON: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
+  HALF_BANNER: '',
+  SKYSCRAPER: '',
+  MEDIUM_RECTANGLE: '',
+  LARGE_RECTANGLE: '',
+  BANNER: '',
   LEADERBOARD: ''
 };
 
@@ -4068,11 +4068,11 @@ google.maps.places.PlacesService.prototype.search = function(request, callback)
  * @enum {string}
  */
 google.maps.places.PlacesServiceStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_6.js b/contrib/externs/maps/google_maps_api_v3_6.js
index fc1875372..dcd937891 100644
--- a/contrib/externs/maps/google_maps_api_v3_6.js
+++ b/contrib/externs/maps/google_maps_api_v3_6.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.Animation = {
-  DROP: 1,
-  BOUNCE: 2
+  DROP: '',
+  BOUNCE: ''
 };
 
 /**
@@ -159,21 +159,21 @@ google.maps.CircleOptions.prototype.strokeWeight;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  TOP_RIGHT: 2,
-  RIGHT_BOTTOM: 3,
-  BOTTOM_RIGHT: 4,
-  LEFT_TOP: 5,
-  LEFT_BOTTOM: 6,
-  TOP_LEFT: 7,
-  TOP_CENTER: 8,
-  LEFT_CENTER: 9,
-  RIGHT_CENTER: 10,
-  RIGHT_TOP: 11,
-  BOTTOM_LEFT: 12
+  BOTTOM_CENTER: '',
+  TOP_RIGHT: '',
+  RIGHT_BOTTOM: '',
+  BOTTOM_RIGHT: '',
+  LEFT_TOP: '',
+  LEFT_BOTTOM: '',
+  TOP_LEFT: '',
+  TOP_CENTER: '',
+  LEFT_CENTER: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  BOTTOM_LEFT: ''
 };
 
 /**
@@ -473,13 +473,13 @@ google.maps.DirectionsService.prototype.route = function(request, callback) {};
  * @enum {string}
  */
 google.maps.DirectionsStatus = {
-  MAX_WAYPOINTS_EXCEEDED: '1',
-  OK: '2',
-  ZERO_RESULTS: '3',
-  INVALID_REQUEST: '4',
-  UNKNOWN_ERROR: '5',
-  REQUEST_DENIED: '6',
-  NOT_FOUND: '7',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  NOT_FOUND: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -557,9 +557,9 @@ google.maps.Distance.prototype.value;
  * @enum {string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  ZERO_RESULTS: '1',
-  NOT_FOUND: '2',
-  OK: '3'
+  ZERO_RESULTS: '',
+  NOT_FOUND: '',
+  OK: ''
 };
 
 /**
@@ -668,12 +668,12 @@ google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request
  * @enum {string}
  */
 google.maps.DistanceMatrixStatus = {
-  OK: '1',
-  INVALID_REQUEST: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  MAX_DIMENSIONS_EXCEEDED: '6',
+  OK: '',
+  INVALID_REQUEST: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -730,10 +730,10 @@ google.maps.ElevationService.prototype.getElevationForLocations = function(reque
  * @enum {string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  UNKNOWN_ERROR: '2',
-  OK: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  OK: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -1013,10 +1013,10 @@ google.maps.GeocoderGeometry.prototype.viewport;
  * @enum {string}
  */
 google.maps.GeocoderLocationType = {
-  RANGE_INTERPOLATED: '1',
-  ROOFTOP: '2',
-  APPROXIMATE: '3',
-  GEOMETRIC_CENTER: '4'
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: '',
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: ''
 };
 
 /**
@@ -1073,12 +1073,12 @@ google.maps.GeocoderResult.prototype.types;
  * @enum {string}
  */
 google.maps.GeocoderStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  ERROR: '6',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  ERROR: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -2139,22 +2139,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  HORIZONTAL_BAR: 2,
-  DROPDOWN_MENU: 3
+  DEFAULT: '',
+  HORIZONTAL_BAR: '',
+  DROPDOWN_MENU: ''
 };
 
 /**
  * @enum {string}
  */
 google.maps.MapTypeId = {
-  TERRAIN: '1',
-  SATELLITE: '2',
-  HYBRID: '3',
-  ROADMAP: '4'
+  TERRAIN: '',
+  SATELLITE: '',
+  HYBRID: '',
+  ROADMAP: ''
 };
 
 /**
@@ -2199,7 +2199,7 @@ google.maps.MapTypeStyleElementType = {
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeStyleFeatureType = {
 
@@ -2581,8 +2581,8 @@ google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callb
  * @enum {string}
  */
 google.maps.MaxZoomStatus = {
-  OK: '1',
-  ERROR: '2'
+  OK: '',
+  ERROR: ''
 };
 
 /**
@@ -3021,10 +3021,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3349,9 +3349,9 @@ google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng,
  * @enum {string}
  */
 google.maps.StreetViewStatus = {
-  UNKNOWN_ERROR: '1',
-  ZERO_RESULTS: '2',
-  OK: '3'
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: '',
+  OK: ''
 };
 
 /**
@@ -3437,17 +3437,17 @@ google.maps.TrafficLayer.prototype.setMap = function(map) {};
  * @enum {string}
  */
 google.maps.TravelMode = {
-  WALKING: '1',
-  DRIVING: '2',
-  BICYCLING: '3'
+  WALKING: '',
+  DRIVING: '',
+  BICYCLING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.UnitSystem = {
-  METRIC: 1,
-  IMPERIAL: 2
+  METRIC: '',
+  IMPERIAL: ''
 };
 
 /**
@@ -3466,12 +3466,12 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
@@ -3481,17 +3481,17 @@ google.maps.adsense = {};
  * @enum {string}
  */
 google.maps.adsense.AdFormat = {
-  SMALL_RECTANGLE: '1',
-  SMALL_SQUARE: '2',
-  SQUARE: '3',
-  BUTTON: '4',
-  VERTICAL_BANNER: '5',
-  WIDE_SKYSCRAPER: '6',
-  HALF_BANNER: '7',
-  SKYSCRAPER: '8',
-  MEDIUM_RECTANGLE: '9',
-  LARGE_RECTANGLE: '10',
-  BANNER: '11',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SQUARE: '',
+  BUTTON: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
+  HALF_BANNER: '',
+  SKYSCRAPER: '',
+  MEDIUM_RECTANGLE: '',
+  LARGE_RECTANGLE: '',
+  BANNER: '',
   LEADERBOARD: ''
 };
 
@@ -4067,11 +4067,11 @@ google.maps.places.PlacesService.prototype.search = function(request, callback)
  * @enum {string}
  */
 google.maps.places.PlacesServiceStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_7.js b/contrib/externs/maps/google_maps_api_v3_7.js
index 6539e915e..da2cbc109 100644
--- a/contrib/externs/maps/google_maps_api_v3_7.js
+++ b/contrib/externs/maps/google_maps_api_v3_7.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.Animation = {
-  DROP: 1,
-  BOUNCE: 2
+  DROP: '',
+  BOUNCE: ''
 };
 
 /**
@@ -171,21 +171,21 @@ google.maps.CircleOptions.prototype.strokeWeight;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  TOP_RIGHT: 2,
-  RIGHT_BOTTOM: 3,
-  BOTTOM_RIGHT: 4,
-  LEFT_TOP: 5,
-  LEFT_BOTTOM: 6,
-  TOP_LEFT: 7,
-  TOP_CENTER: 8,
-  LEFT_CENTER: 9,
-  RIGHT_CENTER: 10,
-  RIGHT_TOP: 11,
-  BOTTOM_LEFT: 12
+  BOTTOM_CENTER: '',
+  TOP_RIGHT: '',
+  RIGHT_BOTTOM: '',
+  BOTTOM_RIGHT: '',
+  LEFT_TOP: '',
+  LEFT_BOTTOM: '',
+  TOP_LEFT: '',
+  TOP_CENTER: '',
+  LEFT_CENTER: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  BOTTOM_LEFT: ''
 };
 
 /**
@@ -485,13 +485,13 @@ google.maps.DirectionsService.prototype.route = function(request, callback) {};
  * @enum {string}
  */
 google.maps.DirectionsStatus = {
-  MAX_WAYPOINTS_EXCEEDED: '1',
-  OK: '2',
-  ZERO_RESULTS: '3',
-  INVALID_REQUEST: '4',
-  UNKNOWN_ERROR: '5',
-  REQUEST_DENIED: '6',
-  NOT_FOUND: '7',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  NOT_FOUND: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -569,9 +569,9 @@ google.maps.Distance.prototype.value;
  * @enum {string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  ZERO_RESULTS: '1',
-  NOT_FOUND: '2',
-  OK: '3'
+  ZERO_RESULTS: '',
+  NOT_FOUND: '',
+  OK: ''
 };
 
 /**
@@ -680,12 +680,12 @@ google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request
  * @enum {string}
  */
 google.maps.DistanceMatrixStatus = {
-  OK: '1',
-  INVALID_REQUEST: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  MAX_DIMENSIONS_EXCEEDED: '6',
+  OK: '',
+  INVALID_REQUEST: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -747,10 +747,10 @@ google.maps.ElevationService.prototype.getElevationForLocations = function(reque
  * @enum {string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  UNKNOWN_ERROR: '2',
-  OK: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  OK: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -1030,10 +1030,10 @@ google.maps.GeocoderGeometry.prototype.viewport;
  * @enum {string}
  */
 google.maps.GeocoderLocationType = {
-  RANGE_INTERPOLATED: '1',
-  ROOFTOP: '2',
-  APPROXIMATE: '3',
-  GEOMETRIC_CENTER: '4'
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: '',
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: ''
 };
 
 /**
@@ -1090,12 +1090,12 @@ google.maps.GeocoderResult.prototype.types;
  * @enum {string}
  */
 google.maps.GeocoderStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
-  ERROR: '6',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
+  ERROR: '',
   OVER_QUERY_LIMIT: ''
 };
 
@@ -2156,22 +2156,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  HORIZONTAL_BAR: 2,
-  DROPDOWN_MENU: 3
+  DEFAULT: '',
+  HORIZONTAL_BAR: '',
+  DROPDOWN_MENU: ''
 };
 
 /**
  * @enum {string}
  */
 google.maps.MapTypeId = {
-  TERRAIN: '1',
-  SATELLITE: '2',
-  HYBRID: '3',
-  ROADMAP: '4'
+  TERRAIN: '',
+  SATELLITE: '',
+  HYBRID: '',
+  ROADMAP: ''
 };
 
 /**
@@ -2216,7 +2216,7 @@ google.maps.MapTypeStyleElementType = {
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.MapTypeStyleFeatureType = {
 
@@ -2598,8 +2598,8 @@ google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callb
  * @enum {string}
  */
 google.maps.MaxZoomStatus = {
-  OK: '1',
-  ERROR: '2'
+  OK: '',
+  ERROR: ''
 };
 
 /**
@@ -3074,10 +3074,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3392,9 +3392,9 @@ google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng,
  * @enum {string}
  */
 google.maps.StreetViewStatus = {
-  UNKNOWN_ERROR: '1',
-  ZERO_RESULTS: '2',
-  OK: '3'
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: '',
+  OK: ''
 };
 
 /**
@@ -3480,17 +3480,17 @@ google.maps.TrafficLayer.prototype.setMap = function(map) {};
  * @enum {string}
  */
 google.maps.TravelMode = {
-  WALKING: '1',
-  DRIVING: '2',
-  BICYCLING: '3'
+  WALKING: '',
+  DRIVING: '',
+  BICYCLING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.UnitSystem = {
-  METRIC: 1,
-  IMPERIAL: 2
+  METRIC: '',
+  IMPERIAL: ''
 };
 
 /**
@@ -3509,12 +3509,12 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
@@ -3524,17 +3524,17 @@ google.maps.adsense = {};
  * @enum {string}
  */
 google.maps.adsense.AdFormat = {
-  SMALL_RECTANGLE: '1',
-  SMALL_SQUARE: '2',
-  SQUARE: '3',
-  BUTTON: '4',
-  VERTICAL_BANNER: '5',
-  WIDE_SKYSCRAPER: '6',
-  HALF_BANNER: '7',
-  SKYSCRAPER: '8',
-  MEDIUM_RECTANGLE: '9',
-  LARGE_RECTANGLE: '10',
-  BANNER: '11',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SQUARE: '',
+  BUTTON: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
+  HALF_BANNER: '',
+  SKYSCRAPER: '',
+  MEDIUM_RECTANGLE: '',
+  LARGE_RECTANGLE: '',
+  BANNER: '',
   LEADERBOARD: ''
 };
 
@@ -3754,10 +3754,10 @@ google.maps.drawing.OverlayCompleteEvent.prototype.type;
  * @enum {string}
  */
 google.maps.drawing.OverlayType = {
-  MARKER: '1',
-  CIRCLE: '2',
-  POLYLINE: '3',
-  POLYGON: '4',
+  MARKER: '',
+  CIRCLE: '',
+  POLYLINE: '',
+  POLYGON: '',
   RECTANGLE: ''
 };
 
@@ -4250,11 +4250,11 @@ google.maps.places.PlacesService.prototype.search = function(request, callback)
  * @enum {string}
  */
 google.maps.places.PlacesServiceStatus = {
-  OK: '1',
-  ZERO_RESULTS: '2',
-  INVALID_REQUEST: '3',
-  UNKNOWN_ERROR: '4',
-  REQUEST_DENIED: '5',
+  OK: '',
+  ZERO_RESULTS: '',
+  INVALID_REQUEST: '',
+  UNKNOWN_ERROR: '',
+  REQUEST_DENIED: '',
   OVER_QUERY_LIMIT: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_8.js b/contrib/externs/maps/google_maps_api_v3_8.js
index 9bd75da6e..9e8feb813 100644
--- a/contrib/externs/maps/google_maps_api_v3_8.js
+++ b/contrib/externs/maps/google_maps_api_v3_8.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -193,21 +193,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -504,16 +504,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -588,12 +588,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -699,15 +699,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -766,13 +766,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1064,13 +1064,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1124,15 +1124,15 @@ google.maps.GeocoderResult.prototype.geometry;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1506,17 +1506,17 @@ google.maps.KmlLayerOptions.prototype.preserveViewport;
 google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2248,22 +2248,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2673,11 +2673,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3223,10 +3223,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3553,12 +3553,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3641,20 +3641,20 @@ google.maps.TrafficLayer.prototype.getMap = function() {};
 google.maps.TrafficLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  WALKING: '3'
+  BICYCLING: '',
+  DRIVING: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -3673,32 +3673,32 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_RECTANGLE: '4',
-  LEADERBOARD: '5',
-  MEDIUM_RECTANGLE: '6',
-  SKYSCRAPER: '7',
-  SMALL_RECTANGLE: '8',
-  SMALL_SQUARE: '9',
-  SQUARE: '10',
-  VERTICAL_BANNER: '11',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_RECTANGLE: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  SKYSCRAPER: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
   WIDE_SKYSCRAPER: ''
 };
 
@@ -3921,13 +3921,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -4435,14 +4435,14 @@ google.maps.places.PlacesService.prototype.getDetails = function(request, callba
 google.maps.places.PlacesService.prototype.search = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -4468,19 +4468,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -4679,11 +4679,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_9.js b/contrib/externs/maps/google_maps_api_v3_9.js
index 71a5f0cae..88de102be 100644
--- a/contrib/externs/maps/google_maps_api_v3_9.js
+++ b/contrib/externs/maps/google_maps_api_v3_9.js
@@ -23,11 +23,11 @@
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 1,
-  DROP: 2
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -193,21 +193,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 1,
-  BOTTOM_LEFT: 2,
-  BOTTOM_RIGHT: 3,
-  LEFT_BOTTOM: 4,
-  LEFT_CENTER: 5,
-  LEFT_TOP: 6,
-  RIGHT_BOTTOM: 7,
-  RIGHT_CENTER: 8,
-  RIGHT_TOP: 9,
-  TOP_CENTER: 10,
-  TOP_LEFT: 11,
-  TOP_RIGHT: 12
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -519,16 +519,16 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '1',
-  MAX_WAYPOINTS_EXCEEDED: '2',
-  NOT_FOUND: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
-  UNKNOWN_ERROR: '7',
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -613,12 +613,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '1',
-  OK: '2',
-  ZERO_RESULTS: '3'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -724,15 +724,15 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '1',
-  MAX_DIMENSIONS_EXCEEDED: '2',
-  MAX_ELEMENTS_EXCEEDED: '3',
-  OK: '4',
-  OVER_QUERY_LIMIT: '5',
-  REQUEST_DENIED: '6',
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -791,13 +791,13 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
   UNKNOWN_ERROR: ''
 };
 
@@ -1089,13 +1089,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '1',
-  GEOMETRIC_CENTER: '2',
-  RANGE_INTERPOLATED: '3',
-  ROOFTOP: '4'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -1149,15 +1149,15 @@ google.maps.GeocoderResult.prototype.geometry;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '1',
-  INVALID_REQUEST: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
@@ -1551,17 +1551,17 @@ google.maps.KmlLayerOptions.prototype.preserveViewport;
 google.maps.KmlLayerOptions.prototype.suppressInfoWindows;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '1',
-  DOCUMENT_TOO_LARGE: '2',
-  FETCH_ERROR: '3',
-  INVALID_DOCUMENT: '4',
-  INVALID_REQUEST: '5',
-  LIMITS_EXCEEDED: '6',
-  OK: '7',
-  TIMED_OUT: '8',
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
   UNKNOWN: ''
 };
 
@@ -2296,22 +2296,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 1,
-  DROPDOWN_MENU: 2,
-  HORIZONTAL_BAR: 3
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '1',
-  ROADMAP: '2',
-  SATELLITE: '3',
-  TERRAIN: '4'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -2721,11 +2721,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '1',
-  OK: '2'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -3297,10 +3297,10 @@ google.maps.ScaleControlOptions.prototype.position;
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 1
+  DEFAULT: ''
 };
 
 /**
@@ -3627,12 +3627,12 @@ google.maps.StreetViewService.prototype.getPanoramaById = function(pano, callbac
 google.maps.StreetViewService.prototype.getPanoramaByLocation = function(latlng, radius, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '1',
-  UNKNOWN_ERROR: '2',
-  ZERO_RESULTS: '3'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -3747,14 +3747,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 1,
-  BACKWARD_OPEN_ARROW: 2,
-  CIRCLE: 3,
-  FORWARD_CLOSED_ARROW: 4,
-  FORWARD_OPEN_ARROW: 5
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -3974,21 +3974,21 @@ google.maps.TransitVehicle.prototype.local_icon;
 google.maps.TransitVehicle.prototype.name;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '1',
-  DRIVING: '2',
-  TRANSIT: '3',
-  WALKING: '4'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 1,
-  METRIC: 2
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -4007,32 +4007,32 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 1,
-  LARGE: 2,
-  SMALL: 3
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
 };
 
 // Namespace
 google.maps.adsense = {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.adsense.AdFormat = {
-  BANNER: '1',
-  BUTTON: '2',
-  HALF_BANNER: '3',
-  LARGE_RECTANGLE: '4',
-  LEADERBOARD: '5',
-  MEDIUM_RECTANGLE: '6',
-  SKYSCRAPER: '7',
-  SMALL_RECTANGLE: '8',
-  SMALL_SQUARE: '9',
-  SQUARE: '10',
-  VERTICAL_BANNER: '11',
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_RECTANGLE: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  SKYSCRAPER: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
   WIDE_SKYSCRAPER: ''
 };
 
@@ -4255,13 +4255,13 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '1',
-  MARKER: '2',
-  POLYGON: '3',
-  POLYLINE: '4',
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
   RECTANGLE: ''
 };
 
@@ -4818,23 +4818,23 @@ google.maps.places.PlacesService.prototype.nearbySearch = function(request, call
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
   ZERO_RESULTS: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 1,
-  PROMINENCE: 2
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -4973,19 +4973,19 @@ google.maps.weather.CloudLayer.prototype.getMap = function() {};
 google.maps.weather.CloudLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.LabelColor = {
-  BLACK: '1',
-  WHITE: '2'
+  BLACK: '',
+  WHITE: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.TemperatureUnit = {
-  CELSIUS: '1',
-  FAHRENHEIT: '2'
+  CELSIUS: '',
+  FAHRENHEIT: ''
 };
 
 /**
@@ -5184,11 +5184,11 @@ google.maps.weather.WeatherMouseEvent.prototype.latLng;
 google.maps.weather.WeatherMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.weather.WindSpeedUnit = {
-  KILOMETERS_PER_HOUR: '1',
-  METERS_PER_SECOND: '2',
-  MILES_PER_HOUR: '3'
+  KILOMETERS_PER_HOUR: '',
+  METERS_PER_SECOND: '',
+  MILES_PER_HOUR: ''
 };
 
diff --git a/contrib/externs/maps/google_maps_api_v3_exp.js b/contrib/externs/maps/google_maps_api_v3_exp.js
index 0dfa09373..de65c6172 100644
--- a/contrib/externs/maps/google_maps_api_v3_exp.js
+++ b/contrib/externs/maps/google_maps_api_v3_exp.js
@@ -30,11 +30,11 @@ var google = {};
 google.maps = {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.Animation = {
-  BOUNCE: 0,
-  DROP: 1
+  BOUNCE: '',
+  DROP: ''
 };
 
 /**
@@ -242,21 +242,21 @@ google.maps.CircleOptions.prototype.visible;
 google.maps.CircleOptions.prototype.zIndex;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ControlPosition = {
-  BOTTOM_CENTER: 0,
-  BOTTOM_LEFT: 1,
-  BOTTOM_RIGHT: 2,
-  LEFT_BOTTOM: 3,
-  LEFT_CENTER: 4,
-  LEFT_TOP: 5,
-  RIGHT_BOTTOM: 6,
-  RIGHT_CENTER: 7,
-  RIGHT_TOP: 8,
-  TOP_CENTER: 9,
-  TOP_LEFT: 10,
-  TOP_RIGHT: 11
+  BOTTOM_CENTER: '',
+  BOTTOM_LEFT: '',
+  BOTTOM_RIGHT: '',
+  LEFT_BOTTOM: '',
+  LEFT_CENTER: '',
+  LEFT_TOP: '',
+  RIGHT_BOTTOM: '',
+  RIGHT_CENTER: '',
+  RIGHT_TOP: '',
+  TOP_CENTER: '',
+  TOP_LEFT: '',
+  TOP_RIGHT: ''
 };
 
 /**
@@ -1300,17 +1300,17 @@ google.maps.DirectionsService = function() {};
 google.maps.DirectionsService.prototype.route = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DirectionsStatus = {
-  INVALID_REQUEST: '0',
-  MAX_WAYPOINTS_EXCEEDED: '1',
-  NOT_FOUND: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6',
-  ZERO_RESULTS: '7'
+  INVALID_REQUEST: '',
+  MAX_WAYPOINTS_EXCEEDED: '',
+  NOT_FOUND: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1394,12 +1394,12 @@ google.maps.Distance.prototype.text;
 google.maps.Distance.prototype.value;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixElementStatus = {
-  NOT_FOUND: '0',
-  OK: '1',
-  ZERO_RESULTS: '2'
+  NOT_FOUND: '',
+  OK: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -1530,16 +1530,16 @@ google.maps.DistanceMatrixService = function() {};
 google.maps.DistanceMatrixService.prototype.getDistanceMatrix = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.DistanceMatrixStatus = {
-  INVALID_REQUEST: '0',
-  MAX_DIMENSIONS_EXCEEDED: '1',
-  MAX_ELEMENTS_EXCEEDED: '2',
-  OK: '3',
-  OVER_QUERY_LIMIT: '4',
-  REQUEST_DENIED: '5',
-  UNKNOWN_ERROR: '6'
+  INVALID_REQUEST: '',
+  MAX_DIMENSIONS_EXCEEDED: '',
+  MAX_ELEMENTS_EXCEEDED: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -1612,14 +1612,14 @@ google.maps.ElevationService.prototype.getElevationAlongPath = function(request,
 google.maps.ElevationService.prototype.getElevationForLocations = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.ElevationStatus = {
-  INVALID_REQUEST: '0',
-  OK: '1',
-  OVER_QUERY_LIMIT: '2',
-  REQUEST_DENIED: '3',
-  UNKNOWN_ERROR: '4'
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
@@ -1940,13 +1940,13 @@ google.maps.GeocoderGeometry.prototype.location_type;
 google.maps.GeocoderGeometry.prototype.viewport;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderLocationType = {
-  APPROXIMATE: '0',
-  GEOMETRIC_CENTER: '1',
-  RANGE_INTERPOLATED: '2',
-  ROOFTOP: '3'
+  APPROXIMATE: '',
+  GEOMETRIC_CENTER: '',
+  RANGE_INTERPOLATED: '',
+  ROOFTOP: ''
 };
 
 /**
@@ -2025,16 +2025,16 @@ google.maps.GeocoderResult.prototype.postcode_localities;
 google.maps.GeocoderResult.prototype.types;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.GeocoderStatus = {
-  ERROR: '0',
-  INVALID_REQUEST: '1',
-  OK: '2',
-  OVER_QUERY_LIMIT: '3',
-  REQUEST_DENIED: '4',
-  UNKNOWN_ERROR: '5',
-  ZERO_RESULTS: '6'
+  ERROR: '',
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -2554,18 +2554,18 @@ google.maps.KmlLayerOptions.prototype.url;
 google.maps.KmlLayerOptions.prototype.zIndex;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.KmlLayerStatus = {
-  DOCUMENT_NOT_FOUND: '0',
-  DOCUMENT_TOO_LARGE: '1',
-  FETCH_ERROR: '2',
-  INVALID_DOCUMENT: '3',
-  INVALID_REQUEST: '4',
-  LIMITS_EXCEEDED: '5',
-  OK: '6',
-  TIMED_OUT: '7',
-  UNKNOWN: '8'
+  DOCUMENT_NOT_FOUND: '',
+  DOCUMENT_TOO_LARGE: '',
+  FETCH_ERROR: '',
+  INVALID_DOCUMENT: '',
+  INVALID_REQUEST: '',
+  LIMITS_EXCEEDED: '',
+  OK: '',
+  TIMED_OUT: '',
+  UNKNOWN: ''
 };
 
 /**
@@ -2612,11 +2612,6 @@ google.maps.LatLng.prototype.lat = function() {};
  */
 google.maps.LatLng.prototype.lng = function() {};
 
-/**
- * @return {google.maps.LatLngLiteral}
- */
-google.maps.LatLng.prototype.toJSON = function() {};
-
 /**
  * @return {string}
  */
@@ -2682,11 +2677,6 @@ google.maps.LatLngBounds.prototype.intersects = function(other) {};
  */
 google.maps.LatLngBounds.prototype.isEmpty = function() {};
 
-/**
- * @return {google.maps.LatLngBoundsLiteral}
- */
-google.maps.LatLngBounds.prototype.toJSON = function() {};
-
 /**
  * @return {google.maps.LatLng}
  */
@@ -3351,22 +3341,22 @@ google.maps.MapTypeControlOptions.prototype.position;
 google.maps.MapTypeControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.MapTypeControlStyle = {
-  DEFAULT: 0,
-  DROPDOWN_MENU: 1,
-  HORIZONTAL_BAR: 2
+  DEFAULT: '',
+  DROPDOWN_MENU: '',
+  HORIZONTAL_BAR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MapTypeId = {
-  HYBRID: '0',
-  ROADMAP: '1',
-  SATELLITE: '2',
-  TERRAIN: '3'
+  HYBRID: '',
+  ROADMAP: '',
+  SATELLITE: '',
+  TERRAIN: ''
 };
 
 /**
@@ -3840,11 +3830,11 @@ google.maps.MaxZoomService = function() {};
 google.maps.MaxZoomService.prototype.getMaxZoomAtLatLng = function(latlng, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.MaxZoomStatus = {
-  ERROR: '0',
-  OK: '1'
+  ERROR: '',
+  OK: ''
 };
 
 /**
@@ -4545,10 +4535,10 @@ google.maps.ScaleControlOptions = function() {};
 google.maps.ScaleControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ScaleControlStyle = {
-  DEFAULT: 0
+  DEFAULT: ''
 };
 
 /**
@@ -4955,11 +4945,11 @@ google.maps.StreetViewPov.prototype.heading;
 google.maps.StreetViewPov.prototype.pitch;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewPreference = {
-  BEST: '0',
-  NEAREST: '1'
+  BEST: '',
+  NEAREST: ''
 };
 
 /**
@@ -4975,20 +4965,20 @@ google.maps.StreetViewService = function() {};
 google.maps.StreetViewService.prototype.getPanorama = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewSource = {
-  DEFAULT: '0',
-  OUTDOOR: '1'
+  DEFAULT: '',
+  OUTDOOR: ''
 };
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.StreetViewStatus = {
-  OK: '0',
-  UNKNOWN_ERROR: '1',
-  ZERO_RESULTS: '2'
+  OK: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -5021,12 +5011,12 @@ google.maps.StreetViewTileData.prototype.worldSize;
 google.maps.StreetViewTileData.prototype.getTileUrl = function(pano, tileZoom, tileX, tileY) {};
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.StrokePosition = {
-  CENTER: 0,
-  INSIDE: 1,
-  OUTSIDE: 2
+  CENTER: '',
+  INSIDE: '',
+  OUTSIDE: ''
 };
 
 /**
@@ -5168,14 +5158,14 @@ google.maps.Symbol.prototype.strokeOpacity;
 google.maps.Symbol.prototype.strokeWeight;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.SymbolPath = {
-  BACKWARD_CLOSED_ARROW: 0,
-  BACKWARD_OPEN_ARROW: 1,
-  CIRCLE: 2,
-  FORWARD_CLOSED_ARROW: 3,
-  FORWARD_OPEN_ARROW: 4
+  BACKWARD_CLOSED_ARROW: '',
+  BACKWARD_OPEN_ARROW: '',
+  CIRCLE: '',
+  FORWARD_CLOSED_ARROW: '',
+  FORWARD_OPEN_ARROW: ''
 };
 
 /**
@@ -5217,12 +5207,12 @@ google.maps.TrafficLayer.prototype.getMap = function() {};
 google.maps.TrafficLayer.prototype.setMap = function(map) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TrafficModel = {
-  BEST_GUESS: '0',
-  OPTIMISTIC: '1',
-  PESSIMISTIC: '2'
+  BEST_GUESS: '',
+  OPTIMISTIC: '',
+  PESSIMISTIC: ''
 };
 
 /**
@@ -5359,14 +5349,14 @@ google.maps.TransitLine.prototype.url;
 google.maps.TransitLine.prototype.vehicle;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitMode = {
-  BUS: '0',
-  RAIL: '1',
-  SUBWAY: '2',
-  TRAIN: '3',
-  TRAM: '4'
+  BUS: '',
+  RAIL: '',
+  SUBWAY: '',
+  TRAIN: '',
+  TRAM: ''
 };
 
 /**
@@ -5395,11 +5385,11 @@ google.maps.TransitOptions.prototype.modes;
 google.maps.TransitOptions.prototype.routingPreference;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TransitRoutePreference = {
-  FEWER_TRANSFERS: '0',
-  LESS_WALKING: '1'
+  FEWER_TRANSFERS: '',
+  LESS_WALKING: ''
 };
 
 /**
@@ -5443,21 +5433,21 @@ google.maps.TransitVehicle.prototype.name;
 google.maps.TransitVehicle.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.TravelMode = {
-  BICYCLING: '0',
-  DRIVING: '1',
-  TRANSIT: '2',
-  WALKING: '3'
+  BICYCLING: '',
+  DRIVING: '',
+  TRANSIT: '',
+  WALKING: ''
 };
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.UnitSystem = {
-  IMPERIAL: 0,
-  METRIC: 1
+  IMPERIAL: '',
+  METRIC: ''
 };
 
 /**
@@ -5476,14 +5466,49 @@ google.maps.ZoomControlOptions.prototype.position;
 google.maps.ZoomControlOptions.prototype.style;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.ZoomControlStyle = {
-  DEFAULT: 0,
-  LARGE: 1,
-  SMALL: 2
+  DEFAULT: '',
+  LARGE: '',
+  SMALL: ''
+};
+
+/** @const */
+google.maps.adsense = {};
+
+/**
+ * @enum {number|string}
+ */
+google.maps.adsense.AdFormat = {
+  BANNER: '',
+  BUTTON: '',
+  HALF_BANNER: '',
+  LARGE_HORIZONTAL_LINK_UNIT: '',
+  LARGE_RECTANGLE: '',
+  LARGE_VERTICAL_LINK_UNIT: '',
+  LEADERBOARD: '',
+  MEDIUM_RECTANGLE: '',
+  MEDIUM_VERTICAL_LINK_UNIT: '',
+  SKYSCRAPER: '',
+  SMALL_HORIZONTAL_LINK_UNIT: '',
+  SMALL_RECTANGLE: '',
+  SMALL_SQUARE: '',
+  SMALL_VERTICAL_LINK_UNIT: '',
+  SQUARE: '',
+  VERTICAL_BANNER: '',
+  WIDE_SKYSCRAPER: '',
+  X_LARGE_VERTICAL_LINK_UNIT: ''
 };
 
+/**
+ * @param {*} container
+ * @param {Object} opts
+ * @extends {google.maps.MVCObject}
+ * @constructor
+ */
+google.maps.adsense.AdUnit = function(container, opts) {};
+
 /** @const */
 google.maps.drawing = {};
 
@@ -5605,14 +5630,14 @@ google.maps.drawing.OverlayCompleteEvent.prototype.overlay;
 google.maps.drawing.OverlayCompleteEvent.prototype.type;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.drawing.OverlayType = {
-  CIRCLE: '0',
-  MARKER: '1',
-  POLYGON: '2',
-  POLYLINE: '3',
-  RECTANGLE: '4'
+  CIRCLE: '',
+  MARKER: '',
+  POLYGON: '',
+  POLYLINE: '',
+  RECTANGLE: ''
 };
 
 /** @const */
@@ -6263,15 +6288,15 @@ google.maps.places.PlacesService.prototype.radarSearch = function(request, callb
 google.maps.places.PlacesService.prototype.textSearch = function(request, callback) {};
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.places.PlacesServiceStatus = {
-  INVALID_REQUEST: '0',
-  OK: '1',
-  OVER_QUERY_LIMIT: '2',
-  REQUEST_DENIED: '3',
-  UNKNOWN_ERROR: '4',
-  ZERO_RESULTS: '5'
+  INVALID_REQUEST: '',
+  OK: '',
+  OVER_QUERY_LIMIT: '',
+  REQUEST_DENIED: '',
+  UNKNOWN_ERROR: '',
+  ZERO_RESULTS: ''
 };
 
 /**
@@ -6395,11 +6420,11 @@ google.maps.places.RadarSearchRequest.prototype.radius;
 google.maps.places.RadarSearchRequest.prototype.types;
 
 /**
- * @enum {number}
+ * @enum {number|string}
  */
 google.maps.places.RankBy = {
-  DISTANCE: 0,
-  PROMINENCE: 1
+  DISTANCE: '',
+  PROMINENCE: ''
 };
 
 /**
@@ -6959,12 +6984,12 @@ google.maps.visualization.MapsEngineMouseEvent.prototype.latLng;
 google.maps.visualization.MapsEngineMouseEvent.prototype.pixelOffset;
 
 /**
- * @enum {string}
+ * @enum {number|string}
  */
 google.maps.visualization.MapsEngineStatus = {
-  INVALID_LAYER: '0',
-  OK: '1',
-  UNKNOWN_ERROR: '2'
+  INVALID_LAYER: '',
+  OK: '',
+  UNKNOWN_ERROR: ''
 };
 
 /**
diff --git a/externs/browser/w3c_rtc.js b/externs/browser/w3c_rtc.js
index 7c9eb6e86..a974ec904 100644
--- a/externs/browser/w3c_rtc.js
+++ b/externs/browser/w3c_rtc.js
@@ -53,7 +53,6 @@ SourceInfo.prototype.facing;
 
 /**
  * @interface
- * @extends {EventTarget}
  * @see http://www.w3.org/TR/mediacapture-streams/#mediastreamtrack
  */
 function MediaStreamTrack() {}
@@ -86,18 +85,6 @@ MediaStreamTrack.prototype.label;
  */
 MediaStreamTrack.prototype.enabled;
 
-/**
- * @type {boolean}
- * @const
- */
-MediaStreamTrack.prototype.muted;
-
-/**
- * @type {boolean}
- * @const
- */
-MediaStreamTrack.prototype.remote;
-
 /**
  * @type {MediaStreamTrackState}
  * Read only.
@@ -193,11 +180,6 @@ MediaStream.prototype.getAudioTracks = function() {};
  */
 MediaStream.prototype.getVideoTracks = function() {};
 
-/**
- * @return {!Array<!MediaStreamTrack>}
- */
-MediaStream.prototype.getTracks = function() {};
-
 /**
  * @param {string} trackId
  * @return {MediaStreamTrack}
@@ -214,11 +196,6 @@ MediaStream.prototype.addTrack = function(track) {};
  */
 MediaStream.prototype.removeTrack = function(track) {};
 
-/**
- * @return {!MediaStream}
- */
-MediaStream.prototype.clone = function() {};
-
 /**
  * @deprecated
  * @type {boolean}
diff --git a/src/com/google/javascript/jscomp/AbstractCommandLineRunner.java b/src/com/google/javascript/jscomp/AbstractCommandLineRunner.java
index d49d6a5ff..8cee6eb71 100644
--- a/src/com/google/javascript/jscomp/AbstractCommandLineRunner.java
+++ b/src/com/google/javascript/jscomp/AbstractCommandLineRunner.java
@@ -33,6 +33,7 @@ import com.google.common.io.ByteStreams;
 import com.google.gson.Gson;
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonWriter;
+import com.google.javascript.jscomp.CompilerOptions.JsonStreamMode;
 import com.google.javascript.jscomp.CompilerOptions.TweakProcessing;
 import com.google.javascript.jscomp.deps.ClosureBundler;
 import com.google.javascript.jscomp.deps.SourceCodeEscapers;
@@ -226,6 +227,15 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
     return testMode;
   }
 
+  /**
+   * Returns whether output should be a JSON stream.
+   */
+  private boolean isOutputInJson() {
+    return config.jsonStreamMode == JsonStreamMode.OUT
+        || config.jsonStreamMode == JsonStreamMode.BOTH;
+  }
+
+
   /**
    * Get the command line config, so that it can be initialized.
    */
@@ -368,7 +378,7 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
 
     if (config.createSourceMap.length() > 0) {
       options.sourceMapOutputPath = config.createSourceMap;
-    } else if (config.useJsonStreams) {
+    } else if (isOutputInJson()) {
       options.sourceMapOutputPath = "%outname%";
     }
     options.sourceMapDetailLevel = config.sourceMapDetailLevel;
@@ -1041,7 +1051,8 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
     List<String> moduleSpecs = config.module;
     List<JsonFileSpec> jsonFiles = null;
 
-    if (config.useJsonStreams) {
+    if (config.jsonStreamMode == JsonStreamMode.IN ||
+        config.jsonStreamMode == JsonStreamMode.BOTH) {
       jsonFiles = parseJsonFilesFromInputStream();
 
       ImmutableMap.Builder<String, SourceMapInput> inputSourceMaps
@@ -1171,7 +1182,7 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
         // Output the source map if requested.
         // If output files are being written to stdout as a JSON string,
         // outputSingleBinary will have added the sourcemap to the output file
-        if (!config.useJsonStreams) {
+        if (!isOutputInJson()) {
           outputSourceMap(options, config.jsOutputFile);
         }
       } else {
@@ -1192,7 +1203,7 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
       outputManifest();
       outputBundle();
 
-      if (config.useJsonStreams) {
+      if (isOutputInJson()) {
         outputJsonStream();
       }
     }
@@ -1213,13 +1224,9 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
       escaper = getJavascriptEscaper();
     }
 
-    if (config.useJsonStreams) {
+    if (isOutputInJson()) {
       this.filesToStreamOut.add(createJsonFile(options, marker, escaper));
     } else {
-      if(!config.jsOutputFile.isEmpty()) {
-        maybeCreateDirsForPath(config.jsOutputFile);
-      }
-
       Appendable jsOutput = createDefaultOutput();
       writeOutput(
           jsOutput, compiler, compiler.toSource(), config.outputWrapper,
@@ -1283,13 +1290,13 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
 
     // When the json_streams flag is specified, sourcemaps are always generated
     // per module
-    if (!(shouldGenerateMapPerModule(options) || config.useJsonStreams)) {
+    if (!(shouldGenerateMapPerModule(options) || isOutputInJson())) {
       mapFileOut = fileNameToOutputWriter2(
           expandSourceMapPath(options, null));
     }
 
     for (JSModule m : modules) {
-      if (config.useJsonStreams) {
+      if (isOutputInJson()) {
         this.filesToStreamOut.add(createJsonFileFromModule(m));
       } else {
         if (shouldGenerateMapPerModule(options)) {
@@ -1557,7 +1564,8 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
     }
 
     String outName = expandSourceMapPath(options, null);
-    maybeCreateDirsForPath(outName);
+    File outPath = new File(outName);
+    maybeCreateDirsForPath(outPath.getParent());
     try (Writer out = fileNameToOutputWriter2(outName)) {
       compiler.getSourceMap().appendTo(out, associatedName);
     }
@@ -2446,10 +2454,10 @@ public abstract class AbstractCommandLineRunner<A extends Compiler,
         return this;
     }
 
-    private boolean useJsonStreams = false;
+    private JsonStreamMode jsonStreamMode = JsonStreamMode.NONE;
 
-    CommandLineConfig setUseJsonStreams(boolean useJsonStreams) {
-      this.useJsonStreams = useJsonStreams;
+    CommandLineConfig setJsonStreamMode(JsonStreamMode mode) {
+      this.jsonStreamMode = mode;
       return this;
     }
 
diff --git a/src/com/google/javascript/jscomp/CodeGenerator.java b/src/com/google/javascript/jscomp/CodeGenerator.java
index c8701ae9e..53d32fe20 100644
--- a/src/com/google/javascript/jscomp/CodeGenerator.java
+++ b/src/com/google/javascript/jscomp/CodeGenerator.java
@@ -812,15 +812,13 @@ class CodeGenerator {
         break;
 
       case Token.YIELD:
+        Preconditions.checkState(childCount == 1);
         add("yield");
+        cc.maybeInsertSpace();
         if (n.isYieldFor()) {
-          Preconditions.checkNotNull(first);
           add("*");
         }
-        if (first != null) {
-          cc.maybeInsertSpace();
-          addExpr(first, NodeUtil.precedence(type), Context.OTHER);
-        }
+        addExpr(first, NodeUtil.precedence(type), Context.OTHER);
         break;
 
       case Token.FALSE:
diff --git a/src/com/google/javascript/jscomp/CommandLineRunner.java b/src/com/google/javascript/jscomp/CommandLineRunner.java
index 660b8b38a..a1d9e38af 100644
--- a/src/com/google/javascript/jscomp/CommandLineRunner.java
+++ b/src/com/google/javascript/jscomp/CommandLineRunner.java
@@ -607,12 +607,13 @@ public class CommandLineRunner extends
 
     @Option(name = "--json_streams",
         hidden = true,
-        handler = BooleanOptionHandler.class,
-        usage = "Specifies that standard input and output streams will be "
+        usage = "Specifies whether standard input and output streams will be "
             + "a JSON array of sources. Each source will be an object of the "
             + "form {path: filename, src: file_contents, srcmap: srcmap_contents }. "
-            + "Intended for use by stream-based build systems such as gulpjs.")
-    private boolean jsonStreams = false;
+            + "Intended for use by stream-based build systems such as gulpjs. "
+            + "Options: NONE, IN, OUT, BOTH. Defaults to NONE.")
+    private CompilerOptions.JsonStreamMode jsonStreamMode =
+        CompilerOptions.JsonStreamMode.NONE;
 
     @Argument
     private List<String> arguments = new ArrayList<>();
@@ -1131,7 +1132,7 @@ public class CommandLineRunner extends
           .setTracerMode(flags.tracerMode)
           .setInstrumentationTemplateFile(flags.instrumentationFile)
           .setNewTypeInference(flags.useNewTypeInference)
-          .setUseJsonStreams(flags.jsonStreams);
+          .setJsonStreamMode(flags.jsonStreamMode);
     }
     errorStream = null;
   }
@@ -1219,27 +1220,27 @@ public class CommandLineRunner extends
     options.setConformanceConfigs(loadConformanceConfigs(flags.conformanceConfigs));
 
     if (!flags.instrumentationFile.isEmpty()) {
-      String instrumentationPb;
-      Instrumentation.Builder builder = Instrumentation.newBuilder();
+        String instrumentationPb;
+        Instrumentation.Builder builder = Instrumentation.newBuilder();
       try (BufferedReader br =
-          new BufferedReader(Files.newReader(new File(flags.instrumentationFile), UTF_8))) {
-        StringBuilder sb = new StringBuilder();
-        String line = br.readLine();
-
-        while (line != null) {
-          sb.append(line);
-          sb.append(System.lineSeparator());
-          line = br.readLine();
-        }
-        instrumentationPb = sb.toString();
-        TextFormat.merge(instrumentationPb, builder);
+              new BufferedReader(Files.newReader(new File(flags.instrumentationFile), UTF_8))) {
+            StringBuilder sb = new StringBuilder();
+            String line = br.readLine();
+
+            while (line != null) {
+                sb.append(line);
+                sb.append(System.lineSeparator());
+                line = br.readLine();
+            }
+            instrumentationPb = sb.toString();
+            TextFormat.merge(instrumentationPb, builder);
 
-        // Setting instrumentation template
-        options.instrumentationTemplate = builder.build();
+            // Setting instrumentation template
+            options.instrumentationTemplate = builder.build();
 
-      } catch (IOException e) {
-        throw new RuntimeException("Error reading instrumentation template", e);
-      }
+        } catch (IOException e) {
+            throw new RuntimeException("Error reading instrumentation template", e);
+        }
     }
 
     return options;
diff --git a/src/com/google/javascript/jscomp/CompilerOptions.java b/src/com/google/javascript/jscomp/CompilerOptions.java
index fc1a2f294..67e41cab5 100644
--- a/src/com/google/javascript/jscomp/CompilerOptions.java
+++ b/src/com/google/javascript/jscomp/CompilerOptions.java
@@ -2639,4 +2639,30 @@ public class CompilerOptions {
      */
     CUSTOM
   }
+
+  /**
+   * Whether standard input or standard output should be an array of
+   * JSON encoded files
+   */
+  static enum JsonStreamMode {
+    /**
+     * stdin/out are both single files.
+     */
+    NONE,
+
+    /**
+     * stdin is a json stream.
+     */
+    IN,
+
+    /**
+     * stdout is a json stream.
+     */
+    OUT,
+
+    /**
+     * stdin and stdout are both json streams.
+     */
+    BOTH
+  }
 }
diff --git a/src/com/google/javascript/jscomp/GlobalTypeInfo.java b/src/com/google/javascript/jscomp/GlobalTypeInfo.java
index 708d70117..78ab9d70b 100644
--- a/src/com/google/javascript/jscomp/GlobalTypeInfo.java
+++ b/src/com/google/javascript/jscomp/GlobalTypeInfo.java
@@ -1672,16 +1672,17 @@ class GlobalTypeInfo implements CompilerPass {
       QualifiedName recvQname = QualifiedName.fromNode(recv);
       String pname = n.getLastChild().getString();
       Declaration decl = this.currentScope.getDeclaration(recvQname, false);
+      if (decl == null) {
+        return null;
+      }
+      EnumType et = decl.getEnum();
+      if (et != null && et.enumLiteralHasKey(pname)) {
+        return et.getEnumeratedType();
+      }
       QualifiedName propQname = new QualifiedName(pname);
-      if (decl != null) {
-        EnumType et = decl.getEnum();
-        if (et != null && et.enumLiteralHasKey(pname)) {
-          return et.getEnumeratedType();
-        }
-        Namespace ns = decl.getNamespace();
-        if (ns != null) {
-          return simpleInferDeclaration(ns.getDeclaration(propQname));
-        }
+      Namespace ns = decl.getNamespace();
+      if (ns != null) {
+        return simpleInferDeclaration(ns.getDeclaration(propQname));
       }
       JSType recvType = simpleInferExprType(recv);
       if (recvType != null && recvType.mayHaveProp(propQname)) {
diff --git a/src/com/google/javascript/jscomp/InlineAliases.java b/src/com/google/javascript/jscomp/InlineAliases.java
index 381dbc04a..1a7968d2a 100644
--- a/src/com/google/javascript/jscomp/InlineAliases.java
+++ b/src/com/google/javascript/jscomp/InlineAliases.java
@@ -16,6 +16,7 @@
 
 package com.google.javascript.jscomp;
 
+import com.google.common.base.Preconditions;
 import com.google.common.base.Predicates;
 import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
 import com.google.javascript.rhino.JSDocInfo;
@@ -24,9 +25,7 @@ import com.google.javascript.rhino.Node;
 import com.google.javascript.rhino.Token;
 
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Inline aliases created by exports of modules before type checking.
@@ -37,10 +36,7 @@ import java.util.Set;
  *
  * @author blickly@gmail.com (Ben Lickly)
  */
-final class InlineAliases implements CompilerPass {
-
-  static final DiagnosticType ALIAS_CYCLE =
-      DiagnosticType.error("JSC_ALIAS_CYCLE", "Alias path contains a cycle: {0} to {1}");
+final class InlineAliases extends AbstractPostOrderCallback implements CompilerPass {
 
   private final AbstractCompiler compiler;
   private final Map<String, String> aliases = new LinkedHashMap<>();
@@ -53,140 +49,95 @@ final class InlineAliases implements CompilerPass {
   @Override
   public void process(Node externs, Node root) {
     namespace = new GlobalNamespace(compiler, root);
-    NodeTraversal.traverseEs6(compiler, root, new AliasesCollector());
-    NodeTraversal.traverseEs6(compiler, root, new AliasesInliner());
+    NodeTraversal.traverseEs6(compiler, root, this);
   }
 
-  private class AliasesCollector extends AbstractPostOrderCallback {
-    @Override
-    public void visit(NodeTraversal t, Node n, Node parent) {
-      switch (n.getType()) {
-        case Token.VAR:
-          if (n.getChildCount() == 1 && t.inGlobalScope()) {
-            visitAliasDefinition(n.getFirstChild(), NodeUtil.getBestJSDocInfo(n.getFirstChild()));
-          }
-          break;
-        case Token.ASSIGN:
-          if (parent != null && parent.isExprResult() && t.inGlobalScope()) {
-            visitAliasDefinition(n.getFirstChild(), n.getJSDocInfo());
-          }
-          break;
-      }
-    }
-
-    /**
-     * Maybe record that given lvalue is an alias of the qualified name on its rhs.
-     * Note that since we are doing a post-order traversal, any previous aliases contained in
-     * the rhs will have already been substituted by the time we record the new alias.
-     */
-    private void visitAliasDefinition(Node lhs, JSDocInfo info) {
-      if (info != null && info.hasConstAnnotation() && lhs.isQualifiedName()) {
-        Node rhs = NodeUtil.getRValueOfLValue(lhs);
-        if (rhs != null && rhs.isQualifiedName()) {
-          GlobalNamespace.Name lhsName = namespace.getOwnSlot(lhs.getQualifiedName());
-          GlobalNamespace.Name rhsName = namespace.getOwnSlot(rhs.getQualifiedName());
-          if (lhsName != null
-              && lhsName.isInlinableGlobalAlias()
-              && rhsName != null
-              && rhsName.isInlinableGlobalAlias()
-              && !isPrivate(rhsName.getDeclaration().getNode())) {
-            aliases.put(lhs.getQualifiedName(), rhs.getQualifiedName());
-          }
+  /**
+    * Maybe record that given lvalue is an alias of the qualified name on its rhs.
+    * Note that since we are doing a post-order traversal, any previous aliases contained in
+    * the rhs will have already been substituted by the time we record the new alias.
+    */
+  private void visitAliasDefinition(Node lhs, JSDocInfo info) {
+    if (info != null && info.hasConstAnnotation() && lhs.isQualifiedName()) {
+      Node rhs = NodeUtil.getRValueOfLValue(lhs);
+      if (rhs != null && rhs.isQualifiedName()) {
+        GlobalNamespace.Name lhsName = namespace.getOwnSlot(lhs.getQualifiedName());
+        GlobalNamespace.Name rhsName = namespace.getOwnSlot(rhs.getQualifiedName());
+        if (lhsName != null && lhsName.isInlinableGlobalAlias()
+            && rhsName != null && rhsName.isInlinableGlobalAlias()
+            && !isPrivate(rhsName.getDeclaration().getNode())) {
+          aliases.put(lhs.getQualifiedName(), rhs.getQualifiedName());
         }
       }
     }
+  }
 
-    private boolean isPrivate(Node nameNode) {
-      if (nameNode.isQualifiedName()
-          && compiler.getCodingConvention().isPrivate(nameNode.getQualifiedName())) {
-        return true;
-      }
-      JSDocInfo info = NodeUtil.getBestJSDocInfo(nameNode);
-      return info != null && info.getVisibility().equals(Visibility.PRIVATE);
+  private boolean isPrivate(Node nameNode) {
+    if (nameNode.isQualifiedName()
+        && compiler.getCodingConvention().isPrivate(nameNode.getQualifiedName())) {
+      return true;
     }
+    JSDocInfo info = NodeUtil.getBestJSDocInfo(nameNode);
+    return info != null && info.getVisibility().equals(Visibility.PRIVATE);
   }
 
-  private class AliasesInliner extends AbstractPostOrderCallback {
-    @Override
-    public void visit(NodeTraversal t, Node n, Node parent) {
-      switch (n.getType()) {
-        case Token.NAME:
-        case Token.GETPROP:
-          if (n.isQualifiedName() && aliases.containsKey(n.getQualifiedName())) {
-            String leftmostName = NodeUtil.getRootOfQualifiedName(n).getString();
-            Var v = t.getScope().getVar(leftmostName);
-            if (v != null && v.isLocal()) {
-              // Shadow of alias. Don't rewrite
-              return;
-            }
-            if (NodeUtil.isVarOrSimpleAssignLhs(n, parent)) {
-              // Alias definition. Don't rewrite
-              return;
-            }
-
-            parent.replaceChild(
-                n,
-                NodeUtil.newQName(compiler, resolveAlias(n.getQualifiedName(), n))
-                    .copyInformationFromForTree(n));
-            compiler.reportCodeChange();
+  @Override
+  public void visit(NodeTraversal t, Node n, Node parent) {
+    switch (n.getType()) {
+      case Token.VAR:
+        if (n.getChildCount() == 1 && t.inGlobalScope()) {
+          visitAliasDefinition(n.getFirstChild(), NodeUtil.getBestJSDocInfo(n.getFirstChild()));
+        }
+        break;
+      case Token.ASSIGN:
+        if (parent != null && parent.isExprResult() && t.inGlobalScope()) {
+          visitAliasDefinition(n.getFirstChild(), n.getJSDocInfo());
+        }
+        break;
+      case Token.NAME:
+      case Token.GETPROP:
+        if (n.isQualifiedName() && aliases.containsKey(n.getQualifiedName())) {
+          String leftmostName = NodeUtil.getRootOfQualifiedName(n).getString();
+          Var v = t.getScope().getVar(leftmostName);
+          if (v != null && v.isLocal()) {
+            // Shadow of alias. Don't rewrite
+            return;
           }
-          break;
-      }
-      maybeRewriteJsdoc(n.getJSDocInfo());
-    }
-
-    /**
-     * Use the alias table to look up the resolved name of the given alias. If the result is also an
-     * alias repeat until the real name is resolved.
-     * @param n
-     */
-    private String resolveAlias(String name, Node n) {
-      Set<String> aliasPath = new LinkedHashSet<>();
-      while (aliases.containsKey(name)) {
-        if (!aliasPath.add(name)) {
-          compiler.report(JSError.make(n, ALIAS_CYCLE, aliasPath.toString(), name));
-
-          // Cut the cycle so that it doesn't get reported more than once.
-          aliases.remove(name);
-          break;
+          Preconditions.checkState(!NodeUtil.isVarOrSimpleAssignLhs(n, parent));
+          parent.replaceChild(n, NodeUtil.newQName(compiler,
+                aliases.get(n.getQualifiedName())).copyInformationFromForTree(n));
+          compiler.reportCodeChange();
         }
+        break;
+    }
+    maybeRewriteJsdoc(n.getJSDocInfo());
+  }
 
-        name = aliases.get(name);
-      }
-      return name;
+  private void maybeRewriteJsdoc(JSDocInfo info) {
+    if (info == null) {
+      return;
+    }
+    for (Node typeNode : info.getTypeNodes()) {
+      NodeUtil.visitPreOrder(typeNode, fixJsdocTypeNodes, Predicates.<Node>alwaysTrue());
     }
+  }
 
-    private void maybeRewriteJsdoc(JSDocInfo info) {
-      if (info == null) {
+  private final NodeUtil.Visitor fixJsdocTypeNodes = new NodeUtil.Visitor() {
+    public void visit(Node aliasReference) {
+      if (!aliasReference.isString()) {
         return;
       }
-      for (Node typeNode : info.getTypeNodes()) {
-        NodeUtil.visitPreOrder(typeNode, fixJsdocTypeNodes, Predicates.<Node>alwaysTrue());
-      }
+      String fullTypeName = aliasReference.getString();
+      int dotIndex = 0;
+      do {
+        dotIndex = fullTypeName.indexOf('.', dotIndex + 1);
+        String aliasName = dotIndex == -1 ? fullTypeName : fullTypeName.substring(0, dotIndex);
+        if (aliases.containsKey(aliasName)) {
+          String replacement = aliases.get(aliasName) + fullTypeName.substring(aliasName.length());
+          aliasReference.setString(replacement);
+          return;
+        }
+      } while (dotIndex != -1);
     }
-
-    private final NodeUtil.Visitor fixJsdocTypeNodes =
-        new NodeUtil.Visitor() {
-          @Override
-          public void visit(Node aliasReference) {
-            if (!aliasReference.isString()) {
-              return;
-            }
-            String fullTypeName = aliasReference.getString();
-            int dotIndex = 0;
-            do {
-              dotIndex = fullTypeName.indexOf('.', dotIndex + 1);
-              String aliasName =
-                  dotIndex == -1 ? fullTypeName : fullTypeName.substring(0, dotIndex);
-              if (aliases.containsKey(aliasName)) {
-                String replacement =
-                    resolveAlias(aliasName, aliasReference)
-                        + fullTypeName.substring(aliasName.length());
-                aliasReference.setString(replacement);
-                return;
-              }
-            } while (dotIndex != -1);
-          }
-        };
-  }
+  };
 }
diff --git a/src/com/google/javascript/jscomp/JSDocInfoPrinter.java b/src/com/google/javascript/jscomp/JSDocInfoPrinter.java
index e99928728..91fd5b12e 100644
--- a/src/com/google/javascript/jscomp/JSDocInfoPrinter.java
+++ b/src/com/google/javascript/jscomp/JSDocInfoPrinter.java
@@ -96,7 +96,7 @@ public final class JSDocInfoPrinter {
 
     if (info.getParameterCount() > 0) {
       for (String name : info.getParameterNames()) {
-        sb.append("\n@param ");
+        sb.append("@param ");
         if (info.getParameterType(name) != null) {
           sb.append("{");
           appendTypeNode(sb, info.getParameterType(name).getRoot());
@@ -107,12 +107,12 @@ public final class JSDocInfoPrinter {
       }
     }
     if (info.hasReturnType()) {
-      sb.append("\n@return {");
+      sb.append("@return {");
       appendTypeNode(sb, info.getReturnType().getRoot());
       sb.append("} ");
     }
     if (info.hasThisType()) {
-      sb.append("\n@this {");
+      sb.append("@this {");
       Node typeNode = info.getThisType().getRoot();
       if (typeNode.getType() == Token.BANG) {
         appendTypeNode(sb, typeNode.getFirstChild());
@@ -122,7 +122,7 @@ public final class JSDocInfoPrinter {
       sb.append("} ");
     }
     if (info.hasBaseType()) {
-      sb.append("\n@extends {");
+      sb.append("@extends {");
       Node typeNode = info.getBaseType().getRoot();
       if (typeNode.getType() == Token.BANG) {
         appendTypeNode(sb, typeNode.getFirstChild());
@@ -132,7 +132,7 @@ public final class JSDocInfoPrinter {
       sb.append("} ");
     }
     for (JSTypeExpression type : info.getExtendedInterfaces()) {
-      sb.append("\n@extends {");
+      sb.append("@extends {");
       Node typeNode = type.getRoot();
       if (typeNode.getType() == Token.BANG) {
         appendTypeNode(sb, typeNode.getFirstChild());
@@ -142,7 +142,7 @@ public final class JSDocInfoPrinter {
       sb.append("} ");
     }
     for (JSTypeExpression type : info.getImplementedInterfaces()) {
-      sb.append("\n@implements {");
+      sb.append("@implements {");
       Node typeNode = type.getRoot();
       if (typeNode.getType() == Token.BANG) {
         appendTypeNode(sb, typeNode.getFirstChild());
diff --git a/src/com/google/javascript/jscomp/newtypes/JSTypeCreatorFromJSDoc.java b/src/com/google/javascript/jscomp/newtypes/JSTypeCreatorFromJSDoc.java
index 073fe8009..5f8715dfc 100644
--- a/src/com/google/javascript/jscomp/newtypes/JSTypeCreatorFromJSDoc.java
+++ b/src/com/google/javascript/jscomp/newtypes/JSTypeCreatorFromJSDoc.java
@@ -699,7 +699,7 @@ public final class JSTypeCreatorFromJSDoc {
       }
       DeclaredFunctionType declType = getFunTypeFromTypicalFunctionJsdoc(
           jsdoc, functionName, declNode,
-          constructorType, ownerType, registry, builder);
+          constructorType, ownerType, registry, builder, false);
       return new FunctionAndSlotType(null, declType);
     } catch (FunctionTypeBuilder.WrongParameterOrderException e) {
       warnings.add(JSError.make(declNode, WRONG_PARAMETER_ORDER));
@@ -756,7 +756,10 @@ public final class JSTypeCreatorFromJSDoc {
   private DeclaredFunctionType getFunTypeFromTypicalFunctionJsdoc(
       JSDocInfo jsdoc, String functionName, Node funNode,
       RawNominalType constructorType, RawNominalType ownerType,
-      DeclaredTypeRegistry registry, FunctionTypeBuilder builder) {
+      DeclaredTypeRegistry registry, FunctionTypeBuilder builder,
+      boolean ignoreJsdoc /* for when the jsdoc is malformed */) {
+    Preconditions.checkArgument(!ignoreJsdoc || jsdoc == null);
+    Preconditions.checkArgument(!ignoreJsdoc || funNode.isFunction());
     ImmutableList.Builder<String> typeParamsBuilder = new ImmutableList.Builder<>();;
     ImmutableList<String> typeParameters = ImmutableList.of();
     Node parent = funNode.getParent();
@@ -765,7 +768,6 @@ public final class JSTypeCreatorFromJSDoc {
     // - warn for multiple @template annotations
     // - warn for @template annotation w/out usage
 
-    boolean ignoreJsdoc = false;
     if (jsdoc != null) {
       typeParamsBuilder.addAll(jsdoc.getTemplateTypeNames());
       // We don't properly support the type transformation language; we treat
diff --git a/src/com/google/javascript/rhino/jstype/JSType.java b/src/com/google/javascript/rhino/jstype/JSType.java
index 28d804aa4..384b9952d 100644
--- a/src/com/google/javascript/rhino/jstype/JSType.java
+++ b/src/com/google/javascript/rhino/jstype/JSType.java
@@ -1347,16 +1347,11 @@ public abstract class JSType implements TypeI, Serializable {
           thatTypeParams, EquivalenceMethod.INVARIANT);
     }
     if (!templateMatch) {
-      return false;
-    }
-
-    // If the super type is an @record instance, then we can't safely remove a templatized type
-    // (since it might affect the types of the properties)
-    if (implicitImplCache.isStructuralTyping() && thatType.isStructuralInterfaceInstance()) {
-      return implicitMatch(thisType, thatType, implicitImplCache);
+      return implicitImplCache.isStructuralTyping()
+          && implicitMatch(thisType, thatType, implicitImplCache);
     }
 
-    // Templatized types. For nominal types, the above check guarantees TemplateTypeMap
+    // Templatized types. The above check guarantees TemplateTypeMap
     // equivalence; check if the base type is a subtype.
     if (thisType.isTemplatizedType()) {
       return thisType.toMaybeTemplatizedType().getReferencedType().isSubtype(
@@ -1368,15 +1363,8 @@ public abstract class JSType implements TypeI, Serializable {
       return thisType.isSubtype(
           ((ProxyObjectType) thatType).getReferencedTypeInternal(), implicitImplCache);
     }
-    return false;
-  }
-
-  private boolean isStructuralInterfaceInstance() {
-    if (!this.isObject()) {
-      return false;
-    }
-    FunctionType constructor = this.toMaybeObjectType().getConstructor();
-    return constructor != null && constructor.isStructuralInterface();
+    return implicitImplCache.isStructuralTyping()
+        && implicitMatch(thisType, thatType, implicitImplCache);
   }
 
   /**
@@ -1385,20 +1373,25 @@ public abstract class JSType implements TypeI, Serializable {
    */
   protected static boolean implicitMatch(JSType subType, JSType superType,
       ImplCache implicitImplCache) {
-    // Union types should be handled by isSubtype already
+    // Union type should be handled by isSubtype already
     Preconditions.checkState(!subType.isUnionType());
     Preconditions.checkState(!superType.isUnionType());
 
-    // Anything other than two object types can't match structurally
+    // Anything other than two object types doesn't match structurally
     if (!subType.isObject() || !superType.isObject()) {
       return false;
     }
-    // A supertype that isn't a structural interface can't match structurally
+
+    // currently the structural interface matching does not support
+    // implicit matching for templatized type
+    if (superType.isTemplatizedType()) {
+      return false;
+    }
+
     FunctionType superConstructor = superType.toMaybeObjectType().getConstructor();
     if (superConstructor == null || !superConstructor.isStructuralInterface()) {
       return false;
     }
-
     return checkObjectImplicitMatch(
         subType.toMaybeObjectType(), superType.toMaybeObjectType(), implicitImplCache);
   }
@@ -1413,6 +1406,11 @@ public abstract class JSType implements TypeI, Serializable {
       return result.subtypeValue();
     }
 
+    if (superType.getConstructor().hasAnyTemplateTypes()) {
+      implicitImplCache.updateCache(subType, superType, MatchStatus.NOT_MATCH);
+      return false;
+    }
+
     for (String propName : superType.getPropertyNames()) {
       if (subType.hasProperty(propName)
           && subType.getPropertyType(propName).isSubtype(
@@ -1423,6 +1421,8 @@ public abstract class JSType implements TypeI, Serializable {
       implicitImplCache.updateCache(subType, superType, MatchStatus.NOT_MATCH);
       return false;
     }
+
+
     implicitImplCache.updateCache(subType, superType, MatchStatus.MATCH);
     return true;
   }


Test patch:
diff --git a/test/com/google/javascript/jscomp/CodePrinterTest.java b/test/com/google/javascript/jscomp/CodePrinterTest.java
index 875210398..4bf7610d9 100644
--- a/test/com/google/javascript/jscomp/CodePrinterTest.java
+++ b/test/com/google/javascript/jscomp/CodePrinterTest.java
@@ -27,7 +27,6 @@ import java.util.List;
 
 
 public final class CodePrinterTest extends CodePrinterTestBase {
-  private static final Joiner LINE_JOINER = Joiner.on('\n');
 
   public void testPrint() {
     assertPrint("10 + a + b", "10+a+b");
@@ -1877,7 +1876,8 @@ public final class CodePrinterTest extends CodePrinterTestBase {
   public void testPreserveTypeAnnotations() {
     preserveTypeAnnotations = true;
     assertPrintSame("/**@type {foo} */var bar");
-    assertPrintSame("function/** void */f(/** string */s,/** number */n){}");
+    assertPrintSame(
+        "function/** void */f(/** string */s,/** number */n){}");
 
     preserveTypeAnnotations = false;
     assertPrint("/** @type {foo} */var bar;", "var bar");
@@ -1955,10 +1955,9 @@ public final class CodePrinterTest extends CodePrinterTestBase {
     assertPrintSame("class C extends D{member(){super.foo()}}");
   }
 
-  public void testGeneratorYield() {
+  public void testGeneratorYield1() {
     languageMode = LanguageMode.ECMASCRIPT6;
     assertPrintSame("function*f(){yield 1}");
-    assertPrintSame("function*f(){yield}");
     assertPrintSame("function*f(){yield 1?0:2}");
     assertPrintSame("function*f(){yield 1,0}");
     assertPrintSame("function*f(){1,yield 0}");
@@ -1967,25 +1966,6 @@ public final class CodePrinterTest extends CodePrinterTestBase {
     assertPrintSame("function*f(){(yield 1)+(yield 1)}");
   }
 
-  public void testGeneratorYieldPretty() {
-    languageMode = LanguageMode.ECMASCRIPT6;
-    assertPrettyPrint(
-        "function *f() {yield 1}",
-        LINE_JOINER.join(
-            "function* f() {",
-            "  yield 1;",
-            "}",
-            ""));
-
-    assertPrettyPrint(
-        "function *f() {yield}",
-        LINE_JOINER.join(
-            "function* f() {",
-            "  yield;",
-            "}",
-            ""));
-  }
-
   public void testMemberGeneratorYield1() {
     languageMode = LanguageMode.ECMASCRIPT6;
     assertPrintSame("class C{*member(){(yield 1)+(yield 1)}}");
@@ -2010,7 +1990,7 @@ public final class CodePrinterTest extends CodePrinterTestBase {
   public void testPrettyArrowFunction() {
     languageMode = LanguageMode.ECMASCRIPT6;
     assertPrettyPrint("if (x) {var f = ()=>{alert(1); alert(2)}}",
-        LINE_JOINER.join(
+        Joiner.on('\n').join(
             "if (x) {",
             "  var f = () => {",
             "    alert(1);",
diff --git a/test/com/google/javascript/jscomp/CompilerTypeTestCase.java b/test/com/google/javascript/jscomp/CompilerTypeTestCase.java
index cc0f8ffc7..2c22062c1 100644
--- a/test/com/google/javascript/jscomp/CompilerTypeTestCase.java
+++ b/test/com/google/javascript/jscomp/CompilerTypeTestCase.java
@@ -77,7 +77,7 @@ abstract class CompilerTypeTestCase extends BaseJSTypeTestCase {
           " */",
           "function IObject() {};",
           "/**",
-          " * @record",
+          " * @interface",
           " * @extends IObject<number, VALUE2>",
           " * @template VALUE2",
           " */",
diff --git a/test/com/google/javascript/jscomp/InlineAliasesTest.java b/test/com/google/javascript/jscomp/InlineAliasesTest.java
index 571b7a110..810e6872a 100644
--- a/test/com/google/javascript/jscomp/InlineAliasesTest.java
+++ b/test/com/google/javascript/jscomp/InlineAliasesTest.java
@@ -16,8 +16,6 @@
 
 package com.google.javascript.jscomp;
 
-import static com.google.javascript.jscomp.InlineAliases.ALIAS_CYCLE;
-
 import com.google.common.collect.ImmutableList;
 
 /** Unit tests for {@link InlineAliases}. */
@@ -253,40 +251,6 @@ public class InlineAliasesTest extends Es6CompilerTestCase {
             "var x = new ns.Foo.Subfoo;"));
   }
 
-  public void testHoistedAliasesInCode() {
-    // Unqualified
-    test(
-        LINE_JOINER.join(
-            "function Foo(){};",
-            "function Bar(){ var x = alias; };",
-            "var /** @const */ alias = Foo;"),
-        LINE_JOINER.join(
-            "function Foo(){};",
-            "function Bar(){ var x = Foo; };",
-            "var /** @const */ alias = Foo;"));
-
-    // Qualified
-    test(
-        LINE_JOINER.join(
-            "var ns = {};",
-            "ns.Foo = function(){};",
-            "function Bar(){ var x = ns.alias; };",
-            "/** @const */ ns.alias = ns.Foo;"),
-        LINE_JOINER.join(
-            "var ns = {};",
-            "ns.Foo = function(){};",
-            "function Bar(){ var x = ns.Foo; };",
-            "/** @const */ ns.alias = ns.Foo;"));
-  }
-
-  public void testAliasCycleError() {
-    testError(
-        LINE_JOINER.join(
-            "/** @const */ var x = y;",
-            "/** @const */ var y = x;"),
-        ALIAS_CYCLE);
-  }
-
   public void testTransitiveAliases() {
     test(
         LINE_JOINER.join(
@@ -305,43 +269,13 @@ public class InlineAliasesTest extends Es6CompilerTestCase {
             "var x = new ns.Foo.Bar;"));
   }
 
-  public void testAliasChains() {
-    // Unqualified
-    test(
-        LINE_JOINER.join(
-            "/** @constructor */ var Foo = function() {};",
-            "var /** @const */ alias1 = Foo;",
-            "var /** @const */ alias2 = alias1;",
-            "var x = new alias2"),
-        LINE_JOINER.join(
-            "/** @constructor */ var Foo = function() {};",
-            "var /** @const */ alias1 = Foo;",
-            "var /** @const */ alias2 = Foo;",
-            "var x = new Foo;"));
-
-    // Qualified
-    test(
-        LINE_JOINER.join(
-            "/** @const */ var ns = {};",
-            "/** @constructor */ ns.Foo = function() {};",
-            "var /** @const */ alias1 = ns.Foo;",
-            "var /** @const */ alias2 = alias1;",
-            "var x = new alias2"),
-        LINE_JOINER.join(
-            "/** @const */ var ns = {};",
-            "/** @constructor */ ns.Foo = function() {};",
-            "var /** @const */ alias1 = ns.Foo;",
-            "var /** @const */ alias2 = ns.Foo;",
-            "var x = new ns.Foo;"));
-}
-
   public void testAliasedEnums() {
     test(
         "/** @enum {number} */ var E = { A : 1 }; var /** @const */ alias = E.A; alias;",
         "/** @enum {number} */ var E = { A : 1 }; var /** @const */ alias = E.A; E.A;");
   }
 
-  public void testIncorrectConstAnnotationDoesntCrash() {
+  public void testIncorrectConstAnnoataionDoesntCrash() {
     testSame("var x = 0; var /** @const */ alias = x; alias = 5; use(alias);");
     testSame("var x = 0; var ns={}; /** @const */ ns.alias = x; ns.alias = 5; use(ns.alias);");
   }
diff --git a/test/com/google/javascript/jscomp/JSDocInfoPrinterTest.java b/test/com/google/javascript/jscomp/JSDocInfoPrinterTest.java
index 4406af0bf..524c32b5e 100644
--- a/test/com/google/javascript/jscomp/JSDocInfoPrinterTest.java
+++ b/test/com/google/javascript/jscomp/JSDocInfoPrinterTest.java
@@ -82,22 +82,22 @@ public final class JSDocInfoPrinterTest extends TestCase {
     builder.recordParameter("bar",
         new JSTypeExpression(JsDocInfoParser.parseTypeString("string"), ""));
     JSDocInfo info = builder.buildAndReset();
-    assertEquals("/**\n@param {number} foo \n@param {string} bar */",
+    assertEquals("/**@param {number} foo @param {string} bar */",
         JSDocInfoPrinter.print(info));
 
     builder.recordParameter("foo",
         new JSTypeExpression(new Node(Token.EQUALS, IR.string("number")), ""));
     info = builder.buildAndReset();
-    assertEquals("/**\n@param {number=} foo */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@param {number=} foo */", JSDocInfoPrinter.print(info));
 
     builder.recordParameter("foo",
         new JSTypeExpression(new Node(Token.ELLIPSIS, IR.string("number")), ""));
     info = builder.buildAndReset();
-    assertEquals("/**\n@param {...number} foo */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@param {...number} foo */", JSDocInfoPrinter.print(info));
 
     builder.recordParameter("foo", null);
     info = builder.buildAndReset();
-    assertEquals("/**\n@param foo */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@param foo */", JSDocInfoPrinter.print(info));
   }
 
   public void testRecordTypes() {
@@ -131,12 +131,12 @@ public final class JSDocInfoPrinterTest extends TestCase {
     builder.recordReturnType(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("number|string"), ""));
     JSDocInfo info = builder.buildAndReset();
-    assertEquals("/**\n@return {(number|string)} */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@return {(number|string)} */", JSDocInfoPrinter.print(info));
 
     builder.recordParameter("foo",
         new JSTypeExpression(new Node(Token.ELLIPSIS, IR.string("number")), ""));
     info = builder.buildAndReset();
-    assertEquals("/**\n@param {...number} foo */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@param {...number} foo */", JSDocInfoPrinter.print(info));
     builder.recordThrowType(new JSTypeExpression(new Node(Token.STAR), ""));
     info = builder.buildAndReset();
     assertEquals("/**@throws {*} */", JSDocInfoPrinter.print(info));
@@ -204,17 +204,17 @@ public final class JSDocInfoPrinterTest extends TestCase {
     builder.recordImplementedInterface(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("Foo"), ""));
     JSDocInfo info = builder.buildAndReset();
-    assertEquals("/**\n@implements {Foo} */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@implements {Foo} */", JSDocInfoPrinter.print(info));
 
     builder.recordImplementedInterface(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("!Foo"), ""));
     info = builder.buildAndReset();
-    assertEquals("/**\n@implements {Foo} */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@implements {Foo} */", JSDocInfoPrinter.print(info));
 
     builder.recordBaseType(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("Foo"), ""));
     info = builder.buildAndReset();
-    assertEquals("/**\n@extends {Foo} */", JSDocInfoPrinter.print(info));
+    assertEquals("/**@extends {Foo} */", JSDocInfoPrinter.print(info));
 
     builder.recordBaseType(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("!Foo"), ""));
@@ -223,8 +223,7 @@ public final class JSDocInfoPrinterTest extends TestCase {
     builder.recordImplementedInterface(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("Bar.Baz"), ""));
     info = builder.buildAndReset();
-    assertEquals(
-        "/**\n@extends {Foo} \n@implements {Bar} \n@implements {Bar.Baz} */",
+    assertEquals("/**@extends {Foo} @implements {Bar} @implements {Bar.Baz} */",
         JSDocInfoPrinter.print(info));
   }
 
@@ -235,7 +234,7 @@ public final class JSDocInfoPrinterTest extends TestCase {
      builder.recordExtendedInterface(
         new JSTypeExpression(JsDocInfoParser.parseTypeString("Bar"), ""));
     JSDocInfo info = builder.buildAndReset();
-    assertEquals("/**@interface \n@extends {Foo} \n@extends {Bar} */",
+    assertEquals("/**@interface @extends {Foo} @extends {Bar} */",
         JSDocInfoPrinter.print(info));
   }
 
diff --git a/test/com/google/javascript/jscomp/NewTypeInferenceES5OrLowerTest.java b/test/com/google/javascript/jscomp/NewTypeInferenceES5OrLowerTest.java
index 44d4abe86..1bd40b61f 100644
--- a/test/com/google/javascript/jscomp/NewTypeInferenceES5OrLowerTest.java
+++ b/test/com/google/javascript/jscomp/NewTypeInferenceES5OrLowerTest.java
@@ -7798,26 +7798,6 @@ public final class NewTypeInferenceES5OrLowerTest extends NewTypeInferenceTestBa
         NewTypeInference.WRONG_ARGUMENT_COUNT);
   }
 
-  public void testInferConstTypeFromNestedObjectLiterals() {
-    typeCheck(Joiner.on('\n').join(
-        "/** @constructor */",
-        "function Foo() {};",
-        "/** @param {!{service: !{eventLogging: !Foo }}} x */",
-        "function f(x) {",
-        "  /** @const */",
-        "  var z = x.service.eventLogging;",
-        "}"));
-
-    typeCheck(Joiner.on('\n').join(
-        "/** @param {{p1: {p2: string }}} x */",
-        "function f(x) {",
-        "  /** @const */",
-        "  var z = x.p1.p2;",
-        "  return z - 5;",
-        "}"),
-        NewTypeInference.INVALID_OPERAND_TYPE);
-  }
-
   public void testDifficultClassGenericsInstantiation() {
     typeCheck(Joiner.on('\n').join(
         "/**",
diff --git a/test/com/google/javascript/jscomp/TypeCheckTest.java b/test/com/google/javascript/jscomp/TypeCheckTest.java
index ae8439690..78826321b 100644
--- a/test/com/google/javascript/jscomp/TypeCheckTest.java
+++ b/test/com/google/javascript/jscomp/TypeCheckTest.java
@@ -13492,7 +13492,6 @@ public final class TypeCheckTest extends CompilerTypeTestCase {
         });
   }
 
-
   public void testTemplateMap1() throws Exception {
     testTypesWithExtraExterns(EXTERNS_WITH_IARRAYLIKE_DECLS,
         "function f() {\n"
@@ -13788,155 +13787,6 @@ public final class TypeCheckTest extends CompilerTypeTestCase {
             "}"));
   }
 
-  public void testIArrayLikeStructuralMatch1() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "function f(/** !IArrayLike */ x){};",
-            "/** @constructor */",
-            "function Foo() {}",
-            "/** @type {number} */ Foo.prototype.length",
-            "f(new Foo)"));
-  }
-
-  public void testIArrayLikeStructuralMatch2() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "function f(/** !IArrayLike */ x){};",
-            "/** @constructor */",
-            "function Foo() {",
-            "  /** @type {number} */ this.length = 5;",
-            "}",
-            "f(new Foo)"));
-  }
-
-  public void testIArrayLikeStructuralMatch3() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "function f(/** !IArrayLike */ x){};",
-            "f({length: 5})"));
-  }
-
-  public void testIArrayLikeStructuralMatch4() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "function f(/** !IArrayLike */ x){};",
-            "/** @const */ var ns = {};",
-            "/** @type {number} */ ns.length",
-            "f(ns)"));
-  }
-
-  public void testIArrayLikeStructuralMatch5() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "function f(/** !IArrayLike */ x){};",
-            "var ns = function() {};",
-            "/** @type {number} */ ns.length",
-            "f(ns)"));
-  }
-
-  public void testIArrayLikeStructuralMatch6() throws Exception {
-    // Even though Foo's [] element type may not be string, we treat the lack
-    // of explicit type like ? and allow this.
-    testTypes(
-        LINE_JOINER.join(
-            "function f(/** !IArrayLike<string> */ x){};",
-            "/** @constructor */",
-            "function Foo() {}",
-            "/** @type {number} */ Foo.prototype.length",
-            "f(new Foo)"));
-  }
-
-  public void testTemplatizedStructuralMatch1() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "/** @record @template T */",
-            "function WithPropT() {}",
-            "/** @type {T} */ WithPropT.prototype.prop",
-            "function f(/** !WithPropT<number> */ x){};",
-            "/** @constructor */ function Foo() {}",
-            "/** @type {number} */ Foo.prototype.prop",
-            "f(new Foo)"));
-  }
-
-  public void testTemplatizedStructuralMatch2() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "/** @record @template T */",
-            "function WithPropT() {}",
-            "/** @type {T} */ WithPropT.prototype.prop",
-            "function f(/** !WithPropT<number> */ x){};",
-            "/** @constructor @template U */ function Foo() {}",
-            "/** @type {number} */ Foo.prototype.prop",
-            "f(new Foo)"));
-  }
-
-  public void testTemplatizedStructuralMatch3() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "/** @record @template T */",
-            "function WithPropT() {}",
-            "/** @type {T} */ WithPropT.prototype.prop",
-            "function f(/** !WithPropT<string> */ x){};",
-            "/** @constructor @template U */ function Foo() {}",
-            "/** @type {U} */ Foo.prototype.prop",
-            "f(new Foo)"));
-  }
-
-  public void testTemplatizedStructuralMismatch1() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "/** @record @template T */",
-            "function WithPropT() {}",
-            "/** @type {T} */ WithPropT.prototype.prop",
-            "function f(/** !WithPropT<number> */ x){};",
-            "/** @constructor */ function Foo() {}",
-            "/** @type {string} */ Foo.prototype.prop = 'str'",
-            "f(new Foo)"),
-        LINE_JOINER.join(
-            "actual parameter 1 of f does not match formal parameter",
-            "found   : Foo",
-            "required: WithPropT<number>"));
-  }
-
-  public void testTemplatizedStructuralMismatch2() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "/** @record @template T */",
-            "function WithPropT() {}",
-            "/** @type {T} */ WithPropT.prototype.prop",
-            "function f(/** !WithPropT<number> */ x){};",
-            "/** @constructor @template U */ function Foo() {}",
-            "/** @type {string} */ Foo.prototype.prop = 'str'",
-            "f(new Foo)"),
-        LINE_JOINER.join(
-            "actual parameter 1 of f does not match formal parameter",
-            "found   : Foo",
-            "required: WithPropT<number>"));
-  }
-
-  public void testTemplatizedStructuralMismatch3() throws Exception {
-    testTypes(
-        LINE_JOINER.join(
-            "/** @record @template T */",
-            "function WithPropT() {}",
-            "/** @type {T} */ WithPropT.prototype.prop",
-            "function f(/** !WithPropT<number> */ x){};",
-            "/**",
-            " * @constructor",
-            " * @template U",
-            " * @param {U} x",
-            " */",
-            "function Foo(x) {",
-            "  /** @type {U} */ this.prop = x",
-            "}",
-            "f(new Foo('str'))"),
-        LINE_JOINER.join(
-            "actual parameter 1 of f does not match formal parameter",
-            "found   : Foo<string>",
-            "required: WithPropT<number>"));
-  }
-
-
   private static final String EXTERNS_WITH_IOBJECT_DECLS = LINE_JOINER.join(
       "/**",
       " * @constructor",
@@ -15271,16 +15121,21 @@ public final class TypeCheckTest extends CompilerTypeTestCase {
    * Using @template @interfaces requires @implements them explicitly.
    */
   public void testStructuralInterfaceMatching45() throws Exception {
-    testTypes(
+    testTypesWithExtraExterns(
         LINE_JOINER.join(
-            "/**",
-            " * @record",
-            " * @template X",
-            " */",
-            "function I() {}",
+            "/** @record",
+            " *  @template X",
+            " */ function I() {}",
             "/** @constructor */",
-            "function C() {}",
-            "var i /** !I */ = new C;"));
+            "function C() {}"),
+        LINE_JOINER.join(
+            "/** @type {I} */ var i;",
+            "/** @type {C} */ var c = new C();",
+            "i = c"),
+        LINE_JOINER.join(
+            "assignment",
+            "found   : (C|null)",
+            "required: (I|null)"));
   }
 
   public void testStructuralInterfaceMatching46() throws Exception {