public List<Block> chunk(String resourceId, List<TokensLine> fragments) {
    List<TokensLine> filtered = new ArrayList<>();
    int i = 0;
    while (i < fragments.size()) {
      TokensLine first = fragments.get(i);
      int j = i + 1;
      while (j < fragments.size() && fragments.get(j).getValue().equals(first.getValue())) {
        j++;
      }
      filtered.add(fragments.get(i));
      if (i < j - 1) {
        filtered.add(fragments.get(j - 1));
      }
      i = j;
    }
    fragments = filtered;

    if (fragments.size() < blockSize) {
      return new ArrayList<>();
    }
    TokensLine[] fragmentsArr = fragments.toArray(new TokensLine[fragments.size()]);
    List<Block> blocks = new ArrayList<>(fragmentsArr.length - blockSize + 1);
    long hash = 0;
    int first = 0;
    int last = 0;
    for (; last < blockSize - 1; last++) {
      hash = hash * PRIME_BASE + fragmentsArr[last].getHashCode();
    }
    Block.Builder blockBuilder = Block.builder().setResourceId(resourceId);
    for (; last < fragmentsArr.length; last++, first++) {
      TokensLine firstFragment = fragmentsArr[first];
      TokensLine lastFragment = fragmentsArr[last];
      // add last statement to hash
      hash = hash * PRIME_BASE + lastFragment.getHashCode();
      // create block
      Block block = blockBuilder
        .setBlockHash(new ByteArray(hash))
        .setIndexInFile(first)
        .setLines(firstFragment.getStartLine(), lastFragment.getEndLine())
        .setUnit(firstFragment.getStartUnit(), lastFragment.getEndUnit())
        .build();
      blocks.add(block);
      // remove first statement from hash
      hash -= power * firstFragment.getHashCode();
    }
    return blocks;
  }
@Test
  public void shouldBuildBlocks() {
    TokensLine line1 = new TokensLine(0, 9, 1, Character.toString((char) 1));
    TokensLine line2 = new TokensLine(10, 19, 2, Character.toString((char) 2));
    TokensLine line3 = new TokensLine(20, 29, 3, Character.toString((char) 3));

    List<Block> blocks = new PmdBlockChunker(2).chunk("resourceId", Arrays.asList(line1, line2, line3));
    assertThat(blocks.size(), is(2));

    Block block = blocks.get(0);
    // assertThat(block.getLengthInUnits(), is(11));
    assertThat(block.getStartLine(), is(1));
    assertThat(block.getEndLine(), is(2));
    assertThat(block.getBlockHash(), is(new ByteArray(1L * 31 + 2)));

    block = blocks.get(1);
    // assertThat(block.getLengthInUnits(), is(33));
    assertThat(block.getStartLine(), is(2));
    assertThat(block.getEndLine(), is(3));
    assertThat(block.getBlockHash(), is(new ByteArray(2L * 31 + 3)));
  }