Support generic method parameters.

Previous support only covered arguments. :(
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b595ef3..8dde679 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.2.13
+
+* Support generic method *parameters* as well as arguments.  
+
 # 0.2.12
 
 * Add support for assert() in constructor initializers.
diff --git a/bin/format.dart b/bin/format.dart
index 1dcad32..3e89f78 100644
--- a/bin/format.dart
+++ b/bin/format.dart
@@ -14,7 +14,7 @@
 import 'package:dart_style/src/source_code.dart';
 
 // Note: The following line of code is modified by tool/grind.dart.
-const version = "0.2.12";
+const version = "0.2.13";
 
 void main(List<String> args) {
   var parser = new ArgParser(allowTrailingOptions: true);
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 2d2c257..1b450b6 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -631,7 +631,7 @@
     // the parameter list gets more deeply indented.
     if (node.redirectedConstructor != null) builder.nestExpression();
 
-    _visitBody(node.parameters, node.body, () {
+    _visitBody(null, node.parameters, node.body, () {
       // Check for redirects or initializer lists.
       if (node.redirectedConstructor != null) {
         _visitConstructorRedirects(node);
@@ -895,7 +895,8 @@
     _visitLoopBody(node.body);
   }
 
-  visitFormalParameterList(FormalParameterList node) {
+  visitFormalParameterList(FormalParameterList node,
+      {bool nestExpression: true}) {
     // Corner case: empty parameter lists.
     if (node.parameters.isEmpty) {
       token(node.leftParenthesis);
@@ -922,7 +923,7 @@
         .where((param) => param is DefaultFormalParameter)
         .toList();
 
-    builder.nestExpression();
+    if (nestExpression) builder.nestExpression();
     token(node.leftParenthesis);
 
     _metadataRules.add(new MetadataRule());
@@ -997,7 +998,7 @@
     _metadataRules.removeLast();
 
     token(node.rightParenthesis);
-    builder.unnest();
+    if (nestExpression) builder.unnest();
   }
 
   visitForStatement(ForStatement node) {
@@ -1067,7 +1068,20 @@
   }
 
   visitFunctionExpression(FunctionExpression node) {
-    _visitBody(node.parameters, node.body);
+    // TODO(rnystrom): This is working but not tested. As of 2016/11/29, the
+    // latest version of analyzer on pub does not parse generic lambdas. When
+    // a version of it that does is published, upgrade dart_style to use it and
+    // then test it:
+    //
+    //     >>> generic function expression
+    //         main() {
+    //           var generic = < T,S >(){};
+    //     }
+    //     <<<
+    //     main() {
+    //       var generic = <T, S>() {};
+    //     }
+    _visitBody(node.typeParameters, node.parameters, node.body);
   }
 
   visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
@@ -1340,7 +1354,6 @@
       // The indentation is fine, but splitting in the middle of each argument
       // list looks kind of strange. If this ends up happening in real world
       // code, consider putting a constraint between them.
-
       visit(node.typeArguments);
       visitArgumentList(node.argumentList, nestExpression: false);
 
@@ -1867,7 +1880,14 @@
     visit(node.name);
     builder.endSpan();
 
-    _visitBody(function.parameters, function.body, () {
+    TypeParameterList typeParameters;
+    if (node is FunctionDeclaration) {
+      typeParameters = node.functionExpression.typeParameters;
+    } else {
+      typeParameters = (node as MethodDeclaration).typeParameters;
+    }
+
+    _visitBody(typeParameters, function.parameters, function.body, () {
       // If the body is a block, we need to exit nesting before we hit the body
       // indentation, but we do want to wrap it around the parameters.
       if (function.body is! ExpressionFunctionBody) builder.unnest();
@@ -1882,7 +1902,8 @@
   /// space before it if it's not empty.
   ///
   /// If [beforeBody] is provided, it is invoked before the body is visited.
-  void _visitBody(FormalParameterList parameters, FunctionBody body,
+  void _visitBody(TypeParameterList typeParameters,
+      FormalParameterList parameters, FunctionBody body,
       [beforeBody()]) {
     // If the body is "=>", add an extra level of indentation around the
     // parameters and a rule that spans the parameters and the "=>". This
@@ -1914,7 +1935,16 @@
       builder.startLazyRule(new Rule(Cost.arrow));
     }
 
-    if (parameters != null) visit(parameters);
+    // Start the nesting for the parameters here, so they wrap around the
+    // type parameters too, if any.
+    builder.nestExpression();
+
+    visit(typeParameters);
+    if (parameters != null) {
+      visitFormalParameterList(parameters, nestExpression: false);
+    }
+
+    builder.unnest();
 
     if (beforeBody != null) beforeBody();
     visit(body);
diff --git a/pubspec.yaml b/pubspec.yaml
index 40a0e05..de73b6d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: dart_style
 # Note: See tool/grind.dart for how to bump the version.
-version: 0.2.12
+version: 0.2.13
 author: Dart Team <misc@dartlang.org>
 description: Opinionated, automatic Dart source code formatter.
 homepage: https://github.com/dart-lang/dart_style
diff --git a/test/splitting/generic_method_parameters.unit b/test/splitting/generic_method_parameters.unit
new file mode 100644
index 0000000..bbe1f43
--- /dev/null
+++ b/test/splitting/generic_method_parameters.unit
@@ -0,0 +1,67 @@
+40 columns                              |
+>>> all fit on one line
+foo<A,B,C,D>() {}
+<<<
+foo<A, B, C, D>() {}
+>>> prefer to split between params even when they all fit on next line
+longFunctionName<First, Second, Third>() {}
+<<<
+longFunctionName<First, Second,
+    Third>() {}
+>>> split before first if needed
+longFunctionName<FirstTypeParameterIsLong, S>() {}
+<<<
+longFunctionName<
+    FirstTypeParameterIsLong, S>() {}
+>>> split in middle if fit in two lines
+longFunctionName<First, Second, Third, Fourth, Fifth, Sixth>() {}
+<<<
+longFunctionName<First, Second, Third,
+    Fourth, Fifth, Sixth>() {}
+>>> split one per line if they don't fit in two lines
+veryLongFunctionName<First, Second, Third, Fourth, Fifth, Sixth, Seventh>() {}
+<<<
+veryLongFunctionName<
+    First,
+    Second,
+    Third,
+    Fourth,
+    Fifth,
+    Sixth,
+    Seventh>() {}
+>>> split both type and value arguments
+lengthyMethodName<First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth>(first, second, third, fourth, fifth, sixth, seventh, eighth) {}
+<<<
+lengthyMethodName<
+        First,
+        Second,
+        Third,
+        Fourth,
+        Fifth,
+        Sixth,
+        Seventh,
+        Eighth>(
+    first,
+    second,
+    third,
+    fourth,
+    fifth,
+    sixth,
+    seventh,
+    eighth) {}
+>>> type parameters and => body
+longFunctionName<LongTypeParameterT, LongTypeParameterS>() => body;
+<<<
+longFunctionName<
+        LongTypeParameterT,
+        LongTypeParameterS>() =>
+    body;
+>>> type parameters, value parameters, and => body
+longFunctionName<LongTypeParameterT, LongTypeParameterS>(longParameter1, longParameter2) => body;
+<<<
+longFunctionName<
+            LongTypeParameterT,
+            LongTypeParameterS>(
+        longParameter1,
+        longParameter2) =>
+    body;
\ No newline at end of file
diff --git a/test/splitting/type_parameters.unit b/test/splitting/type_parameters.unit
index 088f045..920cb38 100644
--- a/test/splitting/type_parameters.unit
+++ b/test/splitting/type_parameters.unit
@@ -34,4 +34,16 @@
     TypeArgument> extends Base {}
 <<<
 class SomeClass<TypeArgument>
-    extends Base {}
\ No newline at end of file
+    extends Base {}
+>>> generic function declaration
+foo<A,B,C,D>() {}
+<<<
+foo<A, B, C, D>() {}
+>>> generic method on class
+class Foo {
+  foo<A,B,C,D>() {}
+}
+<<<
+class Foo {
+  foo<A, B, C, D>() {}
+}
\ No newline at end of file
diff --git a/test/utils.dart b/test/utils.dart
index 022fa28..2ebf406 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -21,8 +21,10 @@
 
   // Locate the "test" directory. Use mirrors so that this works with the test
   // package, which loads this suite into an isolate.
-  var testDir = p.dirname(
-      currentMirrorSystem().findLibrary(#dart_style.test.utils).uri.toFilePath());
+  var testDir = p.dirname(currentMirrorSystem()
+      .findLibrary(#dart_style.test.utils)
+      .uri
+      .toFilePath());
 
   var formatterPath = p.normalize(p.join(testDir, "../bin/format.dart"));