public void testRestURLPostfix1() throws Exception {
    API api = new API(TEST_API, "/test");
    SynapseConfiguration synapseConfig = new SynapseConfiguration();
    synapseConfig.addAPI(TEST_API, api);

    RESTRequestHandler handler = new RESTRequestHandler();

    MessageContext synCtx = getMessageContext(synapseConfig, false, "/test", "GET");
    handler.process(synCtx);
    checkRestURLPostfix(synCtx, "");

    synCtx = getMessageContext(synapseConfig, false, "/test/me/now", "GET");
    handler.process(synCtx);
    checkRestURLPostfix(synCtx, "/me/now");

    synCtx = getMessageContext(synapseConfig, false, "/test?a=5", "GET");
    handler.process(synCtx);
    checkRestURLPostfix(synCtx, "?a=5");

    api.setVersionStrategy(new URLBasedVersionStrategy(api, "1.0.0", null));
    synCtx = getMessageContext(synapseConfig, false, "/test/1.0.0?a=5", "GET");
    handler.process(synCtx);
    checkRestURLPostfix(synCtx, "?a=5");

    synCtx = getMessageContext(synapseConfig, false, "/test/1.0.0/foo?a=5", "GET");
    handler.process(synCtx);
    checkRestURLPostfix(synCtx, "/foo?a=5");
  }
  /**
   * Retrieve the sequence from Continuation state which message should be injected to.
   *
   * @param seqContState SeqContinuationState which contain the sequence information
   * @param synCtx message context
   * @return sequence which message should be injected to
   */
  public static SequenceMediator retrieveSequence(
      MessageContext synCtx, SeqContinuationState seqContState) {
    SequenceMediator sequence = null;

    switch (seqContState.getSeqType()) {
      case NAMED:
        {
          sequence = (SequenceMediator) synCtx.getSequence(seqContState.getSeqName());
          if (sequence == null) {
            // This can happen only if someone delete the sequence while running
            handleException("Sequence : " + seqContState.getSeqName() + " not found");
          }
          break;
        }
      case PROXY_INSEQ:
        {
          String proxyName = (String) synCtx.getProperty(SynapseConstants.PROXY_SERVICE);
          ProxyService proxyService = synCtx.getConfiguration().getProxyService(proxyName);
          if (proxyService != null) {
            sequence = proxyService.getTargetInLineInSequence();
          } else {
            handleException("Proxy Service :" + proxyName + " not found");
          }
          break;
        }
      case API_INSEQ:
        {
          String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API);
          String resourceName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_RESOURCE);
          API api = synCtx.getEnvironment().getSynapseConfiguration().getAPI(apiName);
          if (api != null) {
            Resource resource = api.getResource(resourceName);
            if (resource != null) {
              sequence = resource.getInSequence();
            } else {
              handleException("Resource : " + resourceName + " not found");
            }
          } else {
            handleException("REST API : " + apiName + " not found");
          }
          break;
        }
      case PROXY_OUTSEQ:
        {
          String proxyName = (String) synCtx.getProperty(SynapseConstants.PROXY_SERVICE);
          ProxyService proxyService = synCtx.getConfiguration().getProxyService(proxyName);
          if (proxyService != null) {
            sequence = proxyService.getTargetInLineOutSequence();
          } else {
            handleException("Proxy Service :" + proxyName + " not found");
          }
          break;
        }
      case API_OUTSEQ:
        {
          String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API);
          String resourceName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_RESOURCE);
          API api = synCtx.getEnvironment().getSynapseConfiguration().getAPI(apiName);
          if (api != null) {
            Resource resource = api.getResource(resourceName);
            if (resource != null) {
              sequence = resource.getOutSequence();
            } else {
              handleException("Resource : " + resourceName + " not found");
            }
          } else {
            handleException("REST API : " + apiName + " not found");
          }
          break;
        }
      case PROXY_FAULTSEQ:
        {
          String proxyName = (String) synCtx.getProperty(SynapseConstants.PROXY_SERVICE);
          ProxyService proxyService = synCtx.getConfiguration().getProxyService(proxyName);
          if (proxyService != null) {
            sequence = proxyService.getTargetInLineFaultSequence();
          } else {
            handleException("Proxy Service :" + proxyName + " not found");
          }
          break;
        }
      case API_FAULTSEQ:
        {
          String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API);
          String resourceName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_RESOURCE);
          API api = synCtx.getEnvironment().getSynapseConfiguration().getAPI(apiName);
          if (api != null) {
            Resource resource = api.getResource(resourceName);
            if (resource != null) {
              sequence = resource.getFaultSequence();
            } else {
              handleException("Resource : " + resourceName + " not found");
            }
          } else {
            handleException("REST API : " + apiName + " not found");
          }
          break;
        }
    }

    return sequence;
  }
  public VerbInfoDTO findMatchingVerb(MessageContext synCtx)
      throws ResourceNotFoundException, APISecurityException {

    VerbInfoDTO verb = null;

    // This function is used by more than one handler. If on one execution of this function, it has
    // found and placed
    // the matching verb in the cache, the same can be re-used from all handlers since all handlers
    // share the same
    // MessageContext. The API_RESOURCE_CACHE_KEY property will be set in the MessageContext to
    // indicate that the
    // verb has been put into the cache.
    String resourceCacheKey = (String) synCtx.getProperty(APIConstants.API_RESOURCE_CACHE_KEY);
    if (resourceCacheKey != null) {
      verb = (VerbInfoDTO) getResourceCache().get(resourceCacheKey);
      // Cache hit
      if (verb != null) {
        if (log.isDebugEnabled()) {
          log.debug("Found resource in Cache for key: ".concat(resourceCacheKey));
        }
        return verb;
      }
      if (log.isDebugEnabled()) {
        log.debug("Resource not found in cache for key: ".concat(resourceCacheKey));
      }
    }
    String resourceString = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
    String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
    String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
    String fullRequestPath = (String) synCtx.getProperty(RESTConstants.REST_FULL_REQUEST_PATH);
    String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API);

    String requestPath = Utils.getRequestPath(synCtx, fullRequestPath, apiContext, apiVersion);
    if ("".equals(requestPath)) {
      requestPath = "/";
    }

    if (log.isDebugEnabled()) {
      log.debug("Setting REST_SUB_REQUEST_PATH in msg context: ".concat(requestPath));
    }
    synCtx.setProperty(RESTConstants.REST_SUB_REQUEST_PATH, requestPath);

    String httpMethod =
        (String)
            ((Axis2MessageContext) synCtx)
                .getAxis2MessageContext()
                .getProperty(Constants.Configuration.HTTP_METHOD);
    if (resourceString == null) {
      API selectedApi = synCtx.getConfiguration().getAPI(apiName);
      Resource selectedResource = null;

      if (selectedApi != null) {
        Resource[] selectedAPIResources = selectedApi.getResources();

        Set<Resource> acceptableResources = new HashSet<Resource>();

        for (Resource resource : selectedAPIResources) {
          // If the requesting method is OPTIONS or if the Resource contains the requesting method
          if (RESTConstants.METHOD_OPTIONS.equals(httpMethod)
              || (resource.getMethods() != null
                  && Arrays.asList(resource.getMethods()).contains(httpMethod))) {
            acceptableResources.add(resource);
          }
        }

        if (acceptableResources.size() > 0) {
          for (RESTDispatcher dispatcher : RESTUtils.getDispatchers()) {
            Resource resource = dispatcher.findResource(synCtx, acceptableResources);
            if (resource != null && Arrays.asList(resource.getMethods()).contains(httpMethod)) {
              selectedResource = resource;
              break;
            }
          }
        }
      }

      if (selectedResource == null) {
        // No matching resource found.
        String msg = "Could not find matching resource for " + requestPath;
        log.error(msg);
        throw new ResourceNotFoundException(msg);
      }

      resourceString = selectedResource.getDispatcherHelper().getString();
      resourceCacheKey =
          APIUtil.getResourceInfoDTOCacheKey(apiContext, apiVersion, resourceString, httpMethod);

      if (log.isDebugEnabled()) {
        log.debug("Selected Resource: ".concat(resourceString));
      }
      // Set the elected resource
      synCtx.setProperty(APIConstants.API_ELECTED_RESOURCE, resourceString);
    }
    verb = (VerbInfoDTO) getResourceCache().get(resourceCacheKey);

    // Cache hit
    if (verb != null) {
      if (log.isDebugEnabled()) {
        log.debug("Got Resource from cache for key: ".concat(resourceCacheKey));
      }
      // Set cache key in the message context so that it can be used by the subsequent handlers.
      synCtx.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey);
      return verb;
    }

    if (log.isDebugEnabled()) {
      log.debug("Cache miss for Resource for key: ".concat(resourceCacheKey));
    }

    String apiCacheKey = APIUtil.getAPIInfoDTOCacheKey(apiContext, apiVersion);
    APIInfoDTO apiInfoDTO = null;
    apiInfoDTO = (APIInfoDTO) getResourceCache().get(apiCacheKey);

    // Cache miss
    if (apiInfoDTO == null) {
      if (log.isDebugEnabled()) {
        log.debug("Could not find API object in cache for key: ".concat(apiCacheKey));
      }
      apiInfoDTO = doGetAPIInfo(apiContext, apiVersion);
      getResourceCache().put(apiCacheKey, apiInfoDTO);
    }
    if (apiInfoDTO.getResources() != null) {
      for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
        if ((resourceString.trim()).equalsIgnoreCase(resourceInfoDTO.getUrlPattern().trim())) {
          for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
            if (verbDTO.getHttpVerb().equals(httpMethod)) {
              if (log.isDebugEnabled()) {
                log.debug("Putting resource object in cache with key: ".concat(resourceCacheKey));
              }
              verbDTO.setRequestKey(resourceCacheKey);
              // Store verb in cache
              getResourceCache().put(resourceCacheKey, verbDTO);
              // Set cache key in the message context so that it can be used by the subsequent
              // handlers.
              synCtx.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey);
              return verbDTO;
            }
          }
        }
      }
    }
    return null;
  }