// @Override
  public WOResponse handleRequest(WORequest request) {
    if (!ERSelenium.testsEnabled()) {
      return new WOResponse();
    }

    NSArray pathElements = request.requestHandlerPathArray();

    StringBuilder builder = new StringBuilder();
    Iterator iter = pathElements.iterator();
    while (iter.hasNext()) {
      builder.append(iter.next());
      if (iter.hasNext()) builder.append("/");
    }

    String filePath = builder.toString();
    log.debug("Processing file '" + filePath + "'");

    /*
     * Syncrhonization mistakes are possible here, but not fatal at all.
     * At the worst case the file will be read 2-or-more times instead of 1 (if process 1
     * checks that the file is not cached and process 2 does the same check before
     * process 1 has updated the cache).
     */

    CachedFile cachedFile;
    synchronized (_cache) {
      cachedFile = (CachedFile) _cache.objectForKey(filePath);
    }

    if (cachedFile == null) {
      cachedFile = new CachedFile();

      URL fileUrl =
          WOApplication.application()
              .resourceManager()
              .pathURLForResourceNamed(filePath, "ERSelenium", null);
      if (fileUrl == null) {
        throw new RuntimeException("Can't find specified resource ('" + filePath + "')");
      }
      cachedFile.mimeType =
          WOApplication.application().resourceManager().contentTypeForResourceNamed(filePath);
      if (cachedFile.mimeType == null) {
        throw new RuntimeException("Can't determine resource mime type ('" + filePath + "')");
      }

      try {
        cachedFile.data = new NSData(ERXFileUtilities.bytesFromInputStream(fileUrl.openStream()));
      } catch (Exception e) {
        throw new RuntimeException("Error reading file '" + fileUrl.getPath() + "'", e);
      }

      synchronized (_cache) {
        _cache.setObjectForKey(cachedFile, filePath);
      }
    }

    WOResponse response = new WOResponse();
    response.setHeader(cachedFile.mimeType, "content-type");
    response.setContent(cachedFile.data);

    NSNotificationCenter.defaultCenter()
        .postNotification(WORequestHandler.DidHandleRequestNotification, response);
    return response;
  }
  @Override
  public WOResponse handleRequest(WORequest request) {
    int bufferSize = 16384;

    WOApplication application = WOApplication.application();
    application.awake();
    try {
      WOContext context = application.createContextForRequest(request);
      WOResponse response = application.createResponseInContext(context);

      String sessionIdKey = application.sessionIdKey();
      String sessionId = (String) request.formValueForKey(sessionIdKey);
      if (sessionId == null) {
        sessionId = request.cookieValueForKey(sessionIdKey);
      }
      context._setRequestSessionID(sessionId);
      if (context._requestSessionID() != null) {
        application.restoreSessionWithID(sessionId, context);
      }

      try {
        final WODynamicURL url = request._uriDecomposed();
        final String requestPath = url.requestHandlerPath();
        final Matcher idMatcher = Pattern.compile("^id/(\\d+)/").matcher(requestPath);

        final Integer requestedAttachmentID;
        String requestedWebPath;

        final boolean requestedPathContainsAnAttachmentID = idMatcher.find();
        if (requestedPathContainsAnAttachmentID) {
          requestedAttachmentID = Integer.valueOf(idMatcher.group(1));
          requestedWebPath = idMatcher.replaceFirst("/");
        } else {
          // MS: This is kind of goofy because we lookup by path, your web path needs to
          // have a leading slash on it.
          requestedWebPath = "/" + requestPath;
          requestedAttachmentID = null;
        }

        try {
          InputStream attachmentInputStream;
          String mimeType;
          String fileName;
          long length;
          String queryString = url.queryString();
          boolean proxyAsAttachment =
              (queryString != null && queryString.contains("attachment=true"));

          EOEditingContext editingContext = ERXEC.newEditingContext();
          editingContext.lock();

          try {
            ERAttachment attachment =
                fetchAttachmentFor(editingContext, requestedAttachmentID, requestedWebPath);

            if (_delegate != null && !_delegate.attachmentVisible(attachment, request, context)) {
              throw new SecurityException("You are not allowed to view the requested attachment.");
            }
            mimeType = attachment.mimeType();
            length = attachment.size().longValue();
            fileName = attachment.originalFileName();
            ERAttachmentProcessor<ERAttachment> attachmentProcessor =
                ERAttachmentProcessor.processorForType(attachment);
            if (!proxyAsAttachment) {
              proxyAsAttachment = attachmentProcessor.proxyAsAttachment(attachment);
            }
            InputStream rawAttachmentInputStream =
                attachmentProcessor.attachmentInputStream(attachment);
            attachmentInputStream = new BufferedInputStream(rawAttachmentInputStream, bufferSize);
          } finally {
            editingContext.unlock();
          }

          response.setHeader(mimeType, "Content-Type");
          response.setHeader(String.valueOf(length), "Content-Length");

          if (proxyAsAttachment) {
            response.setHeader("attachment; filename=\"" + fileName + "\"", "Content-Disposition");
          }

          response.setStatus(200);
          response.setContentStream(attachmentInputStream, bufferSize, length);
        } catch (SecurityException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(403);
        } catch (NoSuchElementException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(404);
        } catch (FileNotFoundException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(404);
        } catch (IOException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(500);
        }

        return response;
      } finally {
        if (context._requestSessionID() != null) {
          WOApplication.application().saveSessionForContext(context);
        }
      }
    } finally {
      application.sleep();
    }
  }