Make it possible to depend on groups
diff --git a/lib/src/process_pool.dart b/lib/src/process_pool.dart
index f0c5599..ada6658 100644
--- a/lib/src/process_pool.dart
+++ b/lib/src/process_pool.dart
@@ -135,7 +135,8 @@
     this.workers, {
     this.name = '<unknown>',
     bool setDependencies = true,
-  }) : assert(workers.isNotEmpty) {
+  })  : dependsOn = workers.toSet(),
+        assert(workers.isNotEmpty) {
     // Make sure they run in series.
     if (setDependencies) {
       for (int i = 1; i < workers.length; i++) {
@@ -147,12 +148,11 @@
   @override
   final String name;
 
-  // The workers that will run in order because
-  // They depend on each other.
+  /// The workers that will run in order because They depend on each other.
   final List<DependentJob> workers;
 
   @override
-  Set<DependentJob> get dependsOn => workers.toSet();
+  final Set<DependentJob> dependsOn;
 
   @override
   void addToQueue(List<DependentJob> jobs) {
diff --git a/test/src/process_pool_test.dart b/test/src/process_pool_test.dart
index b552d64..5bbf9f3 100644
--- a/test/src/process_pool_test.dart
+++ b/test/src/process_pool_test.dart
@@ -172,4 +172,80 @@
       unorderedEquals(<String>['job A3', 'job B3']),
     );
   });
+  test('Commands in task groups can depend on other groups', () async {
+    fakeProcessManager = FakeProcessManager((String value) {});
+    processRunner = ProcessRunner(processManager: fakeProcessManager);
+    processPool = ProcessPool(processRunner: processRunner, printReport: null);
+    final Map<FakeInvocationRecord, List<ProcessResult>> calls = <FakeInvocationRecord, List<ProcessResult>>{
+      FakeInvocationRecord(<String>['commandA1', 'arg1', 'arg2'], testPath): <ProcessResult>[
+        ProcessResult(0, 0, 'outputA1', 'stderrA1'),
+      ],
+      FakeInvocationRecord(<String>['commandB1', 'arg1', 'arg2'], testPath): <ProcessResult>[
+        ProcessResult(0, 0, 'outputB1', 'stderrB1'),
+      ],
+      FakeInvocationRecord(<String>['commandA2', 'arg1', 'arg2'], testPath): <ProcessResult>[
+        ProcessResult(0, 0, 'outputA2', 'stderrA2'),
+      ],
+      FakeInvocationRecord(<String>['commandB2', 'arg1', 'arg2'], testPath): <ProcessResult>[
+        ProcessResult(0, -1, 'outputB2', 'stderrB2'),
+      ],
+      FakeInvocationRecord(<String>['commandA3', 'arg1', 'arg2'], testPath): <ProcessResult>[
+        ProcessResult(0, 0, 'outputA3', 'stderrA3'),
+      ],
+      FakeInvocationRecord(<String>['commandB3', 'arg1', 'arg2'], testPath): <ProcessResult>[
+        ProcessResult(0, 0, 'outputB3', 'stderrB3'),
+      ],
+    };
+    fakeProcessManager.fakeResults = calls;
+    final WorkerJobGroup groupA = WorkerJobGroup(
+      <WorkerJob>[
+        WorkerJob(<String>['commandA1', 'arg1', 'arg2'], name: 'job A1'),
+        WorkerJob(<String>['commandA2', 'arg1', 'arg2'], name: 'job A2'),
+        WorkerJob(<String>['commandA3', 'arg1', 'arg2'], name: 'job A3'),
+      ],
+      name: 'Group A',
+    );
+    final WorkerJobGroup groupB = WorkerJobGroup(
+      <WorkerJob>[
+        WorkerJob(<String>['commandB1', 'arg1', 'arg2'], name: 'job B1'),
+        WorkerJob(<String>['commandB2', 'arg1', 'arg2'], name: 'job B2'),
+        WorkerJob(<String>['commandB3', 'arg1', 'arg2'], name: 'job B3'),
+      ],
+      name: 'Group B',
+    );
+    groupB.dependsOn.add(groupA);
+    final List<DependentJob> jobs = <DependentJob>[groupA, groupB];
+    final List<WorkerJob> completed = await processPool.runToCompletion(jobs);
+    expect(completed.length, equals(6));
+    // Make sure they executed in the correct order.
+    expect(completed.map<String>((WorkerJob job) => job.name),
+        equals(<String>['job A1', 'job A2', 'job A3', 'job B1', 'job B2', 'job B3']));
+    // Command B2 failed with -1, so B3 should also fail.
+    expect(
+      completed.where((WorkerJob job) => job.result.exitCode != 0).map((WorkerJob job) => job.name),
+      unorderedEquals(<String>['job B2', 'job B3']),
+    );
+    expect(
+      completed.where((WorkerJob job) => job.exception == null).map((WorkerJob job) => job.name),
+      unorderedEquals(<String>['job A1', 'job B1', 'job A2', 'job A3']),
+    );
+    expect(
+      completed.where((WorkerJob job) => job.result.exitCode == 0).map((WorkerJob job) => job.name),
+      unorderedEquals(<String>['job B1', 'job A1', 'job A2', 'job A3']),
+    );
+    // Either group A or B can come first, but the individual group tasks should
+    // be in order.
+    expect(
+      <String>[completed[0].name, completed[1].name],
+      unorderedEquals(<String>['job A1', 'job B1']),
+    );
+    expect(
+      <String>[completed[2].name, completed[3].name],
+      unorderedEquals(<String>['job A2', 'job B2']),
+    );
+    expect(
+      <String>[completed[4].name, completed[5].name],
+      unorderedEquals(<String>['job A3', 'job B3']),
+    );
+  });
 }