public <T extends Block> List<T> getBlocks(Block currentBlock, Axes currentAxes)
    {
        List<T> blocks = new ArrayList<T>();

        Block block = currentBlock;
        Axes axes = currentAxes;

        while (block != null) {
            Block nextBlock = null;

            switch (axes) {
            // SELF
                case SELF:
                    addBlock(block, blocks);
                    break;
                // ANCESTOR
                case ANCESTOR_OR_SELF:
                    addBlock(block, blocks);
                    nextBlock = block.getParent();
                    break;
                case ANCESTOR:
                    nextBlock = block.getParent();
                    axes = Axes.ANCESTOR_OR_SELF;
                    break;
                case PARENT:
                    nextBlock = block.getParent();
                    axes = Axes.SELF;
                    break;
                // DESCENDANT
                case CHILD:
                    if (!block.getChildren().isEmpty()) {
                        nextBlock = block.getChildren().get(0);
                        axes = Axes.FOLLOWING_SIBLING;
                        addBlock(nextBlock, blocks);
                    }
                    break;
                case DESCENDANT_OR_SELF:
                    addBlock(block, blocks);
                    blocks = getBlocks(block.getChildren(), Axes.DESCENDANT_OR_SELF, blocks);
                    break;
                case DESCENDANT:
                    blocks = getBlocks(block.getChildren(), Axes.DESCENDANT_OR_SELF, blocks);
                    break;
                // FOLLOWING
                case FOLLOWING_SIBLING:
                    nextBlock = block.getNextSibling();
                    addBlock(nextBlock, blocks);
                    break;
                case FOLLOWING:
                    for (Block nextSibling = block.getNextSibling(); nextSibling != null;
                        nextSibling = nextSibling.getNextSibling()) {
                        blocks = getBlocks(nextSibling, Axes.DESCENDANT_OR_SELF, blocks);
                    }
                    break;
                // PRECEDING
                case PRECEDING_SIBLING:
                    nextBlock = block.getPreviousSibling();
                    addBlock(nextBlock, blocks);
                    break;
                case PRECEDING:
                    for (Block previousSibling = block.getPreviousSibling(); previousSibling != null;
                        previousSibling = previousSibling.getPreviousSibling()) {
                        blocks = getBlocks(previousSibling, Axes.DESCENDANT_OR_SELF, blocks);
                    }
                    break;
                default:
                    break;
            }

            block = nextBlock;
        }

        return blocks != null ? blocks : Collections.<T>emptyList();
    }
public < T extends Block > List < T > getBlocks ( Block currentBlock , Axes currentAxes ) { List < T > blocks = new ArrayList < T > ( ) ; Block block = currentBlock ; Axes axes = currentAxes ; while ( block != null ) { Block nextBlock = null ; switch ( axes ) { case SELF : addBlock ( block , blocks ) ; break ; case ANCESTOR_OR_SELF : addBlock ( block , blocks ) ; nextBlock = block . getParent ( ) ; break ; case ANCESTOR : nextBlock = block . getParent ( ) ; axes = Axes . ANCESTOR_OR_SELF ; break ; case PARENT : nextBlock = block . getParent ( ) ; axes = Axes . SELF ; break ; case CHILD : if ( ! block . getChildren ( ) . isEmpty ( ) ) { nextBlock = block . getChildren ( ) . get ( 0 ) ; axes = Axes . FOLLOWING_SIBLING ; addBlock ( nextBlock , blocks ) ; } break ; case DESCENDANT_OR_SELF : addBlock ( block , blocks ) ; blocks = getBlocks ( block . getChildren ( ) , Axes . DESCENDANT_OR_SELF , blocks ) ; break ; case DESCENDANT : blocks = getBlocks ( block . getChildren ( ) , Axes . DESCENDANT_OR_SELF , blocks ) ; break ; case FOLLOWING_SIBLING : nextBlock = block . getNextSibling ( ) ; addBlock ( nextBlock , blocks ) ; break ; case FOLLOWING : for ( Block nextSibling = block . getNextSibling ( ) ; nextSibling != null ; nextSibling = nextSibling . getNextSibling ( ) ) { blocks = getBlocks ( nextSibling , Axes . DESCENDANT_OR_SELF , blocks ) ; } break ; case PRECEDING_SIBLING : nextBlock = block . getPreviousSibling ( ) ; addBlock ( nextBlock , blocks ) ; break ; case PRECEDING : for ( Block previousSibling = block . getPreviousSibling ( ) ; previousSibling != null ; previousSibling = previousSibling . getPreviousSibling ( ) ) { blocks = getBlocks ( previousSibling , Axes . DESCENDANT_OR_SELF , blocks ) ; } break ; default : break ; } block = nextBlock ; } return blocks != null ? blocks : Collections . < T > emptyList ( ) ; }
Get all blocks following provided {@link BlockMatcher} and {@link Axes}.

@param <T> the class of the Blocks to return
@param currentBlock the block to start searching from
@param currentAxes indicate the search axes
@return the matched {@link Block}s, empty list of none was found