// ------------------------------
  private void initialize(
      String user, String hashed_password, String userIp, HttpServletResponse res)
      throws Exception {

    sessionId_m =
        HtCommandProcessor.instance()
            .get_HtSecurityProxy()
            .remote_startUserSessionWithHashedPassword(user, hashed_password, userIp);

    if (sessionId_m == null) {
      throw new HtException(getContext(), "initialize", "Invalid user or password");
    }

    for (int i = 0; i < eventTypes_m.size(); i++) {
      RtGlobalEventManager.instance()
          .resolveListenerThread(RtGlobalEventManager.instance().MAIN_THREAD)
          .subscribeForEvent(eventTypes_m.get(i), 30, this);
    }

    // push event
    XmlEvent syncevent = new XmlEvent();
    syncevent.setEventType(XmlEvent.ET_SynchronizationEvent);
    RtGlobalEventManager.instance().pushCommonEvent(syncevent);

    // here we need to wait until the pending event will come through database layer to make sure
    // that we can select all data
    HtCommandProcessor.instance()
        .get_HtDatabaseProxy()
        .remote_waitDatabaseManagerWritePendingEvents(
            syncevent.getSequenceNumber(), WAIT_DB_PEND_EVENTS_SEC);
  }
  private void deinitialize() {

    // uninitialize
    try {
      RtGlobalEventManager.instance()
          .resolveListenerThread(RtGlobalEventManager.instance().MAIN_THREAD)
          .unsubscribeForAllEvents(30, this);
    } catch (Throwable e) {
      HtLog.log(
          Level.WARNING,
          getContext(),
          "deinitialize",
          "Error on unsubscribing: \"" + e.getMessage() + "\"");
    }

    try {
      if (sessionId_m != null) {
        HtCommandProcessor.instance().get_HtSecurityProxy().remote_stopUserSession(sessionId_m);
      }
    } catch (Throwable e) {
      HtLog.log(
          Level.WARNING,
          getContext(),
          "deinitialize",
          "Error on stop session: \"" + e.getMessage() + "\"");
    }

    queue_m.releaseMonitoring();
  }
  public boolean initialize_Get(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    res.setContentType("text/html; charset=windows-1251");
    forceNoCache(res);

    try {
      // new UID always

      generateUniquePageId();
      setStringSessionValue(getUniquePageId(), req, "provider_symbols", "");

      String operation = getStringParameter(req, "operation", true);
      if (operation.equalsIgnoreCase("do_read_for_profile")) {
        String profile_id = getStringParameter(req, "profile_id", false);
        List<HtPair<String, String>> providerSymbolList =
            HtCommandProcessor.instance()
                .get_HtDatabaseProxy()
                .remote_getStoredProvidersSymbols_ForProfile_FromHistory(profile_id);

        StringBuilder out = new StringBuilder();

        for (int i = 0; i < providerSymbolList.size(); i++) {
          out.append(providerSymbolList.get(i).first);
          out.append(",");
          out.append(providerSymbolList.get(i).second);

          if (i < (providerSymbolList.size() - 1)) out.append("\n");
        }

        setStringSessionValue(getUniquePageId(), req, "provider_symbols", out.toString());
      }

    } catch (Throwable e) {
      writeHtmlErrorToOutput(res, e);

      return false;
    }

    return true;
  } //
  private void readHistoryFromDBAndSend(final HttpServletResponse res, int eventType)
      throws Exception {

    HtXmlEventExchangePacket.Packet packet = new HtXmlEventExchangePacket.Packet();
    final HtXmlEventExchangePacket.DataListSerializator serializator =
        new HtXmlEventExchangePacket.DataListSerializator(packet);
    serializator.initizalize();

    final ServletOutputStream ostrm = res.getOutputStream();
    final HtHTTPEventPropagator pThis = this;

    // so far only XmlEvent.
    if (eventType == XmlEvent.ET_RtProviderTicker) {

      HtDataSelection dataselector =
          new HtDataSelection() {

            @Override
            public void onSelectionFinish(long cnt) throws Exception {

              if (cnt > 0) {
                serializator.finishSerialization(HtXmlEventExchangePacket.PACKET_LIST_RTDATA);

                HtXmlEventExchangePacket.writePacketToStream(serializator.getPacket(), ostrm, ll_m);

                // initialize again
                serializator.initizalize();
              }
            }

            @Override
            public void newRowArrived(
                long ttime,
                String tsymbol,
                String tprovider,
                int ttype,
                int aflag,
                double tbid,
                double task,
                double topen,
                double thigh,
                double tlow,
                double tclose,
                double topen2,
                double thigh2,
                double tlow2,
                double tclose2,
                double tvolume,
                long tid,
                int color,
                int operation)
                throws Exception {
              HtRtData rtdata =
                  new HtRtData(
                      ttime, tsymbol, tprovider, ttype, aflag, tbid, task, topen, thigh, tlow,
                      tclose, topen2, thigh2, tlow2, tclose2, tvolume, tid, color, operation);
              serializator.addNewEntry(HtRtData.serializeToBinary(rtdata));
            }
          };

      RtDataParameters clp =
          (RtDataParameters) eventFilterParameters_m.get(XmlEvent.ET_RtProviderTicker);
      if (clp == null) {
        throw new HtException(
            getContext(),
            "readHistoryFromDBAndSend",
            "Specific parameters for XmlEvent.ET_RtProviderTicker are not registered");
      }

      if (clp.do_read_history) {

        // now ready to read initial history
        HtCommandProcessor.instance()
            .get_HtDatabaseProxy()
            .remote_showDataAll_Callback_NoPaging(
                clp.profile_name_hist,
                new ArrayList<HtPair<String, String>>(),
                clp.begin_date_hist,
                clp.end_date_hist,
                dataselector,
                HISTORY_ROWS_CHUNK,
                true);
      } else {
        HtLog.log(
            Level.INFO,
            getContext(),
            "readHistoryFromDBAndSend",
            "User seleted not to read XmlEvent.ET_RtProviderTicker from DB");
      }

    } else if (eventType == XmlEvent.ET_DrawableObject) {
      DrawableObjectParameters clp =
          (DrawableObjectParameters) eventFilterParameters_m.get(XmlEvent.ET_DrawableObject);
      if (clp == null) {
        throw new HtException(
            getContext(),
            "readHistoryFromDBAndSend",
            "Specific parameters for XmlEvent.ET_DrawableObject are not registered");
      }

      HtDrawableObjectSelector drawableselector =
          new HtDrawableObjectSelector() {

            long cnt_m = 0;

            @Override
            public void onDrawableObjectArrived(HtDrawableObject dobj) throws Exception {
              XmlEvent event = new XmlEvent();
              HtDrawableObject.createXmlEventDrawableObject(dobj, event);

              if (pThis.debugstream_m != null) {
                pThis.writeDebugEntry(
                    "Creating history drawable object entry: " + dobj.toSmallDebugString());
              }

              // serialize

              serializator.addNewEntry(eventToBytes(event));

              if ((++cnt_m % HISTORY_ROWS_CHUNK) == 0) {
                // purge

                serializator.finishSerialization(HtXmlEventExchangePacket.PACKET_LIST_EVENTS);

                HtXmlEventExchangePacket.writePacketToStream(serializator.getPacket(), ostrm, ll_m);

                if (pThis.debugstream_m != null) {
                  pThis.writeDebugEntry(
                      "Sending drawable history chunk of the size: "
                          + serializator.getEntryCount());
                }

                // initialize again
                serializator.initizalize();
              }
            }

            @Override
            public void onFinish(long cntr) throws Exception {
              if (cntr > 0) {
                serializator.finishSerialization(HtXmlEventExchangePacket.PACKET_LIST_EVENTS);

                HtXmlEventExchangePacket.writePacketToStream(serializator.getPacket(), ostrm, ll_m);

                if (pThis.debugstream_m != null) {
                  pThis.writeDebugEntry(
                      "Sending drawable history (finish) chunk of the size: "
                          + serializator.getEntryCount());
                }

                // initialize again
                serializator.initizalize();
              }
            }
          };

      if (clp.do_read_history) {

        ArrayList<Integer> allowedTypes = new ArrayList<Integer>(clp.allowed_type);
        if (allowedTypes.size() == 1 && allowedTypes.get(0) == HtDrawableObject.DO_TEXT) {
          // for fast performance this serves text type only
          HtCommandProcessor.instance()
              .get_HtDatabaseProxy()
              .remote_showDrawableObjects_Callback_DO_TEXT(
                  clp.profile_name_hist,
                  new ArrayList<HtPair<String, String>>(),
                  true,
                  clp.begin_date_hist,
                  clp.end_date_hist,
                  clp.shortTextFilter,
                  clp.textFilter,
                  null,
                  null,
                  drawableselector,
                  -1,
                  -1);
        } else {

          // these servers all types
          HtCommandProcessor.instance()
              .get_HtDatabaseProxy()
              .remote_showDrawableObjects_Callback(
                  clp.profile_name_hist,
                  new ArrayList<HtPair<String, String>>(),
                  true,
                  clp.begin_date_hist,
                  clp.end_date_hist,
                  allowedTypes,
                  clp.shortTextFilter,
                  clp.textFilter,
                  null,
                  null,
                  drawableselector,
                  -1,
                  -1);
        }

      } else {
        HtLog.log(
            Level.INFO,
            getContext(),
            "readHistoryFromDBAndSend",
            "User seleted not to read XmlEvent.ET_DrawableObject from DB");
      }

    } else if (eventType == XmlEvent.ET_CommonLog) {

      HtCommonLogSelection datalogselector =
          new HtCommonLogSelection() {

            long cnt_m = 0;

            @Override
            public void newRowArrived(CommonLog commonLogRow) throws Exception {

              // HtLog.log(Level.INFO, this.getClass().getSimpleName(), "newRowArrived",
              // commonLogRow.getContent());

              XmlEvent event = new XmlEvent();
              CommonLog.createXmlEventCommonLog(commonLogRow, event);

              if (pThis.debugstream_m != null) {
                pThis.writeDebugEntry(
                    "Creating history log entry:" + commonLogRow.toSmallDebugString());
              }

              serializator.addNewEntry(eventToBytes(event));

              if ((++cnt_m % HISTORY_ROWS_CHUNK) == 0) {
                // purge

                serializator.finishSerialization(HtXmlEventExchangePacket.PACKET_LIST_EVENTS);

                HtXmlEventExchangePacket.writePacketToStream(serializator.getPacket(), ostrm, ll_m);

                if (pThis.debugstream_m != null) {
                  pThis.writeDebugEntry(
                      "Sending log history chunk of the size: " + serializator.getEntryCount());
                }

                // initialize again
                serializator.initizalize();
              }
            }

            @Override
            public void onFinish(long cntr) throws Exception {
              // purge the remainder
              if (cntr > 0) {
                serializator.finishSerialization(HtXmlEventExchangePacket.PACKET_LIST_EVENTS);

                HtXmlEventExchangePacket.writePacketToStream(serializator.getPacket(), ostrm, ll_m);

                if (pThis.debugstream_m != null) {
                  pThis.writeDebugEntry(
                      "Sending log history (finish) chunk of the size: "
                          + serializator.getEntryCount());
                }

                // initialize again
                serializator.initizalize();
              }
            }
          };

      CommonLogParameters clp =
          (CommonLogParameters) eventFilterParameters_m.get(XmlEvent.ET_CommonLog);
      if (clp == null) {
        throw new HtException(
            getContext(),
            "readHistoryFromDBAndSend",
            "Specific parameters for XmlEvent.ET_CommonLog are not registered");
      }

      // do not filter
      HtCommandProcessor.instance()
          .get_HtDatabaseProxy()
          .remote_getCommonLogDataPage_Callback(
              clp.contextFilter,
              clp.contentSmallFilter,
              clp.threadFilter,
              clp.level,
              clp.begin_date_hist,
              clp.end_date_hist,
              null,
              datalogselector,
              -1,
              -1,
              -1);
    } else {
      HtLog.log(
          Level.INFO,
          getContext(),
          "readHistoryFromDBAndSend",
          "This type of event cannot be read from DB");
    }

    // clean up everything
    serializator.discardSerialization();
  }
  public boolean initialize_Get(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    // res.setContentType("text/plain; charset=ISO-8859-1");
    // res.setContentType("application/octet-stream");
    forceNoCache(res);
    HtLog.log(Level.INFO, getContext(), "initialize_Get", "Started XML Event propagation servlet");
    ServletOutputStream ostrm = res.getOutputStream();

    res.setHeader("Transfer-Encoding", "chunked");
    res.setContentType("anybinary/type;charset=ISO-8859-1");
    res.flushBuffer();

    try {

      ll_m = new LengthListenerHelper(ostrm);

      // access
      String user = this.getStringParameter(req, "user", false);
      String hashed_password = this.getStringParameter(req, "hashed_password", false);
      String userIp = req.getRemoteHost();

      // common params

      boolean is_debug = this.getBooleanParameter(req, "is_debug", true);

      if (is_debug) {
        debugstream_m =
            new FileOutputStream(
                HtCommandProcessor.instance().get_HtConfigurationProxy().remote_getLogDirectory()
                    + File.separatorChar
                    + "HtHTTPEventPropagator_"
                    + Uid.generateNewStringUid()
                    + ".log",
                true);
      }

      writeDebugEntry("Request received: " + req.getQueryString());

      eventTypes_m = getIntListParameter(req, "event_types", false);

      initialize(user, hashed_password, userIp, res);

      // read history and init
      for (int i = 0; i < eventTypes_m.size(); i++) {
        if (eventTypes_m.get(i) == XmlEvent.ET_CommonLog) {
          CommonLogParameters clp = new CommonLogParameters();

          clp.contextFilter = getStringParameter(req, "context_filter", true);
          clp.contentSmallFilter = getStringParameter(req, "content_filter", true);
          clp.threadFilter = getStringParameter(req, "thread_filter", true);
          clp.level = (int) getIntParameter(req, "log_level", true);
          clp.begin_date_hist = getIntParameter(req, "begin_date_hist", false);
          clp.end_date_hist = getIntParameter(req, "end_date_hist", false);

          clp.initPatterns();

          //
          eventFilterParameters_m.put(XmlEvent.ET_CommonLog, clp);

        } else if (eventTypes_m.get(i) == XmlEvent.ET_RtProviderTicker) {

          RtDataParameters clp = new RtDataParameters();

          clp.do_read_history = this.getBooleanParameter(req, "do_read_history", false);
          if (clp.do_read_history) {
            // read other parameters
            clp.begin_date_hist = getIntParameter(req, "begin_date_hist", false);
            clp.end_date_hist = getIntParameter(req, "end_date_hist", false);
            clp.profile_name_hist = this.getStringParameter(req, "profile_name_hist", false);
          }

          // non obligatory
          List<String> allowed_symbols = getStringListParameter(req, "allowed_symbols", true);
          if (allowed_symbols.size() > 0) {
            clp.allowed_symbols_m = new HashSet<String>();
            clp.allowed_symbols_m.addAll(allowed_symbols);
          }

          eventFilterParameters_m.put(XmlEvent.ET_RtProviderTicker, clp);
        } else if (eventTypes_m.get(i) == XmlEvent.ET_DrawableObject) {
          DrawableObjectParameters clp = new DrawableObjectParameters();

          List<Integer> allowed_do_types = getIntListParameter(req, "allowed_do_types", false);
          clp.allowed_type.addAll(allowed_do_types);
          clp.do_read_history = getBooleanParameter(req, "do_read_history", false);

          // non obligatory
          List<String> allowed_symbols = getStringListParameter(req, "allowed_symbols", true);
          if (allowed_symbols.size() > 0) {
            clp.allowed_symbols_m = new HashSet<String>();
            clp.allowed_symbols_m.addAll(allowed_symbols);
          }

          clp.textFilter = getStringParameter(req, "text_filter", true);
          clp.shortTextFilter = getStringParameter(req, "short_text_filter", true);

          if (clp.do_read_history) {
            clp.begin_date_hist = getIntParameter(req, "begin_date_hist", false);
            clp.end_date_hist = getIntParameter(req, "end_date_hist", false);
            clp.profile_name_hist = this.getStringParameter(req, "profile_name_hist", false);
            clp.initPatterns();
          }

          eventFilterParameters_m.put(XmlEvent.ET_DrawableObject, clp);
        }

        readHistoryFromDBAndSend(res, eventTypes_m.get(i));
      }

      sendFinishReadHistoryFlag(res, ostrm);

      List list = new ArrayList();
      XmlEvent event = null;

      while (true) {

        queue_m.get(list, IDLE_TIME_SEC * 1000);

        for (Iterator it = list.iterator(); it.hasNext(); ) {

          event = (XmlEvent) it.next();

          if (event != null) {

            sendSingleEvent(res, event, ostrm);

            event = null;

          } else {

            sendHeartBeat(res, ostrm);
          }
        }

        if (list.isEmpty()) {
          sendHeartBeat(res, ostrm);
        }
      }

    } catch (Throwable e) {
      HtLog.log(
          Level.WARNING,
          getContext(),
          "initialize_Get",
          "Exception in XML Event propagation servlet: \"" + e.getMessage() + "\"");

      sendError("Exception in XML Event propagation servlet: \"" + e.getMessage() + "\"", res);
    }

    deinitialize();

    // close stream
    try {
      // finish chunked encoded
      ostrm.print("0\r\n\r\n");
      ostrm.close();
    } catch (Throwable e) {
    }

    writeDebugEntry("Processing finished");
    try {
      if (debugstream_m != null) {
        debugstream_m.flush();
        debugstream_m.close();
      }
    } catch (Throwable e2) {
    }

    HtLog.log(Level.INFO, getContext(), "initialize_Get", "Finished XML Event propagation servlet");
    return true;
  }