@Test
  public void testRolloutIdWithValue() throws Exception {

    parse(":do{ rollout id = myplan}");

    assertFalse(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertTrue(handler.isRequestComplete());
    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());
    final ParsedOperationRequestHeader header = headers.iterator().next();
    assertTrue(header instanceof ParsedRolloutPlanHeader);

    final ParsedRolloutPlanHeader rollout = (ParsedRolloutPlanHeader) header;
    assertEquals("myplan", rollout.getPlanRef());
    assertEquals(18, rollout.getLastChunkIndex());
  }
  @Test
  public void testSingleHeader() throws Exception {

    parse("/profile=default/subsystem=threads/thread-factory=mytf:do{ name = value }");

    assertTrue(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertTrue(handler.isRequestComplete());
    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());
    final ParsedOperationRequestHeader header = headers.iterator().next();

    assertEquals("name", header.getName());
    final ModelNode node = new ModelNode();
    node.get("name").set("value");

    final ModelNode headersNode = new ModelNode();
    header.addTo(ctx, headersNode);
    assertEquals(node, headersNode);
  }
  @Test
  public void testEndsOnGroupConcurrent() throws Exception {

    parse(":do{ rollout groupA( prop = v ) ^");

    assertFalse(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertFalse(handler.isRequestComplete());

    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());
    final ParsedOperationRequestHeader header = headers.iterator().next();
    assertTrue(header instanceof ParsedRolloutPlanHeader);
    final ParsedRolloutPlanHeader rollout = (ParsedRolloutPlanHeader) header;
    assertTrue(rollout.endsOnGroupSeparator());
    assertEquals(32, rollout.getLastSeparatorIndex());
  }
  @Test
  public void testEndsOnGroupPropertiesEnd() throws Exception {

    parse("/profile=default/subsystem=threads/thread-factory=mytf:do{ rollout groupA()");

    assertTrue(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertFalse(handler.isRequestComplete());

    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());
    final ParsedOperationRequestHeader header = headers.iterator().next();
    assertTrue(header instanceof ParsedRolloutPlanHeader);
    ParsedRolloutPlanHeader rollout = (ParsedRolloutPlanHeader) header;
    final SingleRolloutPlanGroup group = rollout.getLastGroup();
    assertNotNull(group);

    assertEquals("groupA", group.getGroupName());
    assertFalse(group.endsOnPropertyListStart());
    assertTrue(group.endsOnPropertyListEnd());
    assertFalse(group.hasProperties());
  }
  @Test
  public void testTwoConcurrentGroups() throws Exception {

    parse(
        "/profile=default/subsystem=threads/thread-factory=mytf:do{ rollout "
            + "groupA(rolling-to-servers=true,max-failure-percentage=20) ^  groupB");

    assertTrue(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertFalse(handler.isRequestComplete());

    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());
    final ParsedOperationRequestHeader header = headers.iterator().next();
    assertTrue(header instanceof ParsedRolloutPlanHeader);

    final ModelNode node = new ModelNode();
    final ModelNode inSeries = node.get(Util.ROLLOUT_PLAN).get(Util.IN_SERIES);

    final ModelNode concurrent = new ModelNode();
    final ModelNode cg = concurrent.get(Util.CONCURRENT_GROUPS);

    ModelNode group = cg.get("groupA");
    group.get("rolling-to-servers").set("true");
    group.get("max-failure-percentage").set("20");

    group = cg.get("groupB");

    inSeries.add().set(concurrent);

    final ModelNode headersNode = new ModelNode();
    header.addTo(ctx, headersNode);
    assertEquals(node, headersNode);
  }
  @Test
  public void testEmptyHeaders() throws Exception {

    parse("/profile=default/subsystem=threads/thread-factory=mytf:do{}");

    assertTrue(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertTrue(handler.isRequestComplete());
    assertFalse(handler.hasHeaders());
  }
  @Test
  public void testOnlyHeaderListStart() throws Exception {

    parse("{");

    assertFalse(handler.hasAddress());
    assertFalse(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertTrue(handler.endsOnSeparator());
    assertTrue(handler.endsOnHeaderListStart());
    assertFalse(handler.isRequestComplete());
    assertFalse(handler.hasHeaders());
  }
  @Test
  public void testNonConcurrentGroupNames() throws Exception {

    parse("/profile=default/subsystem=threads/thread-factory=mytf:do{ rollout groupA ,  groupB");

    assertTrue(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertFalse(handler.isRequestComplete());

    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());
    final ParsedOperationRequestHeader header = headers.iterator().next();
    assertTrue(header instanceof ParsedRolloutPlanHeader);

    final ModelNode node = new ModelNode();
    final ModelNode inSeries = node.get(Util.ROLLOUT_PLAN).get(Util.IN_SERIES);
    ModelNode group = new ModelNode();
    group.get("groupA");
    inSeries.add().get(Util.SERVER_GROUP).set(group);

    group = new ModelNode();
    group.get("groupB");
    inSeries.add().get(Util.SERVER_GROUP).set(group);

    final ModelNode headersNode = new ModelNode();
    header.addTo(ctx, headersNode);
    assertEquals(node, headersNode);
  }
  @Test
  public void testRollout() throws Exception {

    parse(":do{rollout");

    assertFalse(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertFalse(handler.isRequestComplete());
    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(0, headers.size());
    assertEquals("rollout", handler.getLastHeaderName());
  }
  @Test
  public void testMixAgainstWholeRequest() throws Exception {

    parse(
        "/profile=default/subsystem=threads/thread-factory=mytf:do{ rollout "
            + "groupA(rolling-to-servers=true,max-failure-percentage=20) ^ groupB, groupC,"
            + "groupD(rolling-to-servers=true,max-failed-servers=1) ^ groupE rollback-across-groups}");

    assertTrue(handler.hasAddress());
    assertTrue(handler.hasOperationName());
    assertFalse(handler.hasProperties());
    assertFalse(handler.endsOnAddressOperationNameSeparator());
    assertFalse(handler.endsOnPropertyListStart());
    assertFalse(handler.endsOnPropertySeparator());
    assertFalse(handler.endsOnPropertyValueSeparator());
    assertFalse(handler.endsOnNodeSeparator());
    assertFalse(handler.endsOnNodeTypeNameSeparator());
    assertFalse(handler.endsOnSeparator());
    assertFalse(handler.endsOnHeaderListStart());
    assertTrue(handler.isRequestComplete());

    assertTrue(handler.hasHeaders());

    final Collection<ParsedOperationRequestHeader> headers = handler.getHeaders();
    assertEquals(1, headers.size());

    final ModelNode op = handler.toOperationRequest(ctx);
    assertTrue(op.hasDefined(Util.OPERATION_HEADERS));
    final ModelNode headersNode = op.get(Util.OPERATION_HEADERS);

    final ModelNode expectedHeaders = new ModelNode();
    final ModelNode rolloutPlan = expectedHeaders.get(Util.ROLLOUT_PLAN);
    final ModelNode inSeries = rolloutPlan.get(Util.IN_SERIES);

    ModelNode concurrent = new ModelNode();
    ModelNode cg = concurrent.get(Util.CONCURRENT_GROUPS);

    ModelNode group = cg.get("groupA");
    group.get("rolling-to-servers").set("true");
    group.get("max-failure-percentage").set("20");

    group = cg.get("groupB");

    inSeries.add().set(concurrent);

    ModelNode sg = new ModelNode();
    group = sg.get(Util.SERVER_GROUP);
    group.get("groupC");
    inSeries.add().set(sg);

    concurrent = new ModelNode();
    cg = concurrent.get(Util.CONCURRENT_GROUPS);

    group = cg.get("groupD");
    group.get("rolling-to-servers").set("true");
    group.get("max-failed-servers").set("1");

    cg.get("groupE");

    inSeries.add().set(concurrent);

    rolloutPlan.get("rollback-across-groups").set("true");

    assertEquals(expectedHeaders, headersNode);
  }