Added `MiddlewareExtensions` which provides `addMiddleware` and `addHandler` (#196)

...to `Middleware` instances.
Provides easier access to the composition capabilities offered by `Pipeline`.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee94fc9..be51752 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 1.2.0
+
+* Added `MiddlewareExtensions` which provides `addMiddleware` and `addHandler`
+  to `Middleware` instances. Provides easier access to the composition
+  capabilities offered by `Pipeline`.
+
 ## 1.1.4
 
 * Documentation improvements.
diff --git a/lib/shelf.dart b/lib/shelf.dart
index ead9ec5..6c5a54c 100644
--- a/lib/shelf.dart
+++ b/lib/shelf.dart
@@ -8,6 +8,7 @@
 export 'src/middleware.dart';
 export 'src/middleware/add_chunked_encoding.dart';
 export 'src/middleware/logger.dart';
+export 'src/middleware_extensions.dart';
 export 'src/pipeline.dart';
 export 'src/request.dart';
 export 'src/response.dart';
diff --git a/lib/src/middleware_extensions.dart b/lib/src/middleware_extensions.dart
new file mode 100644
index 0000000..d946eea
--- /dev/null
+++ b/lib/src/middleware_extensions.dart
@@ -0,0 +1,14 @@
+import 'handler.dart';
+import 'middleware.dart';
+
+/// Extensions on [Middleware] to aid in composing [Middleware] and [Handlers].
+///
+/// These members can be used in place of [Pipeline].
+extension MiddlewareExtensions on Middleware {
+  /// Merges `this` and [other] into a new [Middleware].
+  Middleware addMiddleware(Middleware other) =>
+      (Handler handler) => this(other(handler));
+
+  /// Merges `this` and [handler] into a new [Handler].
+  Handler addHandler(Handler handler) => this(handler);
+}
diff --git a/lib/src/pipeline.dart b/lib/src/pipeline.dart
index 5e9a7b0..2cff4a4 100644
--- a/lib/src/pipeline.dart
+++ b/lib/src/pipeline.dart
@@ -8,10 +8,15 @@
 /// A helper that makes it easy to compose a set of [Middleware] and a
 /// [Handler].
 ///
-///     var handler = const Pipeline()
-///         .addMiddleware(loggingMiddleware)
-///         .addMiddleware(cachingMiddleware)
-///         .addHandler(application);
+/// ```dart
+///  var handler = const Pipeline()
+///      .addMiddleware(loggingMiddleware)
+///      .addMiddleware(cachingMiddleware)
+///      .addHandler(application);
+/// ```
+///
+/// Note: this package also provides `addMiddleware` and `addHandler` extensions
+//  members on [Middleware], which may be easier to use.
 class Pipeline {
   const Pipeline();
 
diff --git a/pubspec.yaml b/pubspec.yaml
index c8cc227..ba7f5e8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: shelf
-version: 1.1.4
+version: 1.2.0
 description: >-
   A model for web server middleware that encourages composition and easy reuse
 repository: https://github.com/dart-lang/shelf
diff --git a/test/pipeline_test.dart b/test/pipeline_test.dart
index e789cd4..62124e1 100644
--- a/test/pipeline_test.dart
+++ b/test/pipeline_test.dart
@@ -49,6 +49,15 @@
     expect(accessLocation, 5);
   });
 
+  test('extensions for composition', () async {
+    var handler =
+        middlewareA.addMiddleware(middlewareB).addHandler(innerHandler);
+
+    final response = await makeSimpleRequest(handler);
+    expect(response, isNotNull);
+    expect(accessLocation, 5);
+  });
+
   test('Pipeline can be used as middleware', () async {
     var innerPipeline =
         const Pipeline().addMiddleware(middlewareA).addMiddleware(middlewareB);