HostedDependency: support host data
diff --git a/pkgs/pubspec_parse/lib/src/dependency.dart b/pkgs/pubspec_parse/lib/src/dependency.dart
index 8488fe1..a66c9c4 100644
--- a/pkgs/pubspec_parse/lib/src/dependency.dart
+++ b/pkgs/pubspec_parse/lib/src/dependency.dart
@@ -154,12 +154,12 @@
 
 @JsonSerializable(createToJson: false)
 class HostedDependency extends Dependency {
-  // TODO: support explicit host
-
   @JsonKey(fromJson: _constraintFromString)
   final VersionConstraint version;
 
-  HostedDependency({VersionConstraint version})
+  final HostedDetails hosted;
+
+  HostedDependency({VersionConstraint version, this.hosted})
       : this.version = version ?? VersionConstraint.any,
         super._();
 
@@ -179,5 +179,24 @@
   String get _info => version.toString();
 }
 
+@JsonSerializable(createToJson: false, nullable: false)
+class HostedDetails {
+  final String name;
+
+  @JsonKey(fromJson: _parseUri)
+  final Uri url;
+
+  HostedDetails(this.name, this.url) {
+    if (name == null) {
+      throw new ArgumentError.value(name, 'name', '"name" cannot be null');
+    }
+    if (url == null) {
+      throw new ArgumentError.value(url, 'url', '"url" cannot be null');
+    }
+  }
+
+  factory HostedDetails.fromJson(Map json) => _$HostedDetailsFromJson(json);
+}
+
 VersionConstraint _constraintFromString(String input) =>
     new VersionConstraint.parse(input);
diff --git a/pkgs/pubspec_parse/lib/src/dependency.g.dart b/pkgs/pubspec_parse/lib/src/dependency.g.dart
index 794200b..f3dc23d 100644
--- a/pkgs/pubspec_parse/lib/src/dependency.g.dart
+++ b/pkgs/pubspec_parse/lib/src/dependency.g.dart
@@ -35,7 +35,18 @@
   return $checkedNew('HostedDependency', json, () {
     var val = new HostedDependency(
         version: $checkedConvert(json, 'version',
-            (v) => v == null ? null : _constraintFromString(v as String)));
+            (v) => v == null ? null : _constraintFromString(v as String)),
+        hosted: $checkedConvert(json, 'hosted',
+            (v) => v == null ? null : new HostedDetails.fromJson(v as Map)));
+    return val;
+  });
+}
+
+HostedDetails _$HostedDetailsFromJson(Map json) {
+  return $checkedNew('HostedDetails', json, () {
+    var val = new HostedDetails(
+        $checkedConvert(json, 'name', (v) => v as String),
+        $checkedConvert(json, 'url', (v) => _parseUri(v as String)));
     return val;
   });
 }
diff --git a/pkgs/pubspec_parse/test/dependency_test.dart b/pkgs/pubspec_parse/test/dependency_test.dart
index b8544d8..9a42a64 100644
--- a/pkgs/pubspec_parse/test/dependency_test.dart
+++ b/pkgs/pubspec_parse/test/dependency_test.dart
@@ -48,18 +48,32 @@
   test('HostedDepedency - null', () {
     var dep = _dependency<HostedDependency>(null);
     expect(dep.version.toString(), 'any');
+    expect(dep.hosted, isNull);
     expect(dep.toString(), 'HostedDependency: any');
   });
 
   test('HostedDepedency - string', () {
     var dep = _dependency<HostedDependency>('^1.0.0');
     expect(dep.version.toString(), '^1.0.0');
+    expect(dep.hosted, isNull);
     expect(dep.toString(), 'HostedDependency: ^1.0.0');
   });
 
   test('HostedDepedency - map', () {
     var dep = _dependency<HostedDependency>({'version': '^1.0.0'});
     expect(dep.version.toString(), '^1.0.0');
+    expect(dep.hosted, isNull);
+    expect(dep.toString(), 'HostedDependency: ^1.0.0');
+  });
+
+  test('HostedDepedency - map', () {
+    var dep = _dependency<HostedDependency>({
+      'version': '^1.0.0',
+      'hosted': {'name': 'hosted_name', 'url': 'hosted_url'}
+    });
+    expect(dep.version.toString(), '^1.0.0');
+    expect(dep.hosted.name, 'hosted_name');
+    expect(dep.hosted.url.toString(), 'hosted_url');
     expect(dep.toString(), 'HostedDependency: ^1.0.0');
   });
 }