/**
   * This method writes this object of <code>ApplicationStateDetails</code> to the specified output
   * stream object.
   *
   * @param out DataOutput object
   * @param versionNo
   * @throws IOException if an error occurs while converting data and writing it to a binary stream.
   * @since Tifosi2.0
   */
  public void toStream(DataOutput out, int versionNo) throws IOException {
    super.toStream(out, versionNo);

    out.writeLong(m_launchTime);
    out.writeLong(m_killTime);
    writeUTF(out, m_strAppGUID);
    writeUTF(out, m_strAppVersion);
    out.writeInt(m_serviceStates.size());

    Enumeration enums = m_serviceStates.keys();

    while (enums.hasMoreElements()) {
      String instName = (String) enums.nextElement();
      ServiceInstanceStateDetails status =
          (ServiceInstanceStateDetails) m_serviceStates.get(instName);

      UTFReaderWriter.writeUTF(out, instName);
      status.toStream(out, versionNo);
    }

    out.writeInt(m_serviceExceptionTraces.size());

    Enumeration traceEnums = m_serviceExceptionTraces.keys();

    while (traceEnums.hasMoreElements()) {
      String instName = (String) traceEnums.nextElement();
      String trace = (String) m_serviceExceptionTraces.get(instName);

      UTFReaderWriter.writeUTF(out, instName);
      UTFReaderWriter.writeUTF(out, trace);
    }

    out.writeInt(m_debugRoutes.size());
    Iterator debugRoutes = getDebugRoutes();

    while (debugRoutes.hasNext()) {
      String routeGUID = (String) debugRoutes.next();
      UTFReaderWriter.writeUTF(out, routeGUID);
    }

    out.writeInt(m_pendingDebugRoutesForClosure.size());
    Iterator pendingDebugRoutesForClosure = getPendingDebugRoutesForClosure();

    while (pendingDebugRoutesForClosure.hasNext()) {
      String routeGUID = (String) pendingDebugRoutesForClosure.next();
      UTFReaderWriter.writeUTF(out, routeGUID);
    }

    out.writeInt(m_previousSyncPeers.size());
    Iterator previousSynchPeers = getPreviousSynchPeers();
    while (previousSynchPeers.hasNext()) {
      String peerName = (String) previousSynchPeers.next();
      UTFReaderWriter.writeUTF(out, peerName);
    }
  }
  /**
   * This method reads this <code>ApplicationStateDetails</code> object from the specified input
   * stream object.
   *
   * @param is DataInput object
   * @param versionNo
   * @throws IOException if any error occurs while reading bytes or while converting them into
   *     specified Java primitive type.
   * @since Tifosi2.0
   */
  public void fromStream(DataInput is, int versionNo) throws IOException {
    super.fromStream(is, versionNo);

    m_launchTime = is.readLong();
    m_killTime = is.readLong();
    m_strAppGUID = readUTF(is);
    m_strAppVersion = readUTF(is);
    int hashTableSize = is.readInt();

    for (int i = 0; i < hashTableSize; i++) {
      ServiceInstanceStateDetails details = new ServiceInstanceStateDetails();
      String instName = UTFReaderWriter.readUTF(is);

      details.fromStream(is, versionNo);
      addServiceStatus(instName, details);
    }

    int tableSize = is.readInt();

    for (int i = 0; i < tableSize; i++) {
      addServiceExceptionTrace(UTFReaderWriter.readUTF(is), UTFReaderWriter.readUTF(is));
    }

    int debugRouteSize = is.readInt();
    for (int i = 0; i < debugRouteSize; i++) {
      addDebugRoute(UTFReaderWriter.readUTF(is));
    }

    int pendingRouteForClosureSize = is.readInt();
    for (int i = 0; i < pendingRouteForClosureSize; i++) {
      addDebugRoute(UTFReaderWriter.readUTF(is));
    }

    int previousSyncSize = is.readInt();
    for (int i = 0; i < previousSyncSize; i++) {
      m_previousSyncPeers.add(UTFReaderWriter.readUTF(is));
    }
  }