@Override
    public void probeEquivalence(final Node other, final Notification result) {
        try {
            final SyntaxNode syntax = (SyntaxNode) other;

            if (!getAttribute(Attributes.TITLE).equals(syntax.getAttribute(Attributes.TITLE))) {
                result.error("Titles of syntx differs: '%s' != '%s'!",
                             getAttribute(Attributes.TITLE),
                             syntax.getAttribute(Attributes.TITLE));
            }

            if (!getAttribute(Attributes.META).equals(syntax.getAttribute(Attributes.META))) {
                result.error("Meta of syntx differs: '%s' != '%s'!",
                             getAttribute(Attributes.META),
                             syntax.getAttribute(Attributes.META));
            }

            if (countChildren() != syntax.countChildren()) {
                result.error(
                    "Node %s has different child count than other: %d != %d!",
                    getNodeName(),
                    countChildren(),
                    syntax.countChildren()
                );
            }

            final List<Node> subnodes      = getChildren();
            final List<Node> otherSubnodes = syntax.getChildren();
            int i = 0; // NOPMD

            for (Node subnode : subnodes) {
                try {
                    subnode.probeEquivalence(otherSubnodes.get(i), result);
                } catch (IndexOutOfBoundsException ex) {
                    result.error("Other node has not the expected subnode!");
                }

                i++;
            }
        } catch (ClassCastException ex) {
            result.error(
                "Probed node types mismatch: '%s' != '%s'!",
                getClass(),
                other.getClass()
            );
        }
    }