class ElementProperties {

    public static ElementPropertyWithNumericalBoundaries hasNChildren(Integer n) {
        return new ElementPropertyWithNumericalBoundaries() {
            @Override
            public String toXpath() {
                return "count(./*)=" + n;
            }

            @Override
            public String toString() {
                return String.format("has %d children", n);
            }

            /**
             * The element has at least n direct children
             * @return a element property that can be applied with Path::that
             */
            @Override
            public ElementProperty orMore() {
                return new ElementProperty() {
                    @Override
                    public String toXpath() {
                        return "count(./*)>=" + n;
                    }

                    public String toString() {
                        return String.format("has at least %d children", n);
                    }
                };
            }

            /**
             * The element has at most n direct children
             * @return a element property that can be applied with Path::that
             */
            @Override
            public ElementProperty orLess() {
                return new ElementProperty() {
                    @Override
                    public String toXpath() {
                        return "count(./*)<=" + n;
                    }

                    public String toString() {
                        return String.format("has at most %d children", n);
                    }
                };
            }
        };
    }

    private  ElementProperties();

}