static boolean verify(ApplicationSpec app, RoutingTableSpec table, Hop parent, List<String> children,
                          String selector, List<String> errors, String context) {
        // Verify that the selector can be parsed.
        Hop hop = Hop.parse(selector);
        for (int i = 0, len = hop.getNumDirectives(); i < len; ++i) {
            HopDirective dir = hop.getDirective(i);
            if (dir instanceof ErrorDirective) {
                errors.add("For " + context + "; " + ((ErrorDirective)dir).getMessage());
                return false;
            }
        }

        // Verify that the parent matches this, if any.
        if (parent != null) {
            if (parent.getNumDirectives() == 1) {
                // hops that contain a single policy directive will typically be magic
            } else if (!parent.matches(hop)) {
                errors.add("Selector '" + parent.getServiceName() + "' does not match " + context + ".");
                return false;
            }
        }

        // Traverse and verify the directives of the hop.
        boolean verifyServiceName = true;
        boolean allowRecipients = false;
        for (int i = 0, len = hop.getNumDirectives(); i < len; ++i) {
            HopDirective dir = hop.getDirective(i);
            if (dir instanceof ErrorDirective) {
                // caught above
            } else if (dir instanceof PolicyDirective) {
                allowRecipients = true;
                verifyServiceName = false;
            } else if (dir instanceof RouteDirective) {
                String routeName = ((RouteDirective)dir).getName();
                if (!table.hasRoute(routeName)) {
                    errors.add(capitalize(context) + " references route '" + routeName + "' which does not exist.");
                    return false;
                }
                verifyServiceName = false;
            } else if (dir instanceof TcpDirective) {
                verifyServiceName = false;
            } else if (dir instanceof VerbatimDirective) {
                // will be verified below
            }
        }

        // Verify that the service referenced by the hop exists, if required.
        if (verifyServiceName) {
            String serviceName = hop.getServiceName();
            if (table.hasRoute(serviceName)) {
                // all good
            } else if (table.hasHop(serviceName)) {
                // also good
            } else if (!app.isService(table.getProtocol(), serviceName)) {
                errors.add(capitalize(context) + " references '" + serviceName + "' which is neither a service," +
                           " a route nor another hop.");
                return false;
            }
        }

        // Verify that recipients are allowed and that they are valid themselves.
        if (children != null && children.size() > 0) {
            if (!allowRecipients) {
                errors.add(capitalize(context) + " has recipients but no policy directive.");
                return false;
            }
            for (String child : children) {
                verify(app, table, hop, null, child, errors, "recipient '" + child + "' in " + context);
            }
        }

        // All ok.
        return true;
    }
Verifies that the hop given by the given selector and children is valid.

@param app      The application to verify against.
@param table    The routing table to verify against.
@param parent   The parent hop that the selector must match.
@param selector The selector to verify.
@param children The children to verify, may be null or empty.
@param errors   The list of errors found.
@param context  The context to use if adding an error.
@return True if no errors where found.
messagebus/src/main/java/com/yahoo/messagebus/routing/HopSpec.java