@Override
  public InputStream getInputStream(
      final ItsNatServletRequest itsNatServletRequest, final ItsNatServletResponse response) {
    final String domain;
    final InputStream returnVal;

    try {
      domain =
          new URI(
                  ((HttpServletRequest) itsNatServletRequest.getServletRequest())
                      .getRequestURL()
                      .toString())
              .getHost();
      if (domain.endsWith(ILIKEPLACES_COM)
          || domain.contains(LOCALHOST_8080)) { // Normal request on our website. Just forward.
        throw ExceptionCache.ILLEGAL_ACCESS_ERROR;
      } else {
        final URL url;

        TemplateSourceGeoBusinessType type = TemplateSourceGeoBusinessType.FullyImplementedHTML;

        switch (type) {
          case FullyImplementedHTML:
            url =
                new URL(
                    type.toString().replace(WWW_ILIKEPLACES_COM, WWW_ILIKEPLACES_COM)
                        + domain
                        + SLASH
                        + domain
                        + HTML);
            URLConnection conn = url.openConnection();
            HttpServletRequest httpRequest =
                (HttpServletRequest) itsNatServletRequest.getServletRequest();
            String userAgent = httpRequest.getHeader(USER_AGENT);
            conn.setRequestProperty(USER_AGENT, userAgent);
            returnVal = conn.getInputStream();
            break;
          case PiratesAttackingUsPirates:
            throw ExceptionCache
                .ILLEGAL_ACCESS_ERROR; // IMPLEMENT to string and redirect to pirate caught page
            // instead
          default:
            throw ExceptionCache.UNSUPPORTED_SWITCH;
        }
      }
    } catch (final URISyntaxException e) {
      Loggers.EXCEPTION.error(URISYNTAX_EXCEPTION, e);
      throw ExceptionCache.ILLEGAL_ACCESS_ERROR;
    } catch (final MalformedURLException e) {
      Loggers.EXCEPTION.error(MALFORMED_URLEXCEPTION, e);
      throw ExceptionCache.ILLEGAL_ACCESS_ERROR;
    } catch (final IOException e) {
      Loggers.EXCEPTION.error(IOEXCEPTION, e);
      throw ExceptionCache.ILLEGAL_ACCESS_ERROR;
    }

    return returnVal;
  }
  public void processWithDocument(ItsNatAttachedClientEvent event) {
    int phase = event.getPhase();
    if (phase == ItsNatAttachedClientEvent.REQUEST) {
      String[] msg = new String[1];
      if (event instanceof ItsNatAttachedClientTimerEvent) {
        ItsNatAttachedClientTimerEvent timerEvent = (ItsNatAttachedClientTimerEvent) event;
        boolean accepted = (timerEvent.getRefreshInterval() >= 3000);
        event.setAccepted(accepted);
        if (!accepted) msg[0] = "Refresh interval too short: " + timerEvent.getRefreshInterval();
      } else if (event instanceof ItsNatAttachedClientCometEvent) {
        event.setAccepted(true);
      } else // "none" refresh mode
      {
        event.setAccepted(true);
      }

      if (event.getWaitDocTimeout() > 30000) {
        event.setAccepted(false);
        msg[0] = "Too much time waiting for iframe/object/embed: " + event.getWaitDocTimeout();
      }

      ItsNatServletRequest request = event.getItsNatServletRequest();
      ServletRequest servRequest = request.getServletRequest();

      if (!event.isAccepted()) {
        ItsNatServletResponse response = event.getItsNatServletResponse();
        ItsNatServlet servlet = response.getItsNatServlet();
        @SuppressWarnings("unchecked")
        Map<String, String[]> newParams =
            new HashMap<String, String[]>(servRequest.getParameterMap());
        newParams.remove("itsnat_action"); // Removes: itsnat_action=attach_doc
        newParams.put("itsnat_doc_name", new String[] {"feashow.ext.core.misc.remCtrlReqRejected"});
        newParams.put("reason", msg); // submitted as array
        servRequest = servlet.createServletRequest(servRequest, newParams);
        servlet.processRequest(servRequest, response.getServletResponse());
      }
    } else if (phase == ItsNatAttachedClientEvent.REFRESH) {
      ClientDocument observer = event.getClientDocument();
      if (observer.getItsNatDocument().isInvalid()) {
        observer.addCodeToSend("alert('Observed document was destroyed');");
      } else {
        long initTime = observer.getCreationTime();
        long currentTime = System.currentTimeMillis();
        long limitMilisec = 15 * 60 * 1000;
        // 15 minutes (to avoid a long monitoring session)
        if (currentTime - initTime > limitMilisec) {
          event.setAccepted(false);
          observer.addCodeToSend("alert('Remote Control Timeout');\n");
        }
      }
    }
    // ItsNatAttachedClientEvent.LOAD & UNLOAD : nothing to do

    if (!event.isAccepted()) event.getItsNatEventListenerChain().stop(); // Not really necessary
  }
  public TestSerialization(ItsNatServletRequest request) {
    if (!TestSerializationConfig.enable) return;

    testSerialization(request);

    ItsNatDocument itsNatDoc = request.getItsNatDocument();
    itsNatDoc.addEventListener(this);
  }
  public static void testSerialization(ItsNatServletRequest request) {
    ClientDocument clientDoc = request.getClientDocument();
    // String file = "c:\\tmp\\itsnat_serialize_test.tmp";

    ByteArrayOutputStream ostream = null;
    ByteArrayInputStream istream = null;
    try {
      ItsNatSession session = clientDoc.getItsNatSession();

      ostream = new ByteArrayOutputStream();
      ObjectOutputStream p = new DebuggingObjectOutputStream(ostream);
      p.writeObject(session);
      // p.writeObject(clientDoc); // Write the tree to the stream.
      p.flush();
      ostream.close(); // close the file.

      Thread.sleep(500); // Para que se note que estamos haciendo este test

      byte[] stream = ostream.toByteArray();
      istream = new ByteArrayInputStream(stream);
      ObjectInputStream q =
          new ItsNatSessionObjectInputStream(
              istream); // ItsNatSessionObjectInputStream es INTERNO DE ITSNAT sólo usar para estas
                        // pruebas
      // clientDoc = (ClientDocument)q.readObject();
      session = (ItsNatSession) q.readObject();
      istream.close(); // close the file.
    } catch (Exception ex) {
      try {
        if (ostream != null) ostream.close();
        if (istream != null) istream.close();
      } catch (IOException ex2) {
        ex.printStackTrace();
        throw new RuntimeException(ex2);
      }
      throw new RuntimeException(ex);
    }
  }
 public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response) {
   new WAIARIADocument((ItsNatHTMLDocument) request.getItsNatDocument());
 }