/** Describe <code>onStart</code> method here. */
  public final void onStart() {
    super.onStart();
    MyLogger.logE(CLASS_TAG, "onStart():mParentFolderPath:" + mParentFolderPath);

    if (getCount() > 0) {
      File path = new File(mParentFolderPath + File.separator + mStoragePath);
      if (!path.exists()) {
        path.mkdirs();
      }

      File file = new File(path.getAbsolutePath() + File.separator + mStorageName);
      if (!file.exists()) {
        try {
          file.createNewFile();
        } catch (Exception e) {
          MyLogger.logE(CLASS_TAG, "onStart():file:" + file.getAbsolutePath());
          MyLogger.logE(CLASS_TAG, "onStart():create file failed");
        }
      }

      try {
        mWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
      } catch (Exception e) {
        MyLogger.logE(CLASS_TAG, "new BufferedWriter failed");
      }
    }
  }
  /** Describe <code>onEnd</code> method here. */
  public final void onEnd() {
    super.onEnd();
    try {
      MyLogger.logD(CLASS_TAG, "SmsBackupComposer onEnd");
      if (mWriter != null) {
        MyLogger.logE(CLASS_TAG, "mWriter.close()");
        mWriter.close();
      }
    } catch (Exception e) {
      MyLogger.logE(CLASS_TAG, "mWriter.close() failed");
    }

    for (Cursor cur : mSmsCursorArray) {
      if (cur != null) {
        cur.close();
        cur = null;
      }
    }
  }
  @Override
  /**
   * Describe <code>getCount</code> method here.
   *
   * @return an <code>int</code> value
   */
  public int getCount() {
    int count = 0;
    for (Cursor cur : mSmsCursorArray) {
      if (cur != null && !cur.isClosed() && cur.getCount() > 0) {
        count += cur.getCount();
      }
    }

    MyLogger.logD(CLASS_TAG, "getCount():" + count);
    return count;
  }
  @Override
  /**
   * Describe <code>isAfterLast</code> method here.
   *
   * @return a <code>boolean</code> value
   */
  public boolean isAfterLast() {
    boolean result = true;
    for (Cursor cur : mSmsCursorArray) {
      if (cur != null && !cur.isAfterLast()) {
        result = false;
        break;
      }
    }

    MyLogger.logD(CLASS_TAG, "isAfterLast():" + result);
    return result;
  }
  @Override
  /**
   * Describe <code>init</code> method here.
   *
   * @return a <code>boolean</code> value
   */
  public boolean init() {
    boolean result = false;
    for (int i = 0; i < mSmsUriArray.length; ++i) {
      mSmsCursorArray[i] =
          mContext.getContentResolver().query(mSmsUriArray[i], null, null, null, "date ASC");
      if (mSmsCursorArray[i] != null) {
        mSmsCursorArray[i].moveToFirst();
        result = true;
      }
    }

    MyLogger.logD(CLASS_TAG, "init():" + result + ",count:" + getCount());
    return result;
  }
  /**
   * Describe <code>implementComposeOneEntity</code> method here.
   *
   * @return a <code>boolean</code> value
   */
  public boolean implementComposeOneEntity() {
    boolean result = false;

    for (int i = 0; i < mSmsCursorArray.length; ++i) {
      if (mSmsCursorArray[i] != null && !mSmsCursorArray[i].isAfterLast()) {
        Cursor tmpCur = mSmsCursorArray[i];

        long mtime = tmpCur.getLong(tmpCur.getColumnIndex(COLUMN_NAME_DATE));

        String timeStamp = formatTimeStampString(mContext, mtime);

        int read = tmpCur.getInt(tmpCur.getColumnIndex(COLUMN_NAME_READ));
        String readByte = (read == 0 ? "UNREAD" : "READ");

        String seen = tmpCur.getString(tmpCur.getColumnIndex(COLUMN_NAME_SEEN));

        int box = tmpCur.getInt(tmpCur.getColumnIndex(COLUMN_NAME_TYPE));
        String boxType = null;
        switch (box) {
          case 1:
            boxType = "INBOX";
            break;

          case 2:
            boxType = "SENDBOX";
            break;

          default:
            boxType = "INBOX";
            break;
        }

        long simid = tmpCur.getLong(tmpCur.getColumnIndex(COLUMN_NAME_SIM_ID));
        String mSlotid = "0";
        if (FeatureOption.MTK_GEMINI_SUPPORT == true && simid >= 0) {
          int slot = SimInfoManager.getSlotById(mContext, simid);
          mSlotid = String.valueOf(slot + 1);
        }

        int lock = tmpCur.getInt(tmpCur.getColumnIndex(COLUMN_NAME_LOCKED));
        String locked = (lock == 1 ? "LOCKED" : "UNLOCKED");

        String smsAddress = null;
        if (i == 3) {
          String threadId = tmpCur.getString(tmpCur.getColumnIndex(COLUMN_NAME_THREAD_ID));
          Cursor draftCursor =
              mContext
                  .getContentResolver()
                  .query(
                      Uri.parse("content://sms"),
                      new String[] {TRICKY_TO_GET_DRAFT_SMS_ADDRESS + threadId + " --"},
                      null,
                      null,
                      null);

          if (draftCursor != null) {
            if (draftCursor.moveToFirst()) {
              smsAddress = draftCursor.getString(draftCursor.getColumnIndex(COLUMN_NAME_ADDRESS));
            }
            draftCursor.close();
          }
        } else {
          smsAddress = tmpCur.getString(tmpCur.getColumnIndex(COLUMN_NAME_ADDRESS));
        }

        if (smsAddress == null) {
          smsAddress = "";
        }

        String sc = tmpCur.getString(tmpCur.getColumnIndex(COLUMN_NAME_SC));

        String body = tmpCur.getString(tmpCur.getColumnIndex(COLUMN_NAME_BODY));

        StringBuffer sbf = new StringBuffer(body);
        int num = 0;
        num = sbf.indexOf("END:VBODY");
        do {
          if (num >= 0) {
            sbf.insert(num, "/");
          } else {
            break;
          }
        } while ((num = sbf.indexOf("END:VBODY", num + 1 + "END:VBODY".length())) >= 0);
        body = sbf.toString();

        try {
          if (mWriter != null) {
            mWriter.write(
                combineVmsg(timeStamp, readByte, boxType, mSlotid, locked, smsAddress, body, seen));
            result = true;
          }
        } catch (Exception e) {
          MyLogger.logE(CLASS_TAG, "mWriter.write() failed");
        } finally {
          tmpCur.moveToNext();
        }
        break;
      }
    }

    return result;
  }