/** Test the normalization and the middle substring match. */
  @Test(dataProvider = "substringMiddleMatchData")
  public void middleMatchingRules(
      final String value, final String[] middleSubs, final ConditionResult result)
      throws Exception {
    final MatchingRule rule = getRule();

    // normalize the 2 provided values and check that they are equals
    final ByteString normalizedValue = rule.normalizeAttributeValue(ByteString.valueOf(value));

    final StringBuilder printableMiddleSubs = new StringBuilder();
    final List<ByteSequence> middleList = new ArrayList<>(middleSubs.length);
    printableMiddleSubs.append("*");
    for (final String middleSub : middleSubs) {
      printableMiddleSubs.append(middleSub);
      printableMiddleSubs.append("*");
      middleList.add(ByteString.valueOf(middleSub));
    }

    final ConditionResult substringAssertionMatches =
        rule.getSubstringAssertion(null, middleList, null).matches(normalizedValue);
    final ConditionResult assertionMatches =
        rule.getAssertion(ByteString.valueOf(printableMiddleSubs)).matches(normalizedValue);
    final String message = getMessage("middle", rule, value, printableMiddleSubs.toString());
    assertEquals(substringAssertionMatches, result, message);
    assertEquals(assertionMatches, result, message);
  }
  /** Test that invalid values are rejected. */
  @Test(
      expectedExceptions = DecodeException.class,
      dataProvider = "substringInvalidAttributeValues")
  public void substringInvalidAttributeValues(final String value) throws Exception {
    // Get the instance of the rule to be tested.
    final MatchingRule rule = getRule();

    rule.normalizeAttributeValue(ByteString.valueOf(value));
  }
  /** Test the normalization and the final substring match. */
  @Test(dataProvider = "substringFinalMatchData")
  public void finalMatchingRules(
      final String value, final String finalValue, final ConditionResult result) throws Exception {
    final MatchingRule rule = getRule();

    // normalize the 2 provided values and check that they are equals
    final ByteString normalizedValue = rule.normalizeAttributeValue(ByteString.valueOf(value));

    final ConditionResult substringAssertionMatches =
        rule.getSubstringAssertion(null, null, ByteString.valueOf(finalValue))
            .matches(normalizedValue);
    final ConditionResult assertionMatches =
        rule.getAssertion(ByteString.valueOf("*" + finalValue)).matches(normalizedValue);
    final String message = getMessage("final", rule, value, finalValue);
    assertEquals(substringAssertionMatches, result, message);
    assertEquals(assertionMatches, result, message);
  }
  /** Test that invalid values are rejected. */
  @Test(
      expectedExceptions = DecodeException.class,
      dataProvider = "substringInvalidAssertionValues")
  public void matchingRulesInvalidAssertionValues(
      final String subInitial, final String[] anys, final String subFinal) throws Exception {
    // Get the instance of the rule to be tested.
    final MatchingRule rule = getRule();

    final List<ByteSequence> anyList = new ArrayList<>(anys.length);
    for (final String middleSub : anys) {
      anyList.add(ByteString.valueOf(middleSub));
    }
    rule.getSubstringAssertion(
        subInitial == null ? null : ByteString.valueOf(subInitial),
        anyList,
        subFinal == null ? null : ByteString.valueOf(subFinal));
  }
  /** Test that invalid values are rejected. */
  @Test(
      expectedExceptions = DecodeException.class,
      dataProvider = "substringInvalidAssertionValues")
  public void matchingRulesInvalidAssertionValuesString(
      final String subInitial, final String[] anys, final String subFinal) throws Exception {
    // Get the instance of the rule to be tested.
    final MatchingRule rule = getRule();

    final StringBuilder assertionString = new StringBuilder();
    if (subInitial != null) {
      assertionString.append(subInitial);
    }
    assertionString.append("*");
    for (final String middleSub : anys) {
      assertionString.append(middleSub);
      assertionString.append("*");
    }
    if (subFinal != null) {
      assertionString.append(subFinal);
    }
    rule.getAssertion(ByteString.valueOf(assertionString.toString()));
  }