/**
   * Note: Filter does not delegate to chain, since it would lead into cycle by calling {@link
   * PushServlet#service(ServletRequest, ServletResponse)}.
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
      HttpServletRequest httpReq = (HttpServletRequest) request;
      HttpServletResponse httpResp = (HttpServletResponse) response;

      if ("GET".equals(httpReq.getMethod())) {
        String pushSessionId = httpReq.getParameter(PUSH_SESSION_ID_PARAM);

        Session session = null;

        if (pushSessionId != null) {
          ensureServletContextAvailable(request);
          PushContext pushContext =
              (PushContext) servletContext.getAttribute(PushContext.INSTANCE_KEY_NAME);
          session = pushContext.getSessionManager().getPushSession(pushSessionId);
        }

        if (session == null) {
          if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(MessageFormat.format("Session {0} was not found", pushSessionId));
          }
          httpResp.sendError(HttpServletResponse.SC_BAD_REQUEST);
          return;
        }

        httpResp.setContentType("text/plain");

        Meteor meteor =
            Meteor.build(httpReq, SCOPE.REQUEST, Collections.<BroadcastFilter>emptyList(), null);

        try {
          Request pushRequest = new RequestImpl(meteor, session);

          httpReq.setAttribute(SESSION_ATTRIBUTE_NAME, session);
          httpReq.setAttribute(REQUEST_ATTRIBUTE_NAME, pushRequest);

          pushRequest.suspend();
        } catch (Exception e) {
          LOGGER.error(e.getMessage(), e);
        }

        return;
      }
    }
  }
 public static Meteor getMeteor(HttpServletRequest request) {
   return Meteor.build(request);
 }