Updated project structure to get credit for having an example

Also moved the non-public libraries into a src directory to hide them,
and updated some documentation in the example.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f6775b2..aafbdf1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Change Log for `process_runner`
 
+## 2.0.1
+
+* Modified the package structure to get credit for having an example
+* Moved sub-libraries into lib/src directory to hide them from dartdoc.
+* Updated example documentation.
+
 ## 2.0.0
 
 * Breaking change to modify the stderr, stdout, and output members of
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 10d58ab..0c9a12a 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -11,6 +11,10 @@
 # See the configuration guide for more
 # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
 
+# Too many false positives: pedantic enforces "omit_local_variable_types", and
+# we don't.
+# include: package:pedantic/analysis_options.yaml
+
 analyzer:
   strong-mode:
     implicit-casts: false
@@ -29,12 +33,6 @@
     # Stream and not importing dart:async
     # Please see https://github.com/flutter/flutter/pull/24528 for details.
     sdk_version_async_exported_from_core: ignore
-  exclude:
-    - "bin/cache/**"
-    # the following two are relative to the stocks example and the flutter package respectively
-    # see https://github.com/dart-lang/sdk/issues/28463
-    - "lib/i18n/messages_*.dart"
-    - "lib/src/http/**"
   enable-experiment:
     - non-nullable
 
@@ -104,7 +102,7 @@
     - flutter_style_todos
     - hash_and_equals
     - implementation_imports
-    # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
+    - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
     - iterable_contains_unrelated_type
     # - join_return_with_assignment # not yet tested
     - library_names
@@ -120,7 +118,7 @@
     - non_constant_identifier_names
     # - null_closures  # not yet tested
     # - omit_local_variable_types # opposite of always_specify_types
-    # - one_member_abstracts # too many false positives
+    - one_member_abstracts # too many false positives
     # - only_throw_errors # https://github.com/flutter/flutter/issues/5792
     - overridden_fields
     - package_api_docs
@@ -177,13 +175,13 @@
     - throw_in_finally
     # - type_annotate_public_apis # subset of always_specify_types
     - type_init_formals
-    # - unawaited_futures # too many false positives
+    - unawaited_futures
     # - unnecessary_await_in_return # not yet tested
     - unnecessary_brace_in_string_interps
     - unnecessary_const
     # - unnecessary_final # conflicts with prefer_final_locals
     - unnecessary_getters_setters
-    # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
+    - unnecessary_lambdas
     - unnecessary_new
     - unnecessary_null_aware_assignments
     - unnecessary_null_in_if_null_operators
@@ -199,7 +197,7 @@
     # - use_key_in_widget_constructors # not yet tested
     - use_rethrow_when_possible
     # - use_setters_to_change_properties # not yet tested
-    # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
-    # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
+    - use_string_buffers
+    - use_to_and_as_if_applicable
     - valid_regexps
     - void_checks
diff --git a/example/bin/main.dart b/example/main.dart
similarity index 65%
rename from example/bin/main.dart
rename to example/main.dart
index 45100d8..0172923 100644
--- a/example/bin/main.dart
+++ b/example/main.dart
@@ -2,6 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// This example shows how to send a bunch of jobs to ProcessPool for processing.
+//
+// This example program is actually pretty useful even if you don't use
+// process_runner for your Dart project. It can speed up processing of a bunch
+// of single-threaded CPU-intensive commands by a multple of the number of
+// processor cores you have (modulo being disk/network bound, of course).
+
 import 'dart:io';
 
 import 'package:args/args.dart';
@@ -74,55 +81,72 @@
   parser.addFlag('help', help: 'Print help.');
   parser.addFlag('report', help: 'Print progress on the jobs while running.', defaultsTo: false);
   parser.addOption('workers',
+      abbr: 'w',
       help: 'Specify the number of workers jobs to run simultanously. Defaults '
           'to the number of processors on the machine.');
   parser.addOption('workingDirectory',
-      help: 'Specify the working directory to run on', defaultsTo: '.');
+      abbr: 'd', help: 'Specify the working directory to run on', defaultsTo: '.');
   parser.addMultiOption('cmd',
+      abbr: 'c',
       help: 'Specify a command to add to the commands to be run. Entire '
           'command must be quoted by the shell. Commands specified with this '
           'option run before those specified with --cmdFile');
-  parser.addOption('cmdFile',
+  parser.addOption('file',
+      abbr: 'f',
       help: 'Specify the name of a file to read commands from, one per line, as '
           'they would appear on the command line, with spaces escaped or '
-          'quoted. Specify "-" to read from stdin.');
-  final ArgResults flags = parser.parse(args);
+          'quoted. Specify "-" to read from stdin.',
+      defaultsTo: '-');
+  final ArgResults options = parser.parse(args);
 
-  if (flags['help'] as bool) {
+  if (options['help'] as bool) {
     print('main.dart [flags]');
     print(parser.usage);
     exit(0);
   }
 
+  // Collect the commands to be run from the command file.
+  final String commandFile = options['file'] as String;
   List<String> fileCommands = <String>[];
-  if (flags['cmdFile'] != null) {
-    if (flags['cmdFile'] == '-') {
+  if (commandFile != null) {
+    // Read from stdin if the --file option is set to '-'.
+    if (commandFile == '-') {
       String line = stdin.readLineSync();
       while (line != null) {
         fileCommands.add(line);
         line = stdin.readLineSync();
       }
     } else {
-      final File cmdFile = File(flags['cmdFile'] as String);
+      // Read the commands from a file.
+      final File cmdFile = File(commandFile);
       if (!cmdFile.existsSync()) {
-        print('Command file "$cmdFile" doesn\'t exist.');
+        print('Command file "$commandFile" doesn\'t exist.');
         exit(1);
       }
       fileCommands = cmdFile.readAsLinesSync();
     }
   }
+
+  // Collect all the commands, both from the input file, and from the command
+  // line. The command line commands come first (although they could all be
+  // executed simultaneously, depending on the number of workers, and number of
+  // commands).
   final List<String> commands = <String>[
-    ...flags['cmd'] as List<String>,
+    ...options['cmd'] as List<String>,
     ...fileCommands,
   ];
+
+  // Split each command entry into a list of strings, taking into account some
+  // simple quoting and escaping.
   final List<List<String>> splitCommands = commands.map<List<String>>(splitIntoArgs).toList();
 
-  int numWorkers = int.parse((flags['workers'] as String) ?? '-1');
-  numWorkers = numWorkers == -1 ? null : numWorkers;
+  // If the numWorkers is set to null, then the ProcessPool will automatically
+  // select the number of processes based on how many CPU cores the machine has.
+  final int numWorkers = int.tryParse(options['workers'] as String ?? '');
 
-  final bool printReport = (flags['report'] as bool) ?? false;
+  final bool printReport = (options['report'] as bool) ?? false;
 
-  final Directory workingDirectory = Directory((flags['workingDirectory'] as String) ?? '.');
+  final Directory workingDirectory = Directory((options['workingDirectory'] as String) ?? '.');
 
   final ProcessPool pool = ProcessPool(
     numWorkers: numWorkers,
diff --git a/lib/process_runner.dart b/lib/process_runner.dart
index 862e36a..309e76d 100644
--- a/lib/process_runner.dart
+++ b/lib/process_runner.dart
@@ -4,5 +4,5 @@
 
 library process_runner;
 
-export 'process_pool.dart';
-export 'process_runner_impl.dart';
+export 'src/process_pool.dart';
+export 'src/process_runner.dart';
diff --git a/lib/process_pool.dart b/lib/src/process_pool.dart
similarity index 96%
rename from lib/process_pool.dart
rename to lib/src/process_pool.dart
index 846abc1..7d96c89 100644
--- a/lib/process_pool.dart
+++ b/lib/src/process_pool.dart
@@ -10,6 +10,10 @@
 
 import 'process_runner.dart';
 
+/// A class that represents a job to be done by a [ProcessPool].
+///
+/// Create a list of these to pass to [ProcessPool.startWorkers] or
+/// [ProcessPool.runToCompletion].
 class WorkerJob {
   WorkerJob(
     this.command, {
@@ -196,7 +200,7 @@
   /// To listen to jobs as they are completed, use [startWorkers] instead.
   Future<List<WorkerJob>> runToCompletion(List<WorkerJob> jobs) async {
     final List<WorkerJob> results = <WorkerJob>[];
-    await startWorkers(jobs).forEach((WorkerJob job) => results.add(job));
+    await startWorkers(jobs).forEach(results.add);
     return results;
   }
 
diff --git a/lib/process_runner_impl.dart b/lib/src/process_runner.dart
similarity index 100%
rename from lib/process_runner_impl.dart
rename to lib/src/process_runner.dart
diff --git a/test/src/process_runner_test.dart b/test/src/process_runner_test.dart
index 835724e..b507da4 100644
--- a/test/src/process_runner_test.dart
+++ b/test/src/process_runner_test.dart
@@ -52,7 +52,7 @@
         ],
       };
       fakeProcessManager.fakeResults = calls;
-      expectLater(() => processRunner.runProcess(calls.keys.first), throwsException);
+      await expectLater(() => processRunner.runProcess(calls.keys.first), throwsException);
     });
   });
 }