606 enum (#608)

* Preserve a blank line between enum cases.

Fix #606.

* Bump to 1.0.1.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0ef1322..28c4d4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 # 1.0.1
 
 * Ensure space between `-` and `--` (#170).
+* Preserve a blank line between enum cases (#606).
 
 # 1.0.0
 
diff --git a/bin/format.dart b/bin/format.dart
index 65a5d83..85f53e2 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 = "1.0.0";
+const version = "1.0.1";
 
 void main(List<String> args) {
   var parser = new ArgParser(allowTrailingOptions: true);
diff --git a/lib/src/argument_list_visitor.dart b/lib/src/argument_list_visitor.dart
index 29125fa..3d0f7dc 100644
--- a/lib/src/argument_list_visitor.dart
+++ b/lib/src/argument_list_visitor.dart
@@ -236,18 +236,16 @@
 
     // Allow functions wrapped in dotted method calls like "a.b.c(() { ... })".
     if (expression is MethodInvocation) {
-      var invocation = expression as MethodInvocation;
-      if (!_isValidWrappingTarget(invocation.target)) return false;
-      if (invocation.argumentList.arguments.length != 1) return false;
+      if (!_isValidWrappingTarget(expression.target)) return false;
+      if (expression.argumentList.arguments.length != 1) return false;
 
-      return _isBlockFunction(invocation.argumentList.arguments.single);
+      return _isBlockFunction(expression.argumentList.arguments.single);
     }
 
     if (expression is InstanceCreationExpression) {
-      var creation = expression as InstanceCreationExpression;
-      if (creation.argumentList.arguments.length != 1) return false;
+      if (expression.argumentList.arguments.length != 1) return false;
 
-      return _isBlockFunction(creation.argumentList.arguments.single);
+      return _isBlockFunction(expression.argumentList.arguments.single);
     }
 
     // Allow immediately-invoked functions like "() { ... }()".
diff --git a/lib/src/chunk_builder.dart b/lib/src/chunk_builder.dart
index 5678e8c..e926859 100644
--- a/lib/src/chunk_builder.dart
+++ b/lib/src/chunk_builder.dart
@@ -101,6 +101,7 @@
   /// token pair.
   bool get needsToPreserveNewlines =>
       _pendingWhitespace == Whitespace.oneOrTwoNewlines ||
+      _pendingWhitespace == Whitespace.splitOrTwoNewlines ||
       _pendingWhitespace == Whitespace.splitOrNewline;
 
   /// The number of characters of code that can fit in a single line.
@@ -309,6 +310,15 @@
         }
         break;
 
+      case Whitespace.splitOrTwoNewlines:
+        if (numLines > 1) {
+          _pendingWhitespace = Whitespace.twoNewlines;
+        } else {
+          _pendingWhitespace = Whitespace.none;
+          split(space: true);
+        }
+        break;
+
       case Whitespace.oneOrTwoNewlines:
         if (numLines > 1) {
           _pendingWhitespace = Whitespace.twoNewlines;
@@ -604,6 +614,7 @@
         break;
 
       case Whitespace.splitOrNewline:
+      case Whitespace.splitOrTwoNewlines:
       case Whitespace.oneOrTwoNewlines:
         // We should have pinned these down before getting here.
         assert(false);
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 22122f7..faab9e8 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -842,7 +842,7 @@
     space();
 
     _beginBody(node.leftBracket, space: true);
-    visitCommaSeparatedNodes(node.constants, between: split);
+    visitCommaSeparatedNodes(node.constants, between: splitOrTwoNewlines);
 
     // If there is a trailing comma, always force the constants to split.
     if (node.constants.last.endToken.next.type == TokenType.COMMA) {
@@ -2497,6 +2497,13 @@
     builder.writeWhitespace(Whitespace.splitOrNewline);
   }
 
+  /// Allow either a single split or newline to be emitted before the next
+  /// non-whitespace token based on whether a newline exists in the source
+  /// between the last token and the next one.
+  void splitOrTwoNewlines() {
+    builder.writeWhitespace(Whitespace.splitOrTwoNewlines);
+  }
+
   /// Allow either one or two newlines to be emitted before the next
   /// non-whitespace token based on whether more than one newline exists in the
   /// source between the last token and the next one.
diff --git a/lib/src/whitespace.dart b/lib/src/whitespace.dart
index 712d9d0..c405063 100644
--- a/lib/src/whitespace.dart
+++ b/lib/src/whitespace.dart
@@ -54,6 +54,16 @@
   /// less prescriptive over the user's whitespace.
   static const splitOrNewline = const Whitespace._("splitOrNewline");
 
+  /// A split or blank line (two newlines) should be output based on whether
+  /// the current token is on the same line as the previous one or not.
+  ///
+  /// This is used between enum cases, which will collapse if possible but
+  /// also allow a blank line to be preserved between cases.
+  ///
+  /// In general, we like to avoid using this because it makes the formatter
+  /// less prescriptive over the user's whitespace.
+  static const splitOrTwoNewlines = const Whitespace._("splitOrTwoNewlines");
+
   /// One or two newlines should be output based on how many newlines are
   /// present between the next token and the previous one.
   ///
diff --git a/pubspec.yaml b/pubspec.yaml
index 46f9a3b..b6d7c02 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: 1.0.1-dev
+version: 1.0.1
 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/regression/0600/0606.unit b/test/regression/0600/0606.unit
new file mode 100644
index 0000000..0a65246
--- /dev/null
+++ b/test/regression/0600/0606.unit
@@ -0,0 +1,118 @@
+>>>
+enum ErrorKind {
+  AbstractNotSync,
+  AsciiControlCharacter,
+  AsyncAsIdentifier,
+  AwaitAsIdentifier,
+  AwaitForNotAsync,
+  AwaitNotAsync,
+  BuiltInIdentifierAsType,
+  BuiltInIdentifierInDeclaration,
+  EmptyNamedParameterList,
+  EmptyOptionalParameterList,
+  Encoding,
+  ExpectedBlockToSkip,
+  ExpectedBody,
+  ExpectedButGot,
+  ExpectedClassBody,
+
+  /// This error code can be used to support non-compliant (with respect to
+  /// Dart Language Specification) Dart VM native clauses. See
+  /// [dart_vm_native.dart].
+  ExpectedClassBodyToSkip,
+
+  ExpectedDeclaration,
+  ExpectedExpression,
+  ExpectedFunctionBody,
+  ExpectedHexDigit,
+  ExpectedIdentifier,
+  ExpectedOpenParens,
+  ExpectedString,
+  ExpectedType,
+  ExtraneousModifier,
+  ExtraneousModifierReplace,
+  FactoryNotSync,
+  GeneratorReturnsValue,
+  InvalidAwaitFor,
+  InvalidInlineFunctionType,
+  InvalidSyncModifier,
+  InvalidVoid,
+  MissingExponent,
+  NonAsciiIdentifier,
+  NonAsciiWhitespace,
+  OnlyTry,
+  PositionalParameterWithEquals,
+  RequiredParameterWithDefault,
+  SetterNotSync,
+  StackOverflow,
+  UnexpectedDollarInString,
+  UnexpectedToken,
+  UnmatchedToken,
+  UnsupportedPrefixPlus,
+  UnterminatedComment,
+  UnterminatedString,
+  UnterminatedToken,
+  YieldAsIdentifier,
+  YieldNotGenerator,
+
+  Unspecified,
+}
+<<<
+enum ErrorKind {
+  AbstractNotSync,
+  AsciiControlCharacter,
+  AsyncAsIdentifier,
+  AwaitAsIdentifier,
+  AwaitForNotAsync,
+  AwaitNotAsync,
+  BuiltInIdentifierAsType,
+  BuiltInIdentifierInDeclaration,
+  EmptyNamedParameterList,
+  EmptyOptionalParameterList,
+  Encoding,
+  ExpectedBlockToSkip,
+  ExpectedBody,
+  ExpectedButGot,
+  ExpectedClassBody,
+
+  /// This error code can be used to support non-compliant (with respect to
+  /// Dart Language Specification) Dart VM native clauses. See
+  /// [dart_vm_native.dart].
+  ExpectedClassBodyToSkip,
+
+  ExpectedDeclaration,
+  ExpectedExpression,
+  ExpectedFunctionBody,
+  ExpectedHexDigit,
+  ExpectedIdentifier,
+  ExpectedOpenParens,
+  ExpectedString,
+  ExpectedType,
+  ExtraneousModifier,
+  ExtraneousModifierReplace,
+  FactoryNotSync,
+  GeneratorReturnsValue,
+  InvalidAwaitFor,
+  InvalidInlineFunctionType,
+  InvalidSyncModifier,
+  InvalidVoid,
+  MissingExponent,
+  NonAsciiIdentifier,
+  NonAsciiWhitespace,
+  OnlyTry,
+  PositionalParameterWithEquals,
+  RequiredParameterWithDefault,
+  SetterNotSync,
+  StackOverflow,
+  UnexpectedDollarInString,
+  UnexpectedToken,
+  UnmatchedToken,
+  UnsupportedPrefixPlus,
+  UnterminatedComment,
+  UnterminatedString,
+  UnterminatedToken,
+  YieldAsIdentifier,
+  YieldNotGenerator,
+
+  Unspecified,
+}
\ No newline at end of file
diff --git a/test/whitespace/enums.unit b/test/whitespace/enums.unit
index ac05e42..26c2271 100644
--- a/test/whitespace/enums.unit
+++ b/test/whitespace/enums.unit
@@ -1,23 +1,53 @@
 40 columns                              |
 >>> single
-enum Unity {ONE}
+enum Unity {one}
 <<<
-enum Unity { ONE }
+enum Unity { one }
 >>> single line
-enum Primate{BONOBO,CHIMP,GORILLA}
+enum Primate{bonobo,chimp,gorilla}
 <<<
-enum Primate { BONOBO, CHIMP, GORILLA }
+enum Primate { bonobo, chimp, gorilla }
 >>> trailing comma always splits
-enum Primate{BONOBO,CHIMP,}
+enum Primate{bonobo,chimp,}
 <<<
 enum Primate {
-  BONOBO,
-  CHIMP,
+  bonobo,
+  chimp,
 }
 >>> metadata
 @Awesome @Fierce("really")
-enum Primate{BONOBO,CHIMP,GORILLA}
+enum Primate{bonobo,chimp,gorilla}
 <<<
 @Awesome
 @Fierce("really")
-enum Primate { BONOBO, CHIMP, GORILLA }
\ No newline at end of file
+enum Primate { bonobo, chimp, gorilla }
+>>> preserve one blank line between enums
+enum Primate {
+
+
+  bonobo,
+
+
+  chimp,
+
+
+
+  gorilla
+
+}
+<<<
+enum Primate {
+  bonobo,
+
+  chimp,
+
+  gorilla
+}
+>>> do not preserve single newline
+enum Primate {
+  bonobo,
+  chimp,
+  gorilla
+}
+<<<
+enum Primate { bonobo, chimp, gorilla }
\ No newline at end of file