/**
   * This method is going to return a ParsedOutputObject from arrays of bytes
   *
   * @param parseInputObject
   * @return
   */
  public static ParseOutputObject parse(ParseInputObject parseInputObject) {
    ParseOutputObject res = new ParseOutputObject();
    boolean error = false;

    if (parseInputObject == null || parseInputObject.getStatusMessagingList() == null) {
      throw new IllegalArgumentException(
          "Rp3UtilityParser.parse parseInputObject is invalid : " + parseInputObject);
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "Rp3UtilityParser parse beginning parseInputObject.getParseType() 			: "
              + parseInputObject.getParseType());
      LOG.debug("Rp3UtilityParser parse beginning FileName 			: " + parseInputObject.getFileName());
      LOG.debug(
          "Rp3UtilityParser parse beginning parseInputObject.getStatusMessagingList() : "
              + parseInputObject.getStatusMessagingList());
    }

    try {
      if (parseInputObject.getData() != null && parseInputObject.getData().length > 0) {
        String stringContent = new String(parseInputObject.getData());
        Scanner sc = new Scanner(stringContent);
        Integer contRow = 0;
        Integer contCol = 0;
        Map<String, List<DataObject>> mapDataByCol = new LinkedHashMap<String, List<DataObject>>();
        Map<String, List<DataObject>> mapDataByRow = new LinkedHashMap<String, List<DataObject>>();
        Map<Integer, List<DataObject>> mapDataByMatrix =
            new LinkedHashMap<Integer, List<DataObject>>();
        List<String> listColumnsNames = new ArrayList<String>();

        if (parseInputObject.getParseType() == PARSE_TYPES.QQ) {
          Rp3UtilityParser.parseQqLayout(res, sc, contRow, listColumnsNames);
        } else {
          Rp3UtilityParser.parseRowColumIdxLayout(
              parseInputObject,
              sc,
              contRow,
              contCol,
              mapDataByCol,
              mapDataByRow,
              mapDataByMatrix,
              listColumnsNames);
        }

        res.setMapDataByColName(mapDataByCol);
        res.setMapDataByRowFieldName(mapDataByRow);
        res.setMapDataByRowIndex(mapDataByMatrix);

      } else {
        StatusMessage statusMessaging =
            new StatusMessage(
                Rp3Constants.CODES_MSG.STATUS_MSG_LEVEL_METHOD.toString(),
                "util_b_001",
                Arrays.asList(
                    parseInputObject.getParseType().toString(), parseInputObject.getFileName()),
                1);
        parseInputObject.getStatusMessagingList().add(statusMessaging);
      }

    } catch (RuntimeException e) {
      error = true;
      LOG.error("Rp3UtilityParser parse error " + e.getMessage(), e);
      StatusMessage statusMessaging =
          new StatusMessage(
              Rp3Constants.CODES_MSG.STATUS_MSG_LEVEL_METHOD.toString(),
              "util_b_002",
              Arrays.asList(
                  parseInputObject.getParseType().toString(),
                  parseInputObject.getFileName(),
                  e.getMessage()),
              2);
      parseInputObject.getStatusMessagingList().add(statusMessaging);
    }

    if (!error) {
      StatusMessage statusMessaging =
          new StatusMessage(
              Rp3Constants.CODES_MSG.STATUS_MSG_LEVEL_METHOD.toString(),
              "util_b_003",
              Arrays.asList(
                  parseInputObject.getParseType().toString(), parseInputObject.getFileName()),
              0);
      parseInputObject.getStatusMessagingList().add(statusMessaging);
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "Rp3UtilityParser parse end parseInputObject.getStatusMessagingList() : "
              + parseInputObject.getStatusMessagingList());
      LOG.debug(
          "Rp3UtilityParser parse end parseInputObject.getParseType() : "
              + parseInputObject.getParseType());
    }

    return res;
  }
  /**
   * This method process text file for the qualifying question layout format
   *
   * @param res
   * @param sc
   * @param contRow
   * @param listColumnsNames
   */
  private static void parseQqLayout(
      ParseOutputObject res, Scanner sc, Integer contRow, List<String> listColumnsNames) {
    Integer contCol;
    QualifyingQuestionParseObjectDto qualifyingQuestionParseObjectDto =
        new QualifyingQuestionParseObjectDto();
    List<QualifyingQuestionModelDto> qualifyingQuestionModelDtoList =
        new ArrayList<QualifyingQuestionModelDto>();
    List<QualifyingQuestionDto> qualifyingQuestionDtoList = new ArrayList<QualifyingQuestionDto>();
    Map<String, Integer> mapTabCoordinate = new LinkedHashMap<String, Integer>();
    Map<String, QualifyingQuestionDto> lstQqDto =
        new LinkedHashMap<String, QualifyingQuestionDto>();
    Map<String, QualifyingQuestionModelDto> lstQqModelDto =
        new LinkedHashMap<String, QualifyingQuestionModelDto>();

    while (sc.hasNextLine()) {
      String valueX = sc.nextLine();
      contCol = 0;
      QualifyingQuestionDto qualifyingQuestionDto = null;
      QualifyingQuestionModelDto qualifyingQuestionModelDto = null;

      if (valueX.isEmpty() == false) {
        if (contRow == 0) {
          Scanner sc1 = new Scanner(valueX);
          sc1.useDelimiter("\\t");
          while (sc1.hasNext()) {
            String valueY = sc1.next();
            if (valueY != null && valueY.isEmpty() == false) {
              listColumnsNames.add(valueY);
              if (LOG.isDebugEnabled()) {
                LOG.debug("Rp3UtilityParser parse listColumnsNames : " + listColumnsNames);
              }
              mapTabCoordinate.put(valueY, contCol);
            }
            contCol++;
          }
          if (LOG.isDebugEnabled()) {
            LOG.debug("Rp3UtilityParser parse mapTabCoordinate : " + mapTabCoordinate);
          }
        } else {
          String[] arrayColsData = valueX.split("\\t");
          if (arrayColsData.length > 0) {

            if ((mapTabCoordinate.get("Panel ID") != null
                    && !arrayColsData[mapTabCoordinate.get("Option Labels")].isEmpty())
                && (mapTabCoordinate.get("Link to Panel") != null
                    && !arrayColsData[mapTabCoordinate.get("Link to Panel")].isEmpty())) {
              qualifyingQuestionDto = new QualifyingQuestionDto();
              qualifyingQuestionDto.setPanelID(arrayColsData[mapTabCoordinate.get("Panel ID")]);
              qualifyingQuestionDto.setOptionLabels(
                  arrayColsData[mapTabCoordinate.get("Option Labels")]);
              qualifyingQuestionDto.setLinkToPanel(
                  arrayColsData[mapTabCoordinate.get("Link to Panel")]);
              qualifyingQuestionDto.setCategoryGroup(
                  arrayColsData[mapTabCoordinate.get("Category Group")]);
              qualifyingQuestionDto.setDescription(
                  arrayColsData[mapTabCoordinate.get("Description")]);
              qualifyingQuestionDto.setRefId(UtilityRefIdGenerator.buildRefId());
            }
            if (LOG.isDebugEnabled()) {
              LOG.debug(
                  "Rp3UtilityParser parse arrayColsData : "
                      + Arrays.toString(arrayColsData)
                      + " length : "
                      + arrayColsData.length);
              LOG.debug("Rp3UtilityParser parse mapTabCoordinate : " + mapTabCoordinate);
            }

            if (arrayColsData.length == 9
                && (mapTabCoordinate.get("Panel ID_2") != null
                    && !arrayColsData[mapTabCoordinate.get("Panel ID_2")].isEmpty())
                && !arrayColsData[mapTabCoordinate.get("Link to Model")].isEmpty()
                && !arrayColsData[mapTabCoordinate.get("Stream ID")].isEmpty()) {
              qualifyingQuestionModelDto = new QualifyingQuestionModelDto();
              qualifyingQuestionModelDto.setPanelID(
                  arrayColsData[mapTabCoordinate.get("Panel ID_2")]);
              qualifyingQuestionModelDto.setLinkToModel(
                  arrayColsData[mapTabCoordinate.get("Link to Model")]);
              qualifyingQuestionModelDto.setStreamID(
                  arrayColsData[mapTabCoordinate.get("Stream ID")]);
              qualifyingQuestionModelDto.setRefId(UtilityRefIdGenerator.buildRefId());
            }
          }
        }
        contRow++;
        if (qualifyingQuestionDto != null) {
          qualifyingQuestionDtoList.add(qualifyingQuestionDto);
          lstQqDto.put(qualifyingQuestionDto.getRefId(), qualifyingQuestionDto);
        }

        if (qualifyingQuestionModelDto != null) {
          qualifyingQuestionModelDtoList.add(qualifyingQuestionModelDto);
          lstQqModelDto.put(qualifyingQuestionModelDto.getRefId(), qualifyingQuestionModelDto);
        }
      }
    }

    qualifyingQuestionParseObjectDto.setLstQqDto(lstQqDto);
    qualifyingQuestionParseObjectDto.setLstQqModelDto(lstQqModelDto);

    res.setQualifyingQuestionParseObjectDto(qualifyingQuestionParseObjectDto);
  }