[google_maps_flutter] Migrate plugin to platform_interface API. (#2674)

This change migrates the core `google_maps_flutter` plugin to use the APIs provided by the `google_maps_flutter_platform_interface` package.

This allows for federated implementations for other platforms to be made.

diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
index 9754552..7f47917 100644
--- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.5.27
+
+* Migrate the core plugin to use `google_maps_flutter_platform_interface` APIs.
+
 ## 0.5.26+4
 
 * Android: Fix map view crash when "exit app" while using `FragmentActivity`.
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart
index 5f3889f..a17b30c 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart
@@ -13,22 +13,36 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 
-part 'src/bitmap.dart';
-part 'src/callbacks.dart';
-part 'src/camera.dart';
-part 'src/cap.dart';
-part 'src/circle.dart';
-part 'src/circle_updates.dart';
+import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
+import 'package:google_maps_flutter_platform_interface/src/method_channel/method_channel_google_maps_flutter.dart';
+
+export 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'
+    show
+        ArgumentCallbacks,
+        ArgumentCallback,
+        BitmapDescriptor,
+        CameraPosition,
+        CameraPositionCallback,
+        CameraTargetBounds,
+        CameraUpdate,
+        Cap,
+        Circle,
+        CircleId,
+        InfoWindow,
+        JointType,
+        LatLng,
+        LatLngBounds,
+        MapStyleException,
+        MapType,
+        Marker,
+        MarkerId,
+        MinMaxZoomPreference,
+        PatternItem,
+        Polygon,
+        PolygonId,
+        Polyline,
+        PolylineId,
+        ScreenCoordinate;
+
 part 'src/controller.dart';
 part 'src/google_map.dart';
-part 'src/joint_type.dart';
-part 'src/location.dart';
-part 'src/marker.dart';
-part 'src/marker_updates.dart';
-part 'src/pattern_item.dart';
-part 'src/polygon.dart';
-part 'src/polygon_updates.dart';
-part 'src/polyline.dart';
-part 'src/polyline_updates.dart';
-part 'src/screen_coordinate.dart';
-part 'src/ui.dart';
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/bitmap.dart
deleted file mode 100644
index 7cf5b2e..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/bitmap.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Defines a bitmap image. For a marker, this class can be used to set the
-/// image of the marker icon. For a ground overlay, it can be used to set the
-/// image to place on the surface of the earth.
-class BitmapDescriptor {
-  const BitmapDescriptor._(this._json);
-
-  /// Convenience hue value representing red.
-  static const double hueRed = 0.0;
-
-  /// Convenience hue value representing orange.
-  static const double hueOrange = 30.0;
-
-  /// Convenience hue value representing yellow.
-  static const double hueYellow = 60.0;
-
-  /// Convenience hue value representing green.
-  static const double hueGreen = 120.0;
-
-  /// Convenience hue value representing cyan.
-  static const double hueCyan = 180.0;
-
-  /// Convenience hue value representing azure.
-  static const double hueAzure = 210.0;
-
-  /// Convenience hue value representing blue.
-  static const double hueBlue = 240.0;
-
-  /// Convenience hue value representing violet.
-  static const double hueViolet = 270.0;
-
-  /// Convenience hue value representing magenta.
-  static const double hueMagenta = 300.0;
-
-  /// Convenience hue value representing rose.
-  static const double hueRose = 330.0;
-
-  /// Creates a BitmapDescriptor that refers to the default marker image.
-  static const BitmapDescriptor defaultMarker =
-      BitmapDescriptor._(<dynamic>['defaultMarker']);
-
-  /// Creates a BitmapDescriptor that refers to a colorization of the default
-  /// marker image. For convenience, there is a predefined set of hue values.
-  /// See e.g. [hueYellow].
-  static BitmapDescriptor defaultMarkerWithHue(double hue) {
-    assert(0.0 <= hue && hue < 360.0);
-    return BitmapDescriptor._(<dynamic>['defaultMarker', hue]);
-  }
-
-  /// Creates a BitmapDescriptor using the name of a bitmap image in the assets
-  /// directory.
-  ///
-  /// Use [fromAssetImage]. This method does not respect the screen dpi when
-  /// picking an asset image.
-  @Deprecated("Use fromAssetImage instead")
-  static BitmapDescriptor fromAsset(String assetName, {String package}) {
-    if (package == null) {
-      return BitmapDescriptor._(<dynamic>['fromAsset', assetName]);
-    } else {
-      return BitmapDescriptor._(<dynamic>['fromAsset', assetName, package]);
-    }
-  }
-
-  /// Creates a [BitmapDescriptor] from an asset image.
-  ///
-  /// Asset images in flutter are stored per:
-  /// https://flutter.dev/docs/development/ui/assets-and-images#declaring-resolution-aware-image-assets
-  /// This method takes into consideration various asset resolutions
-  /// and scales the images to the right resolution depending on the dpi.
-  /// Set `mipmaps` to false to load the exact dpi version of the image, `mipmap` is true by default.
-  static Future<BitmapDescriptor> fromAssetImage(
-    ImageConfiguration configuration,
-    String assetName, {
-    AssetBundle bundle,
-    String package,
-    bool mipmaps = true,
-  }) async {
-    if (!mipmaps && configuration.devicePixelRatio != null) {
-      return BitmapDescriptor._(<dynamic>[
-        'fromAssetImage',
-        assetName,
-        configuration.devicePixelRatio,
-      ]);
-    }
-    final AssetImage assetImage =
-        AssetImage(assetName, package: package, bundle: bundle);
-    final AssetBundleImageKey assetBundleImageKey =
-        await assetImage.obtainKey(configuration);
-    return BitmapDescriptor._(<dynamic>[
-      'fromAssetImage',
-      assetBundleImageKey.name,
-      assetBundleImageKey.scale,
-    ]);
-  }
-
-  /// Creates a BitmapDescriptor using an array of bytes that must be encoded
-  /// as PNG.
-  static BitmapDescriptor fromBytes(Uint8List byteData) {
-    return BitmapDescriptor._(<dynamic>['fromBytes', byteData]);
-  }
-
-  final dynamic _json;
-
-  /// Convert the object to a Json format.
-  /// Used for testing only.
-  @visibleForTesting
-  dynamic toJson() => _json;
-
-  dynamic _toJson() => _json;
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/callbacks.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/callbacks.dart
deleted file mode 100644
index 284c713..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/callbacks.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Callback function taking a single argument.
-typedef void ArgumentCallback<T>(T argument);
-
-/// Mutable collection of [ArgumentCallback] instances, itself an [ArgumentCallback].
-///
-/// Additions and removals happening during a single [call] invocation do not
-/// change who gets a callback until the next such invocation.
-///
-/// Optimized for the singleton case.
-class ArgumentCallbacks<T> {
-  final List<ArgumentCallback<T>> _callbacks = <ArgumentCallback<T>>[];
-
-  /// Callback method. Invokes the corresponding method on each callback
-  /// in this collection.
-  ///
-  /// The list of callbacks being invoked is computed at the start of the
-  /// method and is unaffected by any changes subsequently made to this
-  /// collection.
-  void call(T argument) {
-    final int length = _callbacks.length;
-    if (length == 1) {
-      _callbacks[0].call(argument);
-    } else if (0 < length) {
-      for (ArgumentCallback<T> callback
-          in List<ArgumentCallback<T>>.from(_callbacks)) {
-        callback(argument);
-      }
-    }
-  }
-
-  /// Adds a callback to this collection.
-  void add(ArgumentCallback<T> callback) {
-    assert(callback != null);
-    _callbacks.add(callback);
-  }
-
-  /// Removes a callback from this collection.
-  ///
-  /// Does nothing, if the callback was not present.
-  void remove(ArgumentCallback<T> callback) {
-    _callbacks.remove(callback);
-  }
-
-  /// Whether this collection is empty.
-  bool get isEmpty => _callbacks.isEmpty;
-
-  /// Whether this collection is non-empty.
-  bool get isNotEmpty => _callbacks.isNotEmpty;
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/camera.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/camera.dart
deleted file mode 100644
index 043d0f8..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/camera.dart
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// The position of the map "camera", the view point from which the world is shown in the map view.
-///
-/// Aggregates the camera's [target] geographical location, its [zoom] level,
-/// [tilt] angle, and [bearing].
-class CameraPosition {
-  /// Creates a immutable representation of the [GoogleMap] camera.
-  ///
-  /// [AssertionError] is thrown if [bearing], [target], [tilt], or [zoom] are
-  /// null.
-  const CameraPosition({
-    this.bearing = 0.0,
-    @required this.target,
-    this.tilt = 0.0,
-    this.zoom = 0.0,
-  })  : assert(bearing != null),
-        assert(target != null),
-        assert(tilt != null),
-        assert(zoom != null);
-
-  /// The camera's bearing in degrees, measured clockwise from north.
-  ///
-  /// A bearing of 0.0, the default, means the camera points north.
-  /// A bearing of 90.0 means the camera points east.
-  final double bearing;
-
-  /// The geographical location that the camera is pointing at.
-  final LatLng target;
-
-  /// The angle, in degrees, of the camera angle from the nadir.
-  ///
-  /// A tilt of 0.0, the default and minimum supported value, means the camera
-  /// is directly facing the Earth.
-  ///
-  /// The maximum tilt value depends on the current zoom level. Values beyond
-  /// the supported range are allowed, but on applying them to a map they will
-  /// be silently clamped to the supported range.
-  final double tilt;
-
-  /// The zoom level of the camera.
-  ///
-  /// A zoom of 0.0, the default, means the screen width of the world is 256.
-  /// Adding 1.0 to the zoom level doubles the screen width of the map. So at
-  /// zoom level 3.0, the screen width of the world is 2³x256=2048.
-  ///
-  /// Larger zoom levels thus means the camera is placed closer to the surface
-  /// of the Earth, revealing more detail in a narrower geographical region.
-  ///
-  /// The supported zoom level range depends on the map data and device. Values
-  /// beyond the supported range are allowed, but on applying them to a map they
-  /// will be silently clamped to the supported range.
-  final double zoom;
-
-  /// Serializes [CameraPosition].
-  ///
-  /// Mainly for internal use when calling [CameraUpdate.newCameraPosition].
-  dynamic toMap() => <String, dynamic>{
-        'bearing': bearing,
-        'target': target._toJson(),
-        'tilt': tilt,
-        'zoom': zoom,
-      };
-
-  /// Deserializes [CameraPosition] from a map.
-  ///
-  /// Mainly for internal use.
-  static CameraPosition fromMap(dynamic json) {
-    if (json == null) {
-      return null;
-    }
-    return CameraPosition(
-      bearing: json['bearing'],
-      target: LatLng._fromJson(json['target']),
-      tilt: json['tilt'],
-      zoom: json['zoom'],
-    );
-  }
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(this, other)) return true;
-    if (runtimeType != other.runtimeType) return false;
-    final CameraPosition typedOther = other;
-    return bearing == typedOther.bearing &&
-        target == typedOther.target &&
-        tilt == typedOther.tilt &&
-        zoom == typedOther.zoom;
-  }
-
-  @override
-  int get hashCode => hashValues(bearing, target, tilt, zoom);
-
-  @override
-  String toString() =>
-      'CameraPosition(bearing: $bearing, target: $target, tilt: $tilt, zoom: $zoom)';
-}
-
-/// Defines a camera move, supporting absolute moves as well as moves relative
-/// the current position.
-class CameraUpdate {
-  CameraUpdate._(this._json);
-
-  /// Returns a camera update that moves the camera to the specified position.
-  static CameraUpdate newCameraPosition(CameraPosition cameraPosition) {
-    return CameraUpdate._(
-      <dynamic>['newCameraPosition', cameraPosition.toMap()],
-    );
-  }
-
-  /// Returns a camera update that moves the camera target to the specified
-  /// geographical location.
-  static CameraUpdate newLatLng(LatLng latLng) {
-    return CameraUpdate._(<dynamic>['newLatLng', latLng._toJson()]);
-  }
-
-  /// Returns a camera update that transforms the camera so that the specified
-  /// geographical bounding box is centered in the map view at the greatest
-  /// possible zoom level. A non-zero [padding] insets the bounding box from the
-  /// map view's edges. The camera's new tilt and bearing will both be 0.0.
-  static CameraUpdate newLatLngBounds(LatLngBounds bounds, double padding) {
-    return CameraUpdate._(<dynamic>[
-      'newLatLngBounds',
-      bounds._toList(),
-      padding,
-    ]);
-  }
-
-  /// Returns a camera update that moves the camera target to the specified
-  /// geographical location and zoom level.
-  static CameraUpdate newLatLngZoom(LatLng latLng, double zoom) {
-    return CameraUpdate._(
-      <dynamic>['newLatLngZoom', latLng._toJson(), zoom],
-    );
-  }
-
-  /// Returns a camera update that moves the camera target the specified screen
-  /// distance.
-  ///
-  /// For a camera with bearing 0.0 (pointing north), scrolling by 50,75 moves
-  /// the camera's target to a geographical location that is 50 to the east and
-  /// 75 to the south of the current location, measured in screen coordinates.
-  static CameraUpdate scrollBy(double dx, double dy) {
-    return CameraUpdate._(
-      <dynamic>['scrollBy', dx, dy],
-    );
-  }
-
-  /// Returns a camera update that modifies the camera zoom level by the
-  /// specified amount. The optional [focus] is a screen point whose underlying
-  /// geographical location should be invariant, if possible, by the movement.
-  static CameraUpdate zoomBy(double amount, [Offset focus]) {
-    if (focus == null) {
-      return CameraUpdate._(<dynamic>['zoomBy', amount]);
-    } else {
-      return CameraUpdate._(<dynamic>[
-        'zoomBy',
-        amount,
-        <double>[focus.dx, focus.dy],
-      ]);
-    }
-  }
-
-  /// Returns a camera update that zooms the camera in, bringing the camera
-  /// closer to the surface of the Earth.
-  ///
-  /// Equivalent to the result of calling `zoomBy(1.0)`.
-  static CameraUpdate zoomIn() {
-    return CameraUpdate._(<dynamic>['zoomIn']);
-  }
-
-  /// Returns a camera update that zooms the camera out, bringing the camera
-  /// further away from the surface of the Earth.
-  ///
-  /// Equivalent to the result of calling `zoomBy(-1.0)`.
-  static CameraUpdate zoomOut() {
-    return CameraUpdate._(<dynamic>['zoomOut']);
-  }
-
-  /// Returns a camera update that sets the camera zoom level.
-  static CameraUpdate zoomTo(double zoom) {
-    return CameraUpdate._(<dynamic>['zoomTo', zoom]);
-  }
-
-  final dynamic _json;
-
-  dynamic _toJson() => _json;
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/cap.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/cap.dart
deleted file mode 100644
index 1a6be1f..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/cap.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Cap that can be applied at the start or end vertex of a [Polyline].
-@immutable
-class Cap {
-  const Cap._(this._json);
-
-  /// Cap that is squared off exactly at the start or end vertex of a [Polyline]
-  /// with solid stroke pattern, equivalent to having no additional cap beyond
-  /// the start or end vertex.
-  ///
-  /// This is the default cap type at start and end vertices of Polylines with
-  /// solid stroke pattern.
-  static const Cap buttCap = Cap._(<dynamic>['buttCap']);
-
-  /// Cap that is a semicircle with radius equal to half the stroke width,
-  /// centered at the start or end vertex of a [Polyline] with solid stroke
-  /// pattern.
-  static const Cap roundCap = Cap._(<dynamic>['roundCap']);
-
-  /// Cap that is squared off after extending half the stroke width beyond the
-  /// start or end vertex of a [Polyline] with solid stroke pattern.
-  static const Cap squareCap = Cap._(<dynamic>['squareCap']);
-
-  /// Constructs a new CustomCap with a bitmap overlay centered at the start or
-  /// end vertex of a [Polyline], orientated according to the direction of the line's
-  /// first or last edge and scaled with respect to the line's stroke width.
-  ///
-  /// CustomCap can be applied to [Polyline] with any stroke pattern.
-  ///
-  /// [bitmapDescriptor] must not be null.
-  ///
-  /// [refWidth] is the reference stroke width (in pixels) - the stroke width for which
-  /// the cap bitmap at its native dimension is designed. Must be positive. Default value
-  /// is 10 pixels.
-  static Cap customCapFromBitmap(
-    BitmapDescriptor bitmapDescriptor, {
-    double refWidth = 10,
-  }) {
-    assert(bitmapDescriptor != null);
-    assert(refWidth > 0.0);
-    return Cap._(<dynamic>['customCap', bitmapDescriptor._toJson(), refWidth]);
-  }
-
-  final dynamic _json;
-
-  dynamic _toJson() => _json;
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/circle.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/circle.dart
deleted file mode 100644
index 3edfc88..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/circle.dart
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Uniquely identifies a [Circle] among [GoogleMap] circles.
-///
-/// This does not have to be globally unique, only unique among the list.
-@immutable
-class CircleId {
-  /// Creates an immutable identifier for a [Circle].
-  CircleId(this.value) : assert(value != null);
-
-  /// value of the [CircleId].
-  final String value;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final CircleId typedOther = other;
-    return value == typedOther.value;
-  }
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  String toString() {
-    return 'CircleId{value: $value}';
-  }
-}
-
-/// Draws a circle on the map.
-@immutable
-class Circle {
-  /// Creates an immutable representation of a [Circle] to draw on [GoogleMap].
-  const Circle({
-    @required this.circleId,
-    this.consumeTapEvents = false,
-    this.fillColor = Colors.transparent,
-    this.center = const LatLng(0.0, 0.0),
-    this.radius = 0,
-    this.strokeColor = Colors.black,
-    this.strokeWidth = 10,
-    this.visible = true,
-    this.zIndex = 0,
-    this.onTap,
-  });
-
-  /// Uniquely identifies a [Circle].
-  final CircleId circleId;
-
-  /// True if the [Circle] consumes tap events.
-  ///
-  /// If this is false, [onTap] callback will not be triggered.
-  final bool consumeTapEvents;
-
-  /// Fill color in ARGB format, the same format used by Color. The default value is transparent (0x00000000).
-  final Color fillColor;
-
-  /// Geographical location of the circle center.
-  final LatLng center;
-
-  /// Radius of the circle in meters; must be positive. The default value is 0.
-  final double radius;
-
-  /// Fill color in ARGB format, the same format used by Color. The default value is black (0xff000000).
-  final Color strokeColor;
-
-  /// The width of the circle's outline in screen points.
-  ///
-  /// The width is constant and independent of the camera's zoom level.
-  /// The default value is 10.
-  /// Setting strokeWidth to 0 results in no stroke.
-  final int strokeWidth;
-
-  /// True if the circle is visible.
-  final bool visible;
-
-  /// The z-index of the circle, used to determine relative drawing order of
-  /// map overlays.
-  ///
-  /// Overlays are drawn in order of z-index, so that lower values means drawn
-  /// earlier, and thus appearing to be closer to the surface of the Earth.
-  final int zIndex;
-
-  /// Callbacks to receive tap events for circle placed on this map.
-  final VoidCallback onTap;
-
-  /// Creates a new [Circle] object whose values are the same as this instance,
-  /// unless overwritten by the specified parameters.
-  Circle copyWith({
-    bool consumeTapEventsParam,
-    Color fillColorParam,
-    LatLng centerParam,
-    double radiusParam,
-    Color strokeColorParam,
-    int strokeWidthParam,
-    bool visibleParam,
-    int zIndexParam,
-    VoidCallback onTapParam,
-  }) {
-    return Circle(
-      circleId: circleId,
-      consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents,
-      fillColor: fillColorParam ?? fillColor,
-      center: centerParam ?? center,
-      radius: radiusParam ?? radius,
-      strokeColor: strokeColorParam ?? strokeColor,
-      strokeWidth: strokeWidthParam ?? strokeWidth,
-      visible: visibleParam ?? visible,
-      zIndex: zIndexParam ?? zIndex,
-      onTap: onTapParam ?? onTap,
-    );
-  }
-
-  /// Creates a new [Circle] object whose values are the same as this instance.
-  Circle clone() => copyWith();
-
-  dynamic _toJson() {
-    final Map<String, dynamic> json = <String, dynamic>{};
-
-    void addIfPresent(String fieldName, dynamic value) {
-      if (value != null) {
-        json[fieldName] = value;
-      }
-    }
-
-    addIfPresent('circleId', circleId.value);
-    addIfPresent('consumeTapEvents', consumeTapEvents);
-    addIfPresent('fillColor', fillColor.value);
-    addIfPresent('center', center._toJson());
-    addIfPresent('radius', radius);
-    addIfPresent('strokeColor', strokeColor.value);
-    addIfPresent('strokeWidth', strokeWidth);
-    addIfPresent('visible', visible);
-    addIfPresent('zIndex', zIndex);
-
-    return json;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Circle typedOther = other;
-    return circleId == typedOther.circleId &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        fillColor == typedOther.fillColor &&
-        center == typedOther.center &&
-        radius == typedOther.radius &&
-        strokeColor == typedOther.strokeColor &&
-        strokeWidth == typedOther.strokeWidth &&
-        visible == typedOther.visible &&
-        zIndex == typedOther.zIndex;
-  }
-
-  @override
-  int get hashCode => circleId.hashCode;
-}
-
-Map<CircleId, Circle> _keyByCircleId(Iterable<Circle> circles) {
-  if (circles == null) {
-    return <CircleId, Circle>{};
-  }
-  return Map<CircleId, Circle>.fromEntries(circles.map((Circle circle) =>
-      MapEntry<CircleId, Circle>(circle.circleId, circle.clone())));
-}
-
-List<Map<String, dynamic>> _serializeCircleSet(Set<Circle> circles) {
-  if (circles == null) {
-    return null;
-  }
-  return circles.map<Map<String, dynamic>>((Circle p) => p._toJson()).toList();
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/circle_updates.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/circle_updates.dart
deleted file mode 100644
index c977c41..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/circle_updates.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// [Circle] update events to be applied to the [GoogleMap].
-///
-/// Used in [GoogleMapController] when the map is updated.
-class _CircleUpdates {
-  /// Computes [_CircleUpdates] given previous and current [Circle]s.
-  _CircleUpdates.from(Set<Circle> previous, Set<Circle> current) {
-    if (previous == null) {
-      previous = Set<Circle>.identity();
-    }
-
-    if (current == null) {
-      current = Set<Circle>.identity();
-    }
-
-    final Map<CircleId, Circle> previousCircles = _keyByCircleId(previous);
-    final Map<CircleId, Circle> currentCircles = _keyByCircleId(current);
-
-    final Set<CircleId> prevCircleIds = previousCircles.keys.toSet();
-    final Set<CircleId> currentCircleIds = currentCircles.keys.toSet();
-
-    Circle idToCurrentCircle(CircleId id) {
-      return currentCircles[id];
-    }
-
-    final Set<CircleId> _circleIdsToRemove =
-        prevCircleIds.difference(currentCircleIds);
-
-    final Set<Circle> _circlesToAdd = currentCircleIds
-        .difference(prevCircleIds)
-        .map(idToCurrentCircle)
-        .toSet();
-
-    /// Returns `true` if [current] is not equals to previous one with the
-    /// same id.
-    bool hasChanged(Circle current) {
-      final Circle previous = previousCircles[current.circleId];
-      return current != previous;
-    }
-
-    final Set<Circle> _circlesToChange = currentCircleIds
-        .intersection(prevCircleIds)
-        .map(idToCurrentCircle)
-        .where(hasChanged)
-        .toSet();
-
-    circlesToAdd = _circlesToAdd;
-    circleIdsToRemove = _circleIdsToRemove;
-    circlesToChange = _circlesToChange;
-  }
-
-  Set<Circle> circlesToAdd;
-  Set<CircleId> circleIdsToRemove;
-  Set<Circle> circlesToChange;
-
-  Map<String, dynamic> _toMap() {
-    final Map<String, dynamic> updateMap = <String, dynamic>{};
-
-    void addIfNonNull(String fieldName, dynamic value) {
-      if (value != null) {
-        updateMap[fieldName] = value;
-      }
-    }
-
-    addIfNonNull('circlesToAdd', _serializeCircleSet(circlesToAdd));
-    addIfNonNull('circlesToChange', _serializeCircleSet(circlesToChange));
-    addIfNonNull('circleIdsToRemove',
-        circleIdsToRemove.map<dynamic>((CircleId m) => m.value).toList());
-
-    return updateMap;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final _CircleUpdates typedOther = other;
-    return setEquals(circlesToAdd, typedOther.circlesToAdd) &&
-        setEquals(circleIdsToRemove, typedOther.circleIdsToRemove) &&
-        setEquals(circlesToChange, typedOther.circlesToChange);
-  }
-
-  @override
-  int get hashCode =>
-      hashValues(circlesToAdd, circleIdsToRemove, circlesToChange);
-
-  @override
-  String toString() {
-    return '_CircleUpdates{circlesToAdd: $circlesToAdd, '
-        'circleIdsToRemove: $circleIdsToRemove, '
-        'circlesToChange: $circlesToChange}';
-  }
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
index 750bb69..f5ee180 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
@@ -4,14 +4,20 @@
 
 part of google_maps_flutter;
 
+final GoogleMapsFlutterPlatform _googleMapsFlutterPlatform =
+    GoogleMapsFlutterPlatform.instance;
+
 /// Controller for a single GoogleMap instance running on the host platform.
 class GoogleMapController {
+  /// The mapId for this controller
+  final int mapId;
+
   GoogleMapController._(
-    this.channel,
     CameraPosition initialCameraPosition,
-    this._googleMapState,
-  ) : assert(channel != null) {
-    channel.setMethodCallHandler(_handleMethodCall);
+    this._googleMapState, {
+    @required this.mapId,
+  }) : assert(_googleMapsFlutterPlatform != null) {
+    _connectStreams(mapId);
   }
 
   /// Initialize control of a [GoogleMap] with [id].
@@ -24,72 +30,66 @@
     _GoogleMapState googleMapState,
   ) async {
     assert(id != null);
-    final MethodChannel channel =
-        MethodChannel('plugins.flutter.io/google_maps_$id');
-    await channel.invokeMethod<void>('map#waitForMap');
+    await _googleMapsFlutterPlatform.init(id);
     return GoogleMapController._(
-      channel,
       initialCameraPosition,
       googleMapState,
+      mapId: id,
     );
   }
 
   /// Used to communicate with the native platform.
   ///
   /// Accessible only for testing.
+  // TODO(dit) https://github.com/flutter/flutter/issues/55504 Remove this getter.
   @visibleForTesting
-  final MethodChannel channel;
+  MethodChannel get channel {
+    if (_googleMapsFlutterPlatform is MethodChannelGoogleMapsFlutter) {
+      return (_googleMapsFlutterPlatform as MethodChannelGoogleMapsFlutter)
+          .channel(mapId);
+    }
+    return null;
+  }
 
   final _GoogleMapState _googleMapState;
 
-  Future<dynamic> _handleMethodCall(MethodCall call) async {
-    switch (call.method) {
-      case 'camera#onMoveStarted':
-        if (_googleMapState.widget.onCameraMoveStarted != null) {
-          _googleMapState.widget.onCameraMoveStarted();
-        }
-        break;
-      case 'camera#onMove':
-        if (_googleMapState.widget.onCameraMove != null) {
-          _googleMapState.widget.onCameraMove(
-            CameraPosition.fromMap(call.arguments['position']),
-          );
-        }
-        break;
-      case 'camera#onIdle':
-        if (_googleMapState.widget.onCameraIdle != null) {
-          _googleMapState.widget.onCameraIdle();
-        }
-        break;
-      case 'marker#onTap':
-        _googleMapState.onMarkerTap(call.arguments['markerId']);
-        break;
-      case 'marker#onDragEnd':
-        _googleMapState.onMarkerDragEnd(call.arguments['markerId'],
-            LatLng._fromJson(call.arguments['position']));
-        break;
-      case 'infoWindow#onTap':
-        _googleMapState.onInfoWindowTap(call.arguments['markerId']);
-        break;
-      case 'polyline#onTap':
-        _googleMapState.onPolylineTap(call.arguments['polylineId']);
-        break;
-      case 'polygon#onTap':
-        _googleMapState.onPolygonTap(call.arguments['polygonId']);
-        break;
-      case 'circle#onTap':
-        _googleMapState.onCircleTap(call.arguments['circleId']);
-        break;
-      case 'map#onTap':
-        _googleMapState.onTap(LatLng._fromJson(call.arguments['position']));
-        break;
-      case 'map#onLongPress':
-        _googleMapState
-            .onLongPress(LatLng._fromJson(call.arguments['position']));
-        break;
-      default:
-        throw MissingPluginException();
+  void _connectStreams(int mapId) {
+    if (_googleMapState.widget.onCameraMoveStarted != null) {
+      _googleMapsFlutterPlatform
+          .onCameraMoveStarted(mapId: mapId)
+          .listen((_) => _googleMapState.widget.onCameraMoveStarted());
     }
+    if (_googleMapState.widget.onCameraMove != null) {
+      _googleMapsFlutterPlatform.onCameraMove(mapId: mapId).listen(
+          (CameraMoveEvent e) => _googleMapState.widget.onCameraMove(e.value));
+    }
+    if (_googleMapState.widget.onCameraIdle != null) {
+      _googleMapsFlutterPlatform
+          .onCameraIdle(mapId: mapId)
+          .listen((_) => _googleMapState.widget.onCameraIdle());
+    }
+    _googleMapsFlutterPlatform
+        .onMarkerTap(mapId: mapId)
+        .listen((MarkerTapEvent e) => _googleMapState.onMarkerTap(e.value));
+    _googleMapsFlutterPlatform.onMarkerDragEnd(mapId: mapId).listen(
+        (MarkerDragEndEvent e) =>
+            _googleMapState.onMarkerDragEnd(e.value, e.position));
+    _googleMapsFlutterPlatform.onInfoWindowTap(mapId: mapId).listen(
+        (InfoWindowTapEvent e) => _googleMapState.onInfoWindowTap(e.value));
+    _googleMapsFlutterPlatform
+        .onPolylineTap(mapId: mapId)
+        .listen((PolylineTapEvent e) => _googleMapState.onPolylineTap(e.value));
+    _googleMapsFlutterPlatform
+        .onPolygonTap(mapId: mapId)
+        .listen((PolygonTapEvent e) => _googleMapState.onPolygonTap(e.value));
+    _googleMapsFlutterPlatform
+        .onCircleTap(mapId: mapId)
+        .listen((CircleTapEvent e) => _googleMapState.onCircleTap(e.value));
+    _googleMapsFlutterPlatform
+        .onTap(mapId: mapId)
+        .listen((MapTapEvent e) => _googleMapState.onTap(e.position));
+    _googleMapsFlutterPlatform.onLongPress(mapId: mapId).listen(
+        (MapLongPressEvent e) => _googleMapState.onLongPress(e.position));
   }
 
   /// Updates configuration options of the map user interface.
@@ -98,14 +98,10 @@
   /// platform side.
   ///
   /// The returned [Future] completes after listeners have been notified.
-  Future<void> _updateMapOptions(Map<String, dynamic> optionsUpdate) async {
+  Future<void> _updateMapOptions(Map<String, dynamic> optionsUpdate) {
     assert(optionsUpdate != null);
-    await channel.invokeMethod<void>(
-      'map#update',
-      <String, dynamic>{
-        'options': optionsUpdate,
-      },
-    );
+    return _googleMapsFlutterPlatform.updateMapOptions(optionsUpdate,
+        mapId: mapId);
   }
 
   /// Updates marker configuration.
@@ -114,12 +110,10 @@
   /// platform side.
   ///
   /// The returned [Future] completes after listeners have been notified.
-  Future<void> _updateMarkers(_MarkerUpdates markerUpdates) async {
+  Future<void> _updateMarkers(MarkerUpdates markerUpdates) {
     assert(markerUpdates != null);
-    await channel.invokeMethod<void>(
-      'markers#update',
-      markerUpdates._toMap(),
-    );
+    return _googleMapsFlutterPlatform.updateMarkers(markerUpdates,
+        mapId: mapId);
   }
 
   /// Updates polygon configuration.
@@ -128,12 +122,10 @@
   /// platform side.
   ///
   /// The returned [Future] completes after listeners have been notified.
-  Future<void> _updatePolygons(_PolygonUpdates polygonUpdates) async {
+  Future<void> _updatePolygons(PolygonUpdates polygonUpdates) {
     assert(polygonUpdates != null);
-    await channel.invokeMethod<void>(
-      'polygons#update',
-      polygonUpdates._toMap(),
-    );
+    return _googleMapsFlutterPlatform.updatePolygons(polygonUpdates,
+        mapId: mapId);
   }
 
   /// Updates polyline configuration.
@@ -142,12 +134,10 @@
   /// platform side.
   ///
   /// The returned [Future] completes after listeners have been notified.
-  Future<void> _updatePolylines(_PolylineUpdates polylineUpdates) async {
+  Future<void> _updatePolylines(PolylineUpdates polylineUpdates) {
     assert(polylineUpdates != null);
-    await channel.invokeMethod<void>(
-      'polylines#update',
-      polylineUpdates._toMap(),
-    );
+    return _googleMapsFlutterPlatform.updatePolylines(polylineUpdates,
+        mapId: mapId);
   }
 
   /// Updates circle configuration.
@@ -156,32 +146,26 @@
   /// platform side.
   ///
   /// The returned [Future] completes after listeners have been notified.
-  Future<void> _updateCircles(_CircleUpdates circleUpdates) async {
+  Future<void> _updateCircles(CircleUpdates circleUpdates) {
     assert(circleUpdates != null);
-    await channel.invokeMethod<void>(
-      'circles#update',
-      circleUpdates._toMap(),
-    );
+    return _googleMapsFlutterPlatform.updateCircles(circleUpdates,
+        mapId: mapId);
   }
 
   /// Starts an animated change of the map camera position.
   ///
   /// The returned [Future] completes after the change has been started on the
   /// platform side.
-  Future<void> animateCamera(CameraUpdate cameraUpdate) async {
-    await channel.invokeMethod<void>('camera#animate', <String, dynamic>{
-      'cameraUpdate': cameraUpdate._toJson(),
-    });
+  Future<void> animateCamera(CameraUpdate cameraUpdate) {
+    return _googleMapsFlutterPlatform.animateCamera(cameraUpdate, mapId: mapId);
   }
 
   /// Changes the map camera position.
   ///
   /// The returned [Future] completes after the change has been made on the
   /// platform side.
-  Future<void> moveCamera(CameraUpdate cameraUpdate) async {
-    await channel.invokeMethod<void>('camera#move', <String, dynamic>{
-      'cameraUpdate': cameraUpdate._toJson(),
-    });
+  Future<void> moveCamera(CameraUpdate cameraUpdate) {
+    return _googleMapsFlutterPlatform.moveCamera(cameraUpdate, mapId: mapId);
   }
 
   /// Sets the styling of the base map.
@@ -197,23 +181,13 @@
   /// Also, refer [iOS](https://developers.google.com/maps/documentation/ios-sdk/style-reference)
   /// and [Android](https://developers.google.com/maps/documentation/android-sdk/style-reference)
   /// style reference for more information regarding the supported styles.
-  Future<void> setMapStyle(String mapStyle) async {
-    final List<dynamic> successAndError =
-        await channel.invokeMethod<List<dynamic>>('map#setStyle', mapStyle);
-    final bool success = successAndError[0];
-    if (!success) {
-      throw MapStyleException(successAndError[1]);
-    }
+  Future<void> setMapStyle(String mapStyle) {
+    return _googleMapsFlutterPlatform.setMapStyle(mapStyle, mapId: mapId);
   }
 
   /// Return [LatLngBounds] defining the region that is visible in a map.
-  Future<LatLngBounds> getVisibleRegion() async {
-    final Map<String, dynamic> latLngBounds =
-        await channel.invokeMapMethod<String, dynamic>('map#getVisibleRegion');
-    final LatLng southwest = LatLng._fromJson(latLngBounds['southwest']);
-    final LatLng northeast = LatLng._fromJson(latLngBounds['northeast']);
-
-    return LatLngBounds(northeast: northeast, southwest: southwest);
+  Future<LatLngBounds> getVisibleRegion() {
+    return _googleMapsFlutterPlatform.getVisibleRegion(mapId: mapId);
   }
 
   /// Return [ScreenCoordinate] of the [LatLng] in the current map view.
@@ -221,20 +195,16 @@
   /// A projection is used to translate between on screen location and geographic coordinates.
   /// Screen location is in screen pixels (not display pixels) with respect to the top left corner
   /// of the map, not necessarily of the whole screen.
-  Future<ScreenCoordinate> getScreenCoordinate(LatLng latLng) async {
-    final Map<String, int> point = await channel.invokeMapMethod<String, int>(
-        'map#getScreenCoordinate', latLng._toJson());
-    return ScreenCoordinate(x: point['x'], y: point['y']);
+  Future<ScreenCoordinate> getScreenCoordinate(LatLng latLng) {
+    return _googleMapsFlutterPlatform.getScreenCoordinate(latLng, mapId: mapId);
   }
 
   /// Returns [LatLng] corresponding to the [ScreenCoordinate] in the current map view.
   ///
   /// Returned [LatLng] corresponds to a screen location. The screen location is specified in screen
   /// pixels (not display pixels) relative to the top left of the map, not top left of the whole screen.
-  Future<LatLng> getLatLng(ScreenCoordinate screenCoordinate) async {
-    final List<dynamic> latLng = await channel.invokeMethod<List<dynamic>>(
-        'map#getLatLng', screenCoordinate._toJson());
-    return LatLng(latLng[0], latLng[1]);
+  Future<LatLng> getLatLng(ScreenCoordinate screenCoordinate) {
+    return _googleMapsFlutterPlatform.getLatLng(screenCoordinate, mapId: mapId);
   }
 
   /// Programmatically show the Info Window for a [Marker].
@@ -245,10 +215,10 @@
   /// * See also:
   ///   * [hideMarkerInfoWindow] to hide the Info Window.
   ///   * [isMarkerInfoWindowShown] to check if the Info Window is showing.
-  Future<void> showMarkerInfoWindow(MarkerId markerId) async {
+  Future<void> showMarkerInfoWindow(MarkerId markerId) {
     assert(markerId != null);
-    await channel.invokeMethod<void>(
-        'markers#showInfoWindow', <String, String>{'markerId': markerId.value});
+    return _googleMapsFlutterPlatform.showMarkerInfoWindow(markerId,
+        mapId: mapId);
   }
 
   /// Programmatically hide the Info Window for a [Marker].
@@ -259,10 +229,10 @@
   /// * See also:
   ///   * [showMarkerInfoWindow] to show the Info Window.
   ///   * [isMarkerInfoWindowShown] to check if the Info Window is showing.
-  Future<void> hideMarkerInfoWindow(MarkerId markerId) async {
+  Future<void> hideMarkerInfoWindow(MarkerId markerId) {
     assert(markerId != null);
-    await channel.invokeMethod<void>(
-        'markers#hideInfoWindow', <String, String>{'markerId': markerId.value});
+    return _googleMapsFlutterPlatform.hideMarkerInfoWindow(markerId,
+        mapId: mapId);
   }
 
   /// Returns `true` when the [InfoWindow] is showing, `false` otherwise.
@@ -273,21 +243,19 @@
   /// * See also:
   ///   * [showMarkerInfoWindow] to show the Info Window.
   ///   * [hideMarkerInfoWindow] to hide the Info Window.
-  Future<bool> isMarkerInfoWindowShown(MarkerId markerId) async {
+  Future<bool> isMarkerInfoWindowShown(MarkerId markerId) {
     assert(markerId != null);
-    return await channel.invokeMethod<bool>('markers#isInfoWindowShown',
-        <String, String>{'markerId': markerId.value});
+    return _googleMapsFlutterPlatform.isMarkerInfoWindowShown(markerId,
+        mapId: mapId);
   }
 
   /// Returns the current zoom level of the map
-  Future<double> getZoomLevel() async {
-    final double zoomLevel =
-        await channel.invokeMethod<double>('map#getZoomLevel');
-    return zoomLevel;
+  Future<double> getZoomLevel() {
+    return _googleMapsFlutterPlatform.getZoomLevel(mapId: mapId);
   }
 
   /// Returns the image bytes of the map
-  Future<Uint8List> takeSnapshot() async {
-    return await channel.invokeMethod<Uint8List>('map#takeSnapshot');
+  Future<Uint8List> takeSnapshot() {
+    return _googleMapsFlutterPlatform.takeSnapshot(mapId: mapId);
   }
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
index f2edde3..ecd1a70 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
@@ -10,14 +10,6 @@
 /// map is created.
 typedef void MapCreatedCallback(GoogleMapController controller);
 
-/// Callback that receives updates to the camera position.
-///
-/// This callback is triggered when the platform Google Map
-/// registers a camera movement.
-///
-/// This is used in [GoogleMap.onCameraMove].
-typedef void CameraPositionCallback(CameraPosition position);
-
 /// A widget which displays a map with data obtained from the Google Maps service.
 class GoogleMap extends StatefulWidget {
   /// Creates a widget displaying data from Google Maps services.
@@ -221,41 +213,26 @@
     final Map<String, dynamic> creationParams = <String, dynamic>{
       'initialCameraPosition': widget.initialCameraPosition?.toMap(),
       'options': _googleMapOptions.toMap(),
-      'markersToAdd': _serializeMarkerSet(widget.markers),
-      'polygonsToAdd': _serializePolygonSet(widget.polygons),
-      'polylinesToAdd': _serializePolylineSet(widget.polylines),
-      'circlesToAdd': _serializeCircleSet(widget.circles),
+      'markersToAdd': serializeMarkerSet(widget.markers),
+      'polygonsToAdd': serializePolygonSet(widget.polygons),
+      'polylinesToAdd': serializePolylineSet(widget.polylines),
+      'circlesToAdd': serializeCircleSet(widget.circles),
     };
-    if (defaultTargetPlatform == TargetPlatform.android) {
-      return AndroidView(
-        viewType: 'plugins.flutter.io/google_maps',
-        onPlatformViewCreated: onPlatformViewCreated,
-        gestureRecognizers: widget.gestureRecognizers,
-        creationParams: creationParams,
-        creationParamsCodec: const StandardMessageCodec(),
-      );
-    } else if (defaultTargetPlatform == TargetPlatform.iOS) {
-      return UiKitView(
-        viewType: 'plugins.flutter.io/google_maps',
-        onPlatformViewCreated: onPlatformViewCreated,
-        gestureRecognizers: widget.gestureRecognizers,
-        creationParams: creationParams,
-        creationParamsCodec: const StandardMessageCodec(),
-      );
-    }
-
-    return Text(
-        '$defaultTargetPlatform is not yet supported by the maps plugin');
+    return _googleMapsFlutterPlatform.buildView(
+      creationParams,
+      widget.gestureRecognizers,
+      onPlatformViewCreated,
+    );
   }
 
   @override
   void initState() {
     super.initState();
     _googleMapOptions = _GoogleMapOptions.fromWidget(widget);
-    _markers = _keyByMarkerId(widget.markers);
-    _polygons = _keyByPolygonId(widget.polygons);
-    _polylines = _keyByPolylineId(widget.polylines);
-    _circles = _keyByCircleId(widget.circles);
+    _markers = keyByMarkerId(widget.markers);
+    _polygons = keyByPolygonId(widget.polygons);
+    _polylines = keyByPolylineId(widget.polylines);
+    _circles = keyByCircleId(widget.circles);
   }
 
   @override
@@ -285,32 +262,32 @@
     final GoogleMapController controller = await _controller.future;
     // ignore: unawaited_futures
     controller._updateMarkers(
-        _MarkerUpdates.from(_markers.values.toSet(), widget.markers));
-    _markers = _keyByMarkerId(widget.markers);
+        MarkerUpdates.from(_markers.values.toSet(), widget.markers));
+    _markers = keyByMarkerId(widget.markers);
   }
 
   void _updatePolygons() async {
     final GoogleMapController controller = await _controller.future;
     // ignore: unawaited_futures
     controller._updatePolygons(
-        _PolygonUpdates.from(_polygons.values.toSet(), widget.polygons));
-    _polygons = _keyByPolygonId(widget.polygons);
+        PolygonUpdates.from(_polygons.values.toSet(), widget.polygons));
+    _polygons = keyByPolygonId(widget.polygons);
   }
 
   void _updatePolylines() async {
     final GoogleMapController controller = await _controller.future;
     // ignore: unawaited_futures
     controller._updatePolylines(
-        _PolylineUpdates.from(_polylines.values.toSet(), widget.polylines));
-    _polylines = _keyByPolylineId(widget.polylines);
+        PolylineUpdates.from(_polylines.values.toSet(), widget.polylines));
+    _polylines = keyByPolylineId(widget.polylines);
   }
 
   void _updateCircles() async {
     final GoogleMapController controller = await _controller.future;
     // ignore: unawaited_futures
     controller._updateCircles(
-        _CircleUpdates.from(_circles.values.toSet(), widget.circles));
-    _circles = _keyByCircleId(widget.circles);
+        CircleUpdates.from(_circles.values.toSet(), widget.circles));
+    _circles = keyByCircleId(widget.circles);
   }
 
   Future<void> onPlatformViewCreated(int id) async {
@@ -325,45 +302,39 @@
     }
   }
 
-  void onMarkerTap(String markerIdParam) {
-    assert(markerIdParam != null);
-    final MarkerId markerId = MarkerId(markerIdParam);
+  void onMarkerTap(MarkerId markerId) {
+    assert(markerId != null);
     if (_markers[markerId]?.onTap != null) {
       _markers[markerId].onTap();
     }
   }
 
-  void onMarkerDragEnd(String markerIdParam, LatLng position) {
-    assert(markerIdParam != null);
-    final MarkerId markerId = MarkerId(markerIdParam);
+  void onMarkerDragEnd(MarkerId markerId, LatLng position) {
+    assert(markerId != null);
     if (_markers[markerId]?.onDragEnd != null) {
       _markers[markerId].onDragEnd(position);
     }
   }
 
-  void onPolygonTap(String polygonIdParam) {
-    assert(polygonIdParam != null);
-    final PolygonId polygonId = PolygonId(polygonIdParam);
+  void onPolygonTap(PolygonId polygonId) {
+    assert(polygonId != null);
     _polygons[polygonId].onTap();
   }
 
-  void onPolylineTap(String polylineIdParam) {
-    assert(polylineIdParam != null);
-    final PolylineId polylineId = PolylineId(polylineIdParam);
+  void onPolylineTap(PolylineId polylineId) {
+    assert(polylineId != null);
     if (_polylines[polylineId]?.onTap != null) {
       _polylines[polylineId].onTap();
     }
   }
 
-  void onCircleTap(String circleIdParam) {
-    assert(circleIdParam != null);
-    final CircleId circleId = CircleId(circleIdParam);
+  void onCircleTap(CircleId circleId) {
+    assert(circleId != null);
     _circles[circleId].onTap();
   }
 
-  void onInfoWindowTap(String markerIdParam) {
-    assert(markerIdParam != null);
-    final MarkerId markerId = MarkerId(markerIdParam);
+  void onInfoWindowTap(MarkerId markerId) {
+    assert(markerId != null);
     if (_markers[markerId]?.infoWindow?.onTap != null) {
       _markers[markerId].infoWindow.onTap();
     }
@@ -476,9 +447,9 @@
 
     addIfNonNull('compassEnabled', compassEnabled);
     addIfNonNull('mapToolbarEnabled', mapToolbarEnabled);
-    addIfNonNull('cameraTargetBounds', cameraTargetBounds?._toJson());
+    addIfNonNull('cameraTargetBounds', cameraTargetBounds?.toJson());
     addIfNonNull('mapType', mapType?.index);
-    addIfNonNull('minMaxZoomPreference', minMaxZoomPreference?._toJson());
+    addIfNonNull('minMaxZoomPreference', minMaxZoomPreference?.toJson());
     addIfNonNull('rotateGesturesEnabled', rotateGesturesEnabled);
     addIfNonNull('scrollGesturesEnabled', scrollGesturesEnabled);
     addIfNonNull('tiltGesturesEnabled', tiltGesturesEnabled);
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/joint_type.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/joint_type.dart
deleted file mode 100644
index ced61ba..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/joint_type.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Joint types for [Polyline].
-@immutable
-class JointType {
-  const JointType._(this.value);
-
-  /// The value representing the [JointType] on the sdk.
-  final int value;
-
-  /// Mitered joint, with fixed pointed extrusion equal to half the stroke width on the outside of the joint.
-  ///
-  /// Constant Value: 0
-  static const JointType mitered = JointType._(0);
-
-  /// Flat bevel on the outside of the joint.
-  ///
-  /// Constant Value: 1
-  static const JointType bevel = JointType._(1);
-
-  /// Rounded on the outside of the joint by an arc of radius equal to half the stroke width, centered at the vertex.
-  ///
-  /// Constant Value: 2
-  static const JointType round = JointType._(2);
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/location.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/location.dart
deleted file mode 100644
index ae299ce..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/location.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// A pair of latitude and longitude coordinates, stored as degrees.
-class LatLng {
-  /// Creates a geographical location specified in degrees [latitude] and
-  /// [longitude].
-  ///
-  /// The latitude is clamped to the inclusive interval from -90.0 to +90.0.
-  ///
-  /// The longitude is normalized to the half-open interval from -180.0
-  /// (inclusive) to +180.0 (exclusive)
-  const LatLng(double latitude, double longitude)
-      : assert(latitude != null),
-        assert(longitude != null),
-        latitude =
-            (latitude < -90.0 ? -90.0 : (90.0 < latitude ? 90.0 : latitude)),
-        longitude = (longitude + 180.0) % 360.0 - 180.0;
-
-  /// The latitude in degrees between -90.0 and 90.0, both inclusive.
-  final double latitude;
-
-  /// The longitude in degrees between -180.0 (inclusive) and 180.0 (exclusive).
-  final double longitude;
-
-  dynamic _toJson() {
-    return <double>[latitude, longitude];
-  }
-
-  static LatLng _fromJson(dynamic json) {
-    if (json == null) {
-      return null;
-    }
-    return LatLng(json[0], json[1]);
-  }
-
-  @override
-  String toString() => '$runtimeType($latitude, $longitude)';
-
-  @override
-  bool operator ==(Object o) {
-    return o is LatLng && o.latitude == latitude && o.longitude == longitude;
-  }
-
-  @override
-  int get hashCode => hashValues(latitude, longitude);
-}
-
-/// A latitude/longitude aligned rectangle.
-///
-/// The rectangle conceptually includes all points (lat, lng) where
-/// * lat ∈ [`southwest.latitude`, `northeast.latitude`]
-/// * lng ∈ [`southwest.longitude`, `northeast.longitude`],
-///   if `southwest.longitude` ≤ `northeast.longitude`,
-/// * lng ∈ [-180, `northeast.longitude`] ∪ [`southwest.longitude`, 180],
-///   if `northeast.longitude` < `southwest.longitude`
-class LatLngBounds {
-  /// Creates geographical bounding box with the specified corners.
-  ///
-  /// The latitude of the southwest corner cannot be larger than the
-  /// latitude of the northeast corner.
-  LatLngBounds({@required this.southwest, @required this.northeast})
-      : assert(southwest != null),
-        assert(northeast != null),
-        assert(southwest.latitude <= northeast.latitude);
-
-  /// The southwest corner of the rectangle.
-  final LatLng southwest;
-
-  /// The northeast corner of the rectangle.
-  final LatLng northeast;
-
-  dynamic _toList() {
-    return <dynamic>[southwest._toJson(), northeast._toJson()];
-  }
-
-  /// Returns whether this rectangle contains the given [LatLng].
-  bool contains(LatLng point) {
-    return _containsLatitude(point.latitude) &&
-        _containsLongitude(point.longitude);
-  }
-
-  bool _containsLatitude(double lat) {
-    return (southwest.latitude <= lat) && (lat <= northeast.latitude);
-  }
-
-  bool _containsLongitude(double lng) {
-    if (southwest.longitude <= northeast.longitude) {
-      return southwest.longitude <= lng && lng <= northeast.longitude;
-    } else {
-      return southwest.longitude <= lng || lng <= northeast.longitude;
-    }
-  }
-
-  /// Converts a list to [LatLngBounds].
-  @visibleForTesting
-  static LatLngBounds fromList(dynamic json) {
-    if (json == null) {
-      return null;
-    }
-    return LatLngBounds(
-      southwest: LatLng._fromJson(json[0]),
-      northeast: LatLng._fromJson(json[1]),
-    );
-  }
-
-  @override
-  String toString() {
-    return '$runtimeType($southwest, $northeast)';
-  }
-
-  @override
-  bool operator ==(Object o) {
-    return o is LatLngBounds &&
-        o.southwest == southwest &&
-        o.northeast == northeast;
-  }
-
-  @override
-  int get hashCode => hashValues(southwest, northeast);
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/marker.dart
deleted file mode 100644
index 480f0a3..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/marker.dart
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-dynamic _offsetToJson(Offset offset) {
-  if (offset == null) {
-    return null;
-  }
-  return <dynamic>[offset.dx, offset.dy];
-}
-
-/// Text labels for a [Marker] info window.
-class InfoWindow {
-  /// Creates an immutable representation of a label on for [Marker].
-  const InfoWindow({
-    this.title,
-    this.snippet,
-    this.anchor = const Offset(0.5, 0.0),
-    this.onTap,
-  });
-
-  /// Text labels specifying that no text is to be displayed.
-  static const InfoWindow noText = InfoWindow();
-
-  /// Text displayed in an info window when the user taps the marker.
-  ///
-  /// A null value means no title.
-  final String title;
-
-  /// Additional text displayed below the [title].
-  ///
-  /// A null value means no additional text.
-  final String snippet;
-
-  /// The icon image point that will be the anchor of the info window when
-  /// displayed.
-  ///
-  /// The image point is specified in normalized coordinates: An anchor of
-  /// (0.0, 0.0) means the top left corner of the image. An anchor
-  /// of (1.0, 1.0) means the bottom right corner of the image.
-  final Offset anchor;
-
-  /// onTap callback for this [InfoWindow].
-  final VoidCallback onTap;
-
-  /// Creates a new [InfoWindow] object whose values are the same as this instance,
-  /// unless overwritten by the specified parameters.
-  InfoWindow copyWith({
-    String titleParam,
-    String snippetParam,
-    Offset anchorParam,
-    VoidCallback onTapParam,
-  }) {
-    return InfoWindow(
-      title: titleParam ?? title,
-      snippet: snippetParam ?? snippet,
-      anchor: anchorParam ?? anchor,
-      onTap: onTapParam ?? onTap,
-    );
-  }
-
-  dynamic _toJson() {
-    final Map<String, dynamic> json = <String, dynamic>{};
-
-    void addIfPresent(String fieldName, dynamic value) {
-      if (value != null) {
-        json[fieldName] = value;
-      }
-    }
-
-    addIfPresent('title', title);
-    addIfPresent('snippet', snippet);
-    addIfPresent('anchor', _offsetToJson(anchor));
-
-    return json;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final InfoWindow typedOther = other;
-    return title == typedOther.title &&
-        snippet == typedOther.snippet &&
-        anchor == typedOther.anchor;
-  }
-
-  @override
-  int get hashCode => hashValues(title.hashCode, snippet, anchor);
-
-  @override
-  String toString() {
-    return 'InfoWindow{title: $title, snippet: $snippet, anchor: $anchor}';
-  }
-}
-
-/// Uniquely identifies a [Marker] among [GoogleMap] markers.
-///
-/// This does not have to be globally unique, only unique among the list.
-@immutable
-class MarkerId {
-  /// Creates an immutable identifier for a [Marker].
-  MarkerId(this.value) : assert(value != null);
-
-  /// value of the [MarkerId].
-  final String value;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final MarkerId typedOther = other;
-    return value == typedOther.value;
-  }
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  String toString() {
-    return 'MarkerId{value: $value}';
-  }
-}
-
-/// Marks a geographical location on the map.
-///
-/// A marker icon is drawn oriented against the device's screen rather than
-/// the map's surface; that is, it will not necessarily change orientation
-/// due to map rotations, tilting, or zooming.
-@immutable
-class Marker {
-  /// Creates a set of marker configuration options.
-  ///
-  /// Default marker options.
-  ///
-  /// Specifies a marker that
-  /// * is fully opaque; [alpha] is 1.0
-  /// * uses icon bottom center to indicate map position; [anchor] is (0.5, 1.0)
-  /// * has default tap handling; [consumeTapEvents] is false
-  /// * is stationary; [draggable] is false
-  /// * is drawn against the screen, not the map; [flat] is false
-  /// * has a default icon; [icon] is `BitmapDescriptor.defaultMarker`
-  /// * anchors the info window at top center; [infoWindowAnchor] is (0.5, 0.0)
-  /// * has no info window text; [infoWindowText] is `InfoWindowText.noText`
-  /// * is positioned at 0, 0; [position] is `LatLng(0.0, 0.0)`
-  /// * has an axis-aligned icon; [rotation] is 0.0
-  /// * is visible; [visible] is true
-  /// * is placed at the base of the drawing order; [zIndex] is 0.0
-  /// * reports [onTap] events
-  /// * reports [onDragEnd] events
-  const Marker({
-    @required this.markerId,
-    this.alpha = 1.0,
-    this.anchor = const Offset(0.5, 1.0),
-    this.consumeTapEvents = false,
-    this.draggable = false,
-    this.flat = false,
-    this.icon = BitmapDescriptor.defaultMarker,
-    this.infoWindow = InfoWindow.noText,
-    this.position = const LatLng(0.0, 0.0),
-    this.rotation = 0.0,
-    this.visible = true,
-    this.zIndex = 0.0,
-    this.onTap,
-    this.onDragEnd,
-  }) : assert(alpha == null || (0.0 <= alpha && alpha <= 1.0));
-
-  /// Uniquely identifies a [Marker].
-  final MarkerId markerId;
-
-  /// The opacity of the marker, between 0.0 and 1.0 inclusive.
-  ///
-  /// 0.0 means fully transparent, 1.0 means fully opaque.
-  final double alpha;
-
-  /// The icon image point that will be placed at the [position] of the marker.
-  ///
-  /// The image point is specified in normalized coordinates: An anchor of
-  /// (0.0, 0.0) means the top left corner of the image. An anchor
-  /// of (1.0, 1.0) means the bottom right corner of the image.
-  final Offset anchor;
-
-  /// True if the marker icon consumes tap events. If not, the map will perform
-  /// default tap handling by centering the map on the marker and displaying its
-  /// info window.
-  final bool consumeTapEvents;
-
-  /// True if the marker is draggable by user touch events.
-  final bool draggable;
-
-  /// True if the marker is rendered flatly against the surface of the Earth, so
-  /// that it will rotate and tilt along with map camera movements.
-  final bool flat;
-
-  /// A description of the bitmap used to draw the marker icon.
-  final BitmapDescriptor icon;
-
-  /// A Google Maps InfoWindow.
-  ///
-  /// The window is displayed when the marker is tapped.
-  final InfoWindow infoWindow;
-
-  /// Geographical location of the marker.
-  final LatLng position;
-
-  /// Rotation of the marker image in degrees clockwise from the [anchor] point.
-  final double rotation;
-
-  /// True if the marker is visible.
-  final bool visible;
-
-  /// The z-index of the marker, used to determine relative drawing order of
-  /// map overlays.
-  ///
-  /// Overlays are drawn in order of z-index, so that lower values means drawn
-  /// earlier, and thus appearing to be closer to the surface of the Earth.
-  final double zIndex;
-
-  /// Callbacks to receive tap events for markers placed on this map.
-  final VoidCallback onTap;
-
-  /// Signature reporting the new [LatLng] at the end of a drag event.
-  final ValueChanged<LatLng> onDragEnd;
-
-  /// Creates a new [Marker] object whose values are the same as this instance,
-  /// unless overwritten by the specified parameters.
-  Marker copyWith({
-    double alphaParam,
-    Offset anchorParam,
-    bool consumeTapEventsParam,
-    bool draggableParam,
-    bool flatParam,
-    BitmapDescriptor iconParam,
-    InfoWindow infoWindowParam,
-    LatLng positionParam,
-    double rotationParam,
-    bool visibleParam,
-    double zIndexParam,
-    VoidCallback onTapParam,
-    ValueChanged<LatLng> onDragEndParam,
-  }) {
-    return Marker(
-      markerId: markerId,
-      alpha: alphaParam ?? alpha,
-      anchor: anchorParam ?? anchor,
-      consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents,
-      draggable: draggableParam ?? draggable,
-      flat: flatParam ?? flat,
-      icon: iconParam ?? icon,
-      infoWindow: infoWindowParam ?? infoWindow,
-      position: positionParam ?? position,
-      rotation: rotationParam ?? rotation,
-      visible: visibleParam ?? visible,
-      zIndex: zIndexParam ?? zIndex,
-      onTap: onTapParam ?? onTap,
-      onDragEnd: onDragEndParam ?? onDragEnd,
-    );
-  }
-
-  /// Creates a new [Marker] object whose values are the same as this instance.
-  Marker clone() => copyWith();
-
-  Map<String, dynamic> _toJson() {
-    final Map<String, dynamic> json = <String, dynamic>{};
-
-    void addIfPresent(String fieldName, dynamic value) {
-      if (value != null) {
-        json[fieldName] = value;
-      }
-    }
-
-    addIfPresent('markerId', markerId.value);
-    addIfPresent('alpha', alpha);
-    addIfPresent('anchor', _offsetToJson(anchor));
-    addIfPresent('consumeTapEvents', consumeTapEvents);
-    addIfPresent('draggable', draggable);
-    addIfPresent('flat', flat);
-    addIfPresent('icon', icon?._toJson());
-    addIfPresent('infoWindow', infoWindow?._toJson());
-    addIfPresent('position', position?._toJson());
-    addIfPresent('rotation', rotation);
-    addIfPresent('visible', visible);
-    addIfPresent('zIndex', zIndex);
-    return json;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Marker typedOther = other;
-    return markerId == typedOther.markerId &&
-        alpha == typedOther.alpha &&
-        anchor == typedOther.anchor &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        draggable == typedOther.draggable &&
-        flat == typedOther.flat &&
-        icon == typedOther.icon &&
-        infoWindow == typedOther.infoWindow &&
-        position == typedOther.position &&
-        rotation == typedOther.rotation &&
-        visible == typedOther.visible &&
-        zIndex == typedOther.zIndex;
-  }
-
-  @override
-  int get hashCode => markerId.hashCode;
-
-  @override
-  String toString() {
-    return 'Marker{markerId: $markerId, alpha: $alpha, anchor: $anchor, '
-        'consumeTapEvents: $consumeTapEvents, draggable: $draggable, flat: $flat, '
-        'icon: $icon, infoWindow: $infoWindow, position: $position, rotation: $rotation, '
-        'visible: $visible, zIndex: $zIndex, onTap: $onTap}';
-  }
-}
-
-Map<MarkerId, Marker> _keyByMarkerId(Iterable<Marker> markers) {
-  if (markers == null) {
-    return <MarkerId, Marker>{};
-  }
-  return Map<MarkerId, Marker>.fromEntries(markers.map((Marker marker) =>
-      MapEntry<MarkerId, Marker>(marker.markerId, marker.clone())));
-}
-
-List<Map<String, dynamic>> _serializeMarkerSet(Set<Marker> markers) {
-  if (markers == null) {
-    return null;
-  }
-  return markers.map<Map<String, dynamic>>((Marker m) => m._toJson()).toList();
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/marker_updates.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/marker_updates.dart
deleted file mode 100644
index d4a0825..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/marker_updates.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// [Marker] update events to be applied to the [GoogleMap].
-///
-/// Used in [GoogleMapController] when the map is updated.
-class _MarkerUpdates {
-  /// Computes [_MarkerUpdates] given previous and current [Marker]s.
-  _MarkerUpdates.from(Set<Marker> previous, Set<Marker> current) {
-    if (previous == null) {
-      previous = Set<Marker>.identity();
-    }
-
-    if (current == null) {
-      current = Set<Marker>.identity();
-    }
-
-    final Map<MarkerId, Marker> previousMarkers = _keyByMarkerId(previous);
-    final Map<MarkerId, Marker> currentMarkers = _keyByMarkerId(current);
-
-    final Set<MarkerId> prevMarkerIds = previousMarkers.keys.toSet();
-    final Set<MarkerId> currentMarkerIds = currentMarkers.keys.toSet();
-
-    Marker idToCurrentMarker(MarkerId id) {
-      return currentMarkers[id];
-    }
-
-    final Set<MarkerId> _markerIdsToRemove =
-        prevMarkerIds.difference(currentMarkerIds);
-
-    final Set<Marker> _markersToAdd = currentMarkerIds
-        .difference(prevMarkerIds)
-        .map(idToCurrentMarker)
-        .toSet();
-
-    /// Returns `true` if [current] is not equals to previous one with the
-    /// same id.
-    bool hasChanged(Marker current) {
-      final Marker previous = previousMarkers[current.markerId];
-      return current != previous;
-    }
-
-    final Set<Marker> _markersToChange = currentMarkerIds
-        .intersection(prevMarkerIds)
-        .map(idToCurrentMarker)
-        .where(hasChanged)
-        .toSet();
-
-    markersToAdd = _markersToAdd;
-    markerIdsToRemove = _markerIdsToRemove;
-    markersToChange = _markersToChange;
-  }
-
-  Set<Marker> markersToAdd;
-  Set<MarkerId> markerIdsToRemove;
-  Set<Marker> markersToChange;
-
-  Map<String, dynamic> _toMap() {
-    final Map<String, dynamic> updateMap = <String, dynamic>{};
-
-    void addIfNonNull(String fieldName, dynamic value) {
-      if (value != null) {
-        updateMap[fieldName] = value;
-      }
-    }
-
-    addIfNonNull('markersToAdd', _serializeMarkerSet(markersToAdd));
-    addIfNonNull('markersToChange', _serializeMarkerSet(markersToChange));
-    addIfNonNull('markerIdsToRemove',
-        markerIdsToRemove.map<dynamic>((MarkerId m) => m.value).toList());
-
-    return updateMap;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final _MarkerUpdates typedOther = other;
-    return setEquals(markersToAdd, typedOther.markersToAdd) &&
-        setEquals(markerIdsToRemove, typedOther.markerIdsToRemove) &&
-        setEquals(markersToChange, typedOther.markersToChange);
-  }
-
-  @override
-  int get hashCode =>
-      hashValues(markersToAdd, markerIdsToRemove, markersToChange);
-
-  @override
-  String toString() {
-    return '_MarkerUpdates{markersToAdd: $markersToAdd, '
-        'markerIdsToRemove: $markerIdsToRemove, '
-        'markersToChange: $markersToChange}';
-  }
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/pattern_item.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/pattern_item.dart
deleted file mode 100644
index 82e8703..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/pattern_item.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Item used in the stroke pattern for a Polyline.
-@immutable
-class PatternItem {
-  const PatternItem._(this._json);
-
-  /// A dot used in the stroke pattern for a [Polyline].
-  static const PatternItem dot = PatternItem._(<dynamic>['dot']);
-
-  /// A dash used in the stroke pattern for a [Polyline].
-  ///
-  /// [length] has to be non-negative.
-  static PatternItem dash(double length) {
-    assert(length >= 0.0);
-    return PatternItem._(<dynamic>['dash', length]);
-  }
-
-  /// A gap used in the stroke pattern for a [Polyline].
-  ///
-  /// [length] has to be non-negative.
-  static PatternItem gap(double length) {
-    assert(length >= 0.0);
-    return PatternItem._(<dynamic>['gap', length]);
-  }
-
-  final dynamic _json;
-
-  dynamic _toJson() => _json;
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/polygon.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/polygon.dart
deleted file mode 100644
index 973667e..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/polygon.dart
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Uniquely identifies a [Polygon] among [GoogleMap] polygons.
-///
-/// This does not have to be globally unique, only unique among the list.
-@immutable
-class PolygonId {
-  /// Creates an immutable identifier for a [Polygon].
-  PolygonId(this.value) : assert(value != null);
-
-  /// value of the [PolygonId].
-  final String value;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final PolygonId typedOther = other;
-    return value == typedOther.value;
-  }
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  String toString() {
-    return 'PolygonId{value: $value}';
-  }
-}
-
-/// Draws a polygon through geographical locations on the map.
-@immutable
-class Polygon {
-  /// Creates an immutable representation of a polygon through geographical locations on the map.
-  const Polygon({
-    @required this.polygonId,
-    this.consumeTapEvents = false,
-    this.fillColor = Colors.black,
-    this.geodesic = false,
-    this.points = const <LatLng>[],
-    this.strokeColor = Colors.black,
-    this.strokeWidth = 10,
-    this.visible = true,
-    this.zIndex = 0,
-    this.onTap,
-  });
-
-  /// Uniquely identifies a [Polygon].
-  final PolygonId polygonId;
-
-  /// True if the [Polygon] consumes tap events.
-  ///
-  /// If this is false, [onTap] callback will not be triggered.
-  final bool consumeTapEvents;
-
-  /// Fill color in ARGB format, the same format used by Color. The default value is black (0xff000000).
-  final Color fillColor;
-
-  /// Indicates whether the segments of the polygon should be drawn as geodesics, as opposed to straight lines
-  /// on the Mercator projection.
-  ///
-  /// A geodesic is the shortest path between two points on the Earth's surface.
-  /// The geodesic curve is constructed assuming the Earth is a sphere
-  final bool geodesic;
-
-  /// The vertices of the polygon to be drawn.
-  ///
-  /// Line segments are drawn between consecutive points. A polygon is not closed by
-  /// default; to form a closed polygon, the start and end points must be the same.
-  final List<LatLng> points;
-
-  /// True if the marker is visible.
-  final bool visible;
-
-  /// Line color in ARGB format, the same format used by Color. The default value is black (0xff000000).
-  final Color strokeColor;
-
-  /// Width of the polygon, used to define the width of the line to be drawn.
-  ///
-  /// The width is constant and independent of the camera's zoom level.
-  /// The default value is 10.
-  final int strokeWidth;
-
-  /// The z-index of the polygon, used to determine relative drawing order of
-  /// map overlays.
-  ///
-  /// Overlays are drawn in order of z-index, so that lower values means drawn
-  /// earlier, and thus appearing to be closer to the surface of the Earth.
-  final int zIndex;
-
-  /// Callbacks to receive tap events for polygon placed on this map.
-  final VoidCallback onTap;
-
-  /// Creates a new [Polygon] object whose values are the same as this instance,
-  /// unless overwritten by the specified parameters.
-  Polygon copyWith({
-    bool consumeTapEventsParam,
-    Color fillColorParam,
-    bool geodesicParam,
-    List<LatLng> pointsParam,
-    Color strokeColorParam,
-    int strokeWidthParam,
-    bool visibleParam,
-    int zIndexParam,
-    VoidCallback onTapParam,
-  }) {
-    return Polygon(
-      polygonId: polygonId,
-      consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents,
-      fillColor: fillColorParam ?? fillColor,
-      geodesic: geodesicParam ?? geodesic,
-      points: pointsParam ?? points,
-      strokeColor: strokeColorParam ?? strokeColor,
-      strokeWidth: strokeWidthParam ?? strokeWidth,
-      visible: visibleParam ?? visible,
-      onTap: onTapParam ?? onTap,
-      zIndex: zIndexParam ?? zIndex,
-    );
-  }
-
-  /// Creates a new [Polygon] object whose values are the same as this instance.
-  Polygon clone() {
-    return copyWith(pointsParam: List<LatLng>.of(points));
-  }
-
-  dynamic _toJson() {
-    final Map<String, dynamic> json = <String, dynamic>{};
-
-    void addIfPresent(String fieldName, dynamic value) {
-      if (value != null) {
-        json[fieldName] = value;
-      }
-    }
-
-    addIfPresent('polygonId', polygonId.value);
-    addIfPresent('consumeTapEvents', consumeTapEvents);
-    addIfPresent('fillColor', fillColor.value);
-    addIfPresent('geodesic', geodesic);
-    addIfPresent('strokeColor', strokeColor.value);
-    addIfPresent('strokeWidth', strokeWidth);
-    addIfPresent('visible', visible);
-    addIfPresent('zIndex', zIndex);
-
-    if (points != null) {
-      json['points'] = _pointsToJson();
-    }
-
-    return json;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Polygon typedOther = other;
-    return polygonId == typedOther.polygonId &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        fillColor == typedOther.fillColor &&
-        geodesic == typedOther.geodesic &&
-        listEquals(points, typedOther.points) &&
-        visible == typedOther.visible &&
-        strokeColor == typedOther.strokeColor &&
-        strokeWidth == typedOther.strokeWidth &&
-        zIndex == typedOther.zIndex;
-  }
-
-  @override
-  int get hashCode => polygonId.hashCode;
-
-  dynamic _pointsToJson() {
-    final List<dynamic> result = <dynamic>[];
-    for (final LatLng point in points) {
-      result.add(point._toJson());
-    }
-    return result;
-  }
-}
-
-Map<PolygonId, Polygon> _keyByPolygonId(Iterable<Polygon> polygons) {
-  if (polygons == null) {
-    return <PolygonId, Polygon>{};
-  }
-  return Map<PolygonId, Polygon>.fromEntries(polygons.map((Polygon polygon) =>
-      MapEntry<PolygonId, Polygon>(polygon.polygonId, polygon.clone())));
-}
-
-List<Map<String, dynamic>> _serializePolygonSet(Set<Polygon> polygons) {
-  if (polygons == null) {
-    return null;
-  }
-  return polygons
-      .map<Map<String, dynamic>>((Polygon p) => p._toJson())
-      .toList();
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/polygon_updates.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/polygon_updates.dart
deleted file mode 100644
index 5a14c6b..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/polygon_updates.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// [Polygon] update events to be applied to the [GoogleMap].
-///
-/// Used in [GoogleMapController] when the map is updated.
-class _PolygonUpdates {
-  /// Computes [_PolygonUpdates] given previous and current [Polygon]s.
-  _PolygonUpdates.from(Set<Polygon> previous, Set<Polygon> current) {
-    if (previous == null) {
-      previous = Set<Polygon>.identity();
-    }
-
-    if (current == null) {
-      current = Set<Polygon>.identity();
-    }
-
-    final Map<PolygonId, Polygon> previousPolygons = _keyByPolygonId(previous);
-    final Map<PolygonId, Polygon> currentPolygons = _keyByPolygonId(current);
-
-    final Set<PolygonId> prevPolygonIds = previousPolygons.keys.toSet();
-    final Set<PolygonId> currentPolygonIds = currentPolygons.keys.toSet();
-
-    Polygon idToCurrentPolygon(PolygonId id) {
-      return currentPolygons[id];
-    }
-
-    final Set<PolygonId> _polygonIdsToRemove =
-        prevPolygonIds.difference(currentPolygonIds);
-
-    final Set<Polygon> _polygonsToAdd = currentPolygonIds
-        .difference(prevPolygonIds)
-        .map(idToCurrentPolygon)
-        .toSet();
-
-    /// Returns `true` if [current] is not equals to previous one with the
-    /// same id.
-    bool hasChanged(Polygon current) {
-      final Polygon previous = previousPolygons[current.polygonId];
-      return current != previous;
-    }
-
-    final Set<Polygon> _polygonsToChange = currentPolygonIds
-        .intersection(prevPolygonIds)
-        .map(idToCurrentPolygon)
-        .where(hasChanged)
-        .toSet();
-
-    polygonsToAdd = _polygonsToAdd;
-    polygonIdsToRemove = _polygonIdsToRemove;
-    polygonsToChange = _polygonsToChange;
-  }
-
-  Set<Polygon> polygonsToAdd;
-  Set<PolygonId> polygonIdsToRemove;
-  Set<Polygon> polygonsToChange;
-
-  Map<String, dynamic> _toMap() {
-    final Map<String, dynamic> updateMap = <String, dynamic>{};
-
-    void addIfNonNull(String fieldName, dynamic value) {
-      if (value != null) {
-        updateMap[fieldName] = value;
-      }
-    }
-
-    addIfNonNull('polygonsToAdd', _serializePolygonSet(polygonsToAdd));
-    addIfNonNull('polygonsToChange', _serializePolygonSet(polygonsToChange));
-    addIfNonNull('polygonIdsToRemove',
-        polygonIdsToRemove.map<dynamic>((PolygonId m) => m.value).toList());
-
-    return updateMap;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final _PolygonUpdates typedOther = other;
-    return setEquals(polygonsToAdd, typedOther.polygonsToAdd) &&
-        setEquals(polygonIdsToRemove, typedOther.polygonIdsToRemove) &&
-        setEquals(polygonsToChange, typedOther.polygonsToChange);
-  }
-
-  @override
-  int get hashCode =>
-      hashValues(polygonsToAdd, polygonIdsToRemove, polygonsToChange);
-
-  @override
-  String toString() {
-    return '_PolygonUpdates{polygonsToAdd: $polygonsToAdd, '
-        'polygonIdsToRemove: $polygonIdsToRemove, '
-        'polygonsToChange: $polygonsToChange}';
-  }
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/polyline.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/polyline.dart
deleted file mode 100644
index c27b19e..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/polyline.dart
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Uniquely identifies a [Polyline] among [GoogleMap] polylines.
-///
-/// This does not have to be globally unique, only unique among the list.
-@immutable
-class PolylineId {
-  /// Creates an immutable object representing a [PolylineId] among [GoogleMap] polylines.
-  ///
-  /// An [AssertionError] will be thrown if [value] is null.
-  PolylineId(this.value) : assert(value != null);
-
-  /// value of the [PolylineId].
-  final String value;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final PolylineId typedOther = other;
-    return value == typedOther.value;
-  }
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  String toString() {
-    return 'PolylineId{value: $value}';
-  }
-}
-
-/// Draws a line through geographical locations on the map.
-@immutable
-class Polyline {
-  /// Creates an immutable object representing a line drawn through geographical locations on the map.
-  const Polyline({
-    @required this.polylineId,
-    this.consumeTapEvents = false,
-    this.color = Colors.black,
-    this.endCap = Cap.buttCap,
-    this.geodesic = false,
-    this.jointType = JointType.mitered,
-    this.points = const <LatLng>[],
-    this.patterns = const <PatternItem>[],
-    this.startCap = Cap.buttCap,
-    this.visible = true,
-    this.width = 10,
-    this.zIndex = 0,
-    this.onTap,
-  });
-
-  /// Uniquely identifies a [Polyline].
-  final PolylineId polylineId;
-
-  /// True if the [Polyline] consumes tap events.
-  ///
-  /// If this is false, [onTap] callback will not be triggered.
-  final bool consumeTapEvents;
-
-  /// Line segment color in ARGB format, the same format used by Color. The default value is black (0xff000000).
-  final Color color;
-
-  /// Indicates whether the segments of the polyline should be drawn as geodesics, as opposed to straight lines
-  /// on the Mercator projection.
-  ///
-  /// A geodesic is the shortest path between two points on the Earth's surface.
-  /// The geodesic curve is constructed assuming the Earth is a sphere
-  final bool geodesic;
-
-  /// Joint type of the polyline line segments.
-  ///
-  /// The joint type defines the shape to be used when joining adjacent line segments at all vertices of the
-  /// polyline except the start and end vertices. See [JointType] for supported joint types. The default value is
-  /// mitered.
-  ///
-  /// Supported on Android only.
-  final JointType jointType;
-
-  /// The stroke pattern for the polyline.
-  ///
-  /// Solid or a sequence of PatternItem objects to be repeated along the line.
-  /// Available PatternItem types: Gap (defined by gap length in pixels), Dash (defined by line width and dash
-  /// length in pixels) and Dot (circular, centered on the line, diameter defined by line width in pixels).
-  final List<PatternItem> patterns;
-
-  /// The vertices of the polyline to be drawn.
-  ///
-  /// Line segments are drawn between consecutive points. A polyline is not closed by
-  /// default; to form a closed polyline, the start and end points must be the same.
-  final List<LatLng> points;
-
-  /// The cap at the start vertex of the polyline.
-  ///
-  /// The default start cap is ButtCap.
-  ///
-  /// Supported on Android only.
-  final Cap startCap;
-
-  /// The cap at the end vertex of the polyline.
-  ///
-  /// The default end cap is ButtCap.
-  ///
-  /// Supported on Android only.
-  final Cap endCap;
-
-  /// True if the marker is visible.
-  final bool visible;
-
-  /// Width of the polyline, used to define the width of the line segment to be drawn.
-  ///
-  /// The width is constant and independent of the camera's zoom level.
-  /// The default value is 10.
-  final int width;
-
-  /// The z-index of the polyline, used to determine relative drawing order of
-  /// map overlays.
-  ///
-  /// Overlays are drawn in order of z-index, so that lower values means drawn
-  /// earlier, and thus appearing to be closer to the surface of the Earth.
-  final int zIndex;
-
-  /// Callbacks to receive tap events for polyline placed on this map.
-  final VoidCallback onTap;
-
-  /// Creates a new [Polyline] object whose values are the same as this instance,
-  /// unless overwritten by the specified parameters.
-  Polyline copyWith({
-    Color colorParam,
-    bool consumeTapEventsParam,
-    Cap endCapParam,
-    bool geodesicParam,
-    JointType jointTypeParam,
-    List<PatternItem> patternsParam,
-    List<LatLng> pointsParam,
-    Cap startCapParam,
-    bool visibleParam,
-    int widthParam,
-    int zIndexParam,
-    VoidCallback onTapParam,
-  }) {
-    return Polyline(
-      polylineId: polylineId,
-      color: colorParam ?? color,
-      consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents,
-      endCap: endCapParam ?? endCap,
-      geodesic: geodesicParam ?? geodesic,
-      jointType: jointTypeParam ?? jointType,
-      patterns: patternsParam ?? patterns,
-      points: pointsParam ?? points,
-      startCap: startCapParam ?? startCap,
-      visible: visibleParam ?? visible,
-      width: widthParam ?? width,
-      onTap: onTapParam ?? onTap,
-      zIndex: zIndexParam ?? zIndex,
-    );
-  }
-
-  /// Creates a new [Polyline] object whose values are the same as this
-  /// instance.
-  Polyline clone() {
-    return copyWith(
-      patternsParam: List<PatternItem>.of(patterns),
-      pointsParam: List<LatLng>.of(points),
-    );
-  }
-
-  dynamic _toJson() {
-    final Map<String, dynamic> json = <String, dynamic>{};
-
-    void addIfPresent(String fieldName, dynamic value) {
-      if (value != null) {
-        json[fieldName] = value;
-      }
-    }
-
-    addIfPresent('polylineId', polylineId.value);
-    addIfPresent('consumeTapEvents', consumeTapEvents);
-    addIfPresent('color', color.value);
-    addIfPresent('endCap', endCap?._toJson());
-    addIfPresent('geodesic', geodesic);
-    addIfPresent('jointType', jointType?.value);
-    addIfPresent('startCap', startCap?._toJson());
-    addIfPresent('visible', visible);
-    addIfPresent('width', width);
-    addIfPresent('zIndex', zIndex);
-
-    if (points != null) {
-      json['points'] = _pointsToJson();
-    }
-
-    if (patterns != null) {
-      json['pattern'] = _patternToJson();
-    }
-
-    return json;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Polyline typedOther = other;
-    return polylineId == typedOther.polylineId &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        color == typedOther.color &&
-        geodesic == typedOther.geodesic &&
-        jointType == typedOther.jointType &&
-        listEquals(patterns, typedOther.patterns) &&
-        listEquals(points, typedOther.points) &&
-        startCap == typedOther.startCap &&
-        endCap == typedOther.endCap &&
-        visible == typedOther.visible &&
-        width == typedOther.width &&
-        zIndex == typedOther.zIndex;
-  }
-
-  @override
-  int get hashCode => polylineId.hashCode;
-
-  dynamic _pointsToJson() {
-    final List<dynamic> result = <dynamic>[];
-    for (final LatLng point in points) {
-      result.add(point._toJson());
-    }
-    return result;
-  }
-
-  dynamic _patternToJson() {
-    final List<dynamic> result = <dynamic>[];
-    for (final PatternItem patternItem in patterns) {
-      if (patternItem != null) {
-        result.add(patternItem._toJson());
-      }
-    }
-    return result;
-  }
-}
-
-Map<PolylineId, Polyline> _keyByPolylineId(Iterable<Polyline> polylines) {
-  if (polylines == null) {
-    return <PolylineId, Polyline>{};
-  }
-  return Map<PolylineId, Polyline>.fromEntries(polylines.map(
-      (Polyline polyline) => MapEntry<PolylineId, Polyline>(
-          polyline.polylineId, polyline.clone())));
-}
-
-List<Map<String, dynamic>> _serializePolylineSet(Set<Polyline> polylines) {
-  if (polylines == null) {
-    return null;
-  }
-  return polylines
-      .map<Map<String, dynamic>>((Polyline p) => p._toJson())
-      .toList();
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/polyline_updates.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/polyline_updates.dart
deleted file mode 100644
index ed972a5..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/polyline_updates.dart
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// [Polyline] update events to be applied to the [GoogleMap].
-///
-/// Used in [GoogleMapController] when the map is updated.
-class _PolylineUpdates {
-  /// Computes [_PolylineUpdates] given previous and current [Polyline]s.
-  _PolylineUpdates.from(Set<Polyline> previous, Set<Polyline> current) {
-    if (previous == null) {
-      previous = Set<Polyline>.identity();
-    }
-
-    if (current == null) {
-      current = Set<Polyline>.identity();
-    }
-
-    final Map<PolylineId, Polyline> previousPolylines =
-        _keyByPolylineId(previous);
-    final Map<PolylineId, Polyline> currentPolylines =
-        _keyByPolylineId(current);
-
-    final Set<PolylineId> prevPolylineIds = previousPolylines.keys.toSet();
-    final Set<PolylineId> currentPolylineIds = currentPolylines.keys.toSet();
-
-    Polyline idToCurrentPolyline(PolylineId id) {
-      return currentPolylines[id];
-    }
-
-    final Set<PolylineId> _polylineIdsToRemove =
-        prevPolylineIds.difference(currentPolylineIds);
-
-    final Set<Polyline> _polylinesToAdd = currentPolylineIds
-        .difference(prevPolylineIds)
-        .map(idToCurrentPolyline)
-        .toSet();
-
-    /// Returns `true` if [current] is not equals to previous one with the
-    /// same id.
-    bool hasChanged(Polyline current) {
-      final Polyline previous = previousPolylines[current.polylineId];
-      return current != previous;
-    }
-
-    final Set<Polyline> _polylinesToChange = currentPolylineIds
-        .intersection(prevPolylineIds)
-        .map(idToCurrentPolyline)
-        .where(hasChanged)
-        .toSet();
-
-    polylinesToAdd = _polylinesToAdd;
-    polylineIdsToRemove = _polylineIdsToRemove;
-    polylinesToChange = _polylinesToChange;
-  }
-
-  Set<Polyline> polylinesToAdd;
-  Set<PolylineId> polylineIdsToRemove;
-  Set<Polyline> polylinesToChange;
-
-  Map<String, dynamic> _toMap() {
-    final Map<String, dynamic> updateMap = <String, dynamic>{};
-
-    void addIfNonNull(String fieldName, dynamic value) {
-      if (value != null) {
-        updateMap[fieldName] = value;
-      }
-    }
-
-    addIfNonNull('polylinesToAdd', _serializePolylineSet(polylinesToAdd));
-    addIfNonNull('polylinesToChange', _serializePolylineSet(polylinesToChange));
-    addIfNonNull('polylineIdsToRemove',
-        polylineIdsToRemove.map<dynamic>((PolylineId m) => m.value).toList());
-
-    return updateMap;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final _PolylineUpdates typedOther = other;
-    return setEquals(polylinesToAdd, typedOther.polylinesToAdd) &&
-        setEquals(polylineIdsToRemove, typedOther.polylineIdsToRemove) &&
-        setEquals(polylinesToChange, typedOther.polylinesToChange);
-  }
-
-  @override
-  int get hashCode =>
-      hashValues(polylinesToAdd, polylineIdsToRemove, polylinesToChange);
-
-  @override
-  String toString() {
-    return '_PolylineUpdates{polylinesToAdd: $polylinesToAdd, '
-        'polylineIdsToRemove: $polylineIdsToRemove, '
-        'polylinesToChange: $polylinesToChange}';
-  }
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/screen_coordinate.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/screen_coordinate.dart
deleted file mode 100644
index e58abe9..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/screen_coordinate.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Represents a point coordinate in the [GoogleMap]'s view.
-///
-/// The screen location is specified in screen pixels (not display pixels) relative
-/// to the top left of the map, not top left of the whole screen. (x, y) = (0, 0)
-/// corresponds to top-left of the [GoogleMap] not the whole screen.
-@immutable
-class ScreenCoordinate {
-  /// Creates an immutable representation of a point coordinate in the [GoogleMap]'s view.
-  const ScreenCoordinate({
-    @required this.x,
-    @required this.y,
-  });
-
-  /// Represents the number of pixels from the left of the [GoogleMap].
-  final int x;
-
-  /// Represents the number of pixels from the top of the [GoogleMap].
-  final int y;
-
-  dynamic _toJson() {
-    return <String, int>{
-      "x": x,
-      "y": y,
-    };
-  }
-
-  @override
-  String toString() => '$runtimeType($x, $y)';
-
-  @override
-  bool operator ==(Object o) {
-    return o is ScreenCoordinate && o.x == x && o.y == y;
-  }
-
-  @override
-  int get hashCode => hashValues(x, y);
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/ui.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/ui.dart
deleted file mode 100644
index 4b57ebd..0000000
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/ui.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of google_maps_flutter;
-
-/// Type of map tiles to display.
-// Enum constants must be indexed to match the corresponding int constants of
-// the Android platform API, see
-// <https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.html#MAP_TYPE_NORMAL>
-enum MapType {
-  /// Do not display map tiles.
-  none,
-
-  /// Normal tiles (traffic and labels, subtle terrain information).
-  normal,
-
-  /// Satellite imaging tiles (aerial photos)
-  satellite,
-
-  /// Terrain tiles (indicates type and height of terrain)
-  terrain,
-
-  /// Hybrid tiles (satellite images with some labels/overlays)
-  hybrid,
-}
-
-/// Bounds for the map camera target.
-// Used with [GoogleMapOptions] to wrap a [LatLngBounds] value. This allows
-// distinguishing between specifying an unbounded target (null `LatLngBounds`)
-// from not specifying anything (null `CameraTargetBounds`).
-class CameraTargetBounds {
-  /// Creates a camera target bounds with the specified bounding box, or null
-  /// to indicate that the camera target is not bounded.
-  const CameraTargetBounds(this.bounds);
-
-  /// The geographical bounding box for the map camera target.
-  ///
-  /// A null value means the camera target is unbounded.
-  final LatLngBounds bounds;
-
-  /// Unbounded camera target.
-  static const CameraTargetBounds unbounded = CameraTargetBounds(null);
-
-  dynamic _toJson() => <dynamic>[bounds?._toList()];
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(this, other)) return true;
-    if (runtimeType != other.runtimeType) return false;
-    final CameraTargetBounds typedOther = other;
-    return bounds == typedOther.bounds;
-  }
-
-  @override
-  int get hashCode => bounds.hashCode;
-
-  @override
-  String toString() {
-    return 'CameraTargetBounds(bounds: $bounds)';
-  }
-}
-
-/// Preferred bounds for map camera zoom level.
-// Used with [GoogleMapOptions] to wrap min and max zoom. This allows
-// distinguishing between specifying unbounded zooming (null `minZoom` and
-// `maxZoom`) from not specifying anything (null `MinMaxZoomPreference`).
-class MinMaxZoomPreference {
-  /// Creates a immutable representation of the preferred minimum and maximum zoom values for the map camera.
-  ///
-  /// [AssertionError] will be thrown if [minZoom] > [maxZoom].
-  const MinMaxZoomPreference(this.minZoom, this.maxZoom)
-      : assert(minZoom == null || maxZoom == null || minZoom <= maxZoom);
-
-  /// The preferred minimum zoom level or null, if unbounded from below.
-  final double minZoom;
-
-  /// The preferred maximum zoom level or null, if unbounded from above.
-  final double maxZoom;
-
-  /// Unbounded zooming.
-  static const MinMaxZoomPreference unbounded =
-      MinMaxZoomPreference(null, null);
-
-  dynamic _toJson() => <dynamic>[minZoom, maxZoom];
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(this, other)) return true;
-    if (runtimeType != other.runtimeType) return false;
-    final MinMaxZoomPreference typedOther = other;
-    return minZoom == typedOther.minZoom && maxZoom == typedOther.maxZoom;
-  }
-
-  @override
-  int get hashCode => hashValues(minZoom, maxZoom);
-
-  @override
-  String toString() {
-    return 'MinMaxZoomPreference(minZoom: $minZoom, maxZoom: $maxZoom)';
-  }
-}
-
-/// Exception when a map style is invalid or was unable to be set.
-///
-/// See also: `setStyle` on [GoogleMapController] for why this exception
-/// might be thrown.
-class MapStyleException implements Exception {
-  /// Default constructor for [MapStyleException].
-  const MapStyleException(this.cause);
-
-  /// The reason `GoogleMapController.setStyle` would throw this exception.
-  final String cause;
-}
diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
index 7831934..89fd66a 100644
--- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
@@ -1,12 +1,13 @@
 name: google_maps_flutter
 description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
 homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
-version: 0.5.26+4
+version: 0.5.27
 
 dependencies:
   flutter:
     sdk: flutter
   flutter_plugin_android_lifecycle: ^1.0.0
+  google_maps_flutter_platform_interface: ^1.0.1
 
 dev_dependencies:
   flutter_test:
@@ -27,6 +28,8 @@
         pluginClass: GoogleMapsPlugin
       ios:
         pluginClass: FLTGoogleMapsPlugin
+      web:
+        default_package: google_maps_flutter_web
 
 environment:
   sdk: ">=2.0.0-dev.47.0 <3.0.0"