/**
   * This utility method is used to get the String representation of this object of <code>
   * ApplicationStateDetails</code>.
   *
   * @return The String representation of this object.
   * @since Tifosi2.0
   */
  public String toString() {
    String baseString = super.toString();
    StringBuffer strBuf = new StringBuffer();

    strBuf.append(baseString);
    strBuf.append("");
    strBuf.append("Application State Details = ");
    strBuf.append("[");
    strBuf.append("Launch Time = ");
    strBuf.append(m_launchTime);
    strBuf.append(", ");
    strBuf.append("Kill Time = ");
    strBuf.append(m_killTime);
    strBuf.append(", ");
    strBuf.append("Application GUID = ");
    strBuf.append(m_strAppGUID);
    strBuf.append(", ");
    strBuf.append("Application Version = ");
    strBuf.append(m_strAppVersion);
    strBuf.append(", ");

    Enumeration enums = m_serviceStates.keys();

    if (enums != null) {
      strBuf.append("Service States :: ");
      while (enums.hasMoreElements()) {
        String instName = (String) enums.nextElement();

        strBuf.append(instName);
        strBuf.append(", ");

        ServiceInstanceStateDetails status =
            (ServiceInstanceStateDetails) m_serviceStates.get(instName);

        strBuf.append(status.toString());
        strBuf.append(", ");
      }
    }

    Enumeration traceEnums = m_serviceExceptionTraces.keys();

    if (enums != null) {
      strBuf.append("Service Error Trace = ");
      while (traceEnums.hasMoreElements()) {
        String instName = (String) traceEnums.nextElement();

        strBuf.append(instName);
        strBuf.append(", ");

        String status = (String) m_serviceExceptionTraces.get(instName);

        strBuf.append(status);
        strBuf.append(", ");
      }
    }
    return strBuf.toString();
  }
  /**
   * 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));
    }
  }