public RoutingPolicy getRoutingPolicy(String protocolName, String policyName, String policyParam) {
        String cacheKey = protocolName + "." + policyName + "." + policyParam;
        RoutingPolicy ret = routingPolicyCache.get(cacheKey);
        if (ret != null) {
            return ret;
        }
        synchronized (this) {
            ret = routingPolicyCache.get(cacheKey);
            if (ret != null) {
                return ret;
            }
            Protocol protocol = getProtocol(protocolName);
            if (protocol == null) {
                log.log(Level.SEVERE, "Protocol '" + protocolName + "' not supported.");
                return null;
            }
            try {
                ret = protocol.createPolicy(policyName, policyParam);
            } catch (RuntimeException e) {
                log.log(Level.SEVERE, "Protocol '" + protocolName + "' threw an exception: " + e.getMessage(), e);
                return null;
            }
            if (ret == null) {
                log.log(Level.SEVERE, "Protocol '" + protocolName + "' failed to create routing policy '" + policyName +
                                        "' with parameter '" + policyParam + "'.");
                return null;
            }
            routingPolicyCache.put(cacheKey, ret);
        }
        return ret;
    }
Creates and returns a routing policy that matches the given arguments. If a routing policy has been created
previously using the exact same parameters, this method will returned that cached instance instead of creating
another. Not that when you replace a protocol using {@link #putProtocol(Protocol)} the policy cache is cleared.

@param protocolName The name of the protocol whose routing policy to create.
@param policyName   The name of the routing policy to create.
@param policyParam  The parameter to pass to the routing policy constructor.
@return The created routing policy.
messagebus/src/main/java/com/yahoo/messagebus/ProtocolRepository.java