default void doScanCorps(CorpsAllData corpsAllData) throws IOException, InvalidDataException {

    //
    // Get data
    //
    StockManager stockManager = corpsAllData.getStockManager();
    List<StockRecord> lastData = corpsAllData.getLastData();
    FinanceManager financeManager = corpsAllData.getFinanceManager();
    Map<String, StockSplitInfo> stockCodeToSplitInfoMap =
        financeManager.getStockCodeToSplitInfoMap();
    String[] stockCodes = corpsAllData.getStockCodes();

    //
    // scan
    //
    printHeader();
    Calendar currentDay = CalendarUtil.createToday();
    int count = 0;
    for (int idxCorp = 0; idxCorp < stockCodes.length; ++idxCorp) {
      String stockCode = stockCodes[idxCorp];
      List<StockRecord> oneCorpRecords = null;
      if (stockManager != null) {
        oneCorpRecords = stockManager.retrieve(stockCode);
      }

      if (oneCorpRecords == null) {

      } else if (oneCorpRecords.size() == 0) {
        System.out.println("Warning: No stock price record for one corp. stockCode=" + stockCode);
      } else {
        String splitSerachStockCode = financeManager.toSplitSearchStockCode(stockCode);
        StockSplitInfo stockSplitInfo = stockCodeToSplitInfoMap.get(splitSerachStockCode);
        stockManager.calcAdjustedPricesForOneCorp(oneCorpRecords, stockSplitInfo, currentDay);
      }

      if (doScanOneCorp(stockCode, oneCorpRecords, stockManager, financeManager)) {
        ++count;
      }
    }
    printFooter(count);
  }
  private DetailRecord convertStringToRecord(Calendar dataGetDate) throws InvalidDataException {
    DetailRecord record = new DetailRecord();
    String org = null;
    String s = null;
    record.put(DetailEnum.DATA_GET_DATE, dataGetDate);

    try {
      // コード
      record.put(DetailEnum.STOCK_CODE, stockCodeStr);

      // 銘柄名
      record.put(DetailEnum.MARKET, marketStr);

      // 銘柄名
      record.put(DetailEnum.STOCK_NAME, stockNameStr);

      // 業種
      record.put(DetailEnum.SECTOR, sectorStr);

      // リアルタイム株価
      org = realtimePriceStr;
      if ((s = org) != null) {
        s = Util.substringChopStartIfMatch(s, "ストップ高");
        s = Util.substringChopStartIfMatch(s, "ストップ安");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.REALTIME_PRICE, Double.parseDouble(s));
        }
      }

      // 前日比
      org = priceComparisonWithPreviousDayStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "前日比");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.PRICE_COMPARISON_WITH_PREVIOUS_DAY, Double.parseDouble(s));
        }
      }

      // 前日終値
      org = previousClosingPriceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "ストップ高");
        s = Util.substringChopStartIfMatch(s, "ストップ安");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.PREVIOUS_CLOSING_PRICE, Double.parseDouble(s));
        }
      }

      // 始値
      org = openingPriceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "ストップ高");
        s = Util.substringChopStartIfMatch(s, "ストップ安");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.OPENING_PRICE, Double.parseDouble(s));
        }
      }

      // 高値
      org = highPriceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "ストップ高");
        s = Util.substringChopStartIfMatch(s, "ストップ安");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.HIGH_PRICE, Double.parseDouble(s));
        }
      }

      // 安値
      org = lowPriceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "ストップ高");
        s = Util.substringChopStartIfMatch(s, "ストップ安");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.LOW_PRICE, Double.parseDouble(s));
        }
      }

      // 出来高
      org = tradingVolumeOfStocksStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.TRADING_VOLUME_OF_STOCKS, Double.parseDouble(s));
        }
      }

      // 売買代金
      org = tradingValueOfMoneyStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "千円"); // thousand yen
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.TRADING_VALUE_OF_MONEY, Double.parseDouble(s));
        }
      }

      // 値幅制限
      org = priceLimitStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.removeCommaAndTrim(s);
        String[] ar = s.split("~");
        if (ar.length >= 1) {
          s = ar[0];
          if (!isNoDataInDetail(s)) {
            record.put(DetailEnum.LOW_PRICE_LIMIT, Double.parseDouble(s));
          }
        }
        if (ar.length >= 2) {
          s = ar[1];
          if (!isNoDataInDetail(s)) {
            record.put(DetailEnum.HIGH_PRICE_LIMIT, Double.parseDouble(s));
          }
        }
      }

      // 時価総額
      org = marketCapitalizationStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "百万円"); // million yen
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.MARKET_CAPITALIZATION, Double.parseDouble(s));
        }
      }

      // 発行済株式数
      org = outstandingStockVolumeStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.OUTSTANDING_STOCK_VOLUME, Double.parseDouble(s));
        }
      }

      // 配当利回り
      org = annualInterestRateStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "%");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.ANNUAL_INTEREST_RATE, Double.parseDouble(s));
        }
      }

      // 1株配当
      org = dividendsPerShareStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.DIVIDENDS_PER_SHARE, Double.parseDouble(s));
        }
      }

      // PER
      org = perStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "(連)");
        s = Util.substringChopStartIfMatch(s, "(単)");
        s = Util.substringChopEndIfMatch(s, "倍");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.PER, Double.parseDouble(s));
        }
      }

      // PBR
      org = pbrStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "(連)");
        s = Util.substringChopStartIfMatch(s, "(単)");
        s = Util.substringChopEndIfMatch(s, "倍");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.PBR, Double.parseDouble(s));
        }
      }

      // EPS
      org = epsStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "(連)");
        s = Util.substringChopStartIfMatch(s, "(単)");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.EPS, Double.parseDouble(s));
        }
      }

      // BPS
      org = bpsStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "(連)");
        s = Util.substringChopStartIfMatch(s, "(単)");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.BPS, Double.parseDouble(s));
        }
      }

      // ROE
      Double eps = (Double) record.get(DetailEnum.EPS);
      Double bps = (Double) record.get(DetailEnum.BPS);
      Double roe = null;
      if (eps != null && bps != null && bps != 0.0d) {
        roe = eps.doubleValue() / bps.doubleValue() * 100.0d;
      }
      if (roe != null) {
        record.put(DetailEnum.ROE, roe);
      }

      // 最低購入代金
      org = minimumPurchaseAmountStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.MINIMUM_PURCHASE_AMOUNT, Double.parseDouble(s));
        }
      }

      // 単元株数
      org = shareUnitNumberStr;
      if ((s = org) != null) {
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.SHARE_UNIT_NUMBER, Double.parseDouble(s));
        }
      }

      // 年初来高値
      org = yearlyHighStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "更新");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.YEARLY_HIGH, Double.parseDouble(s));
        }
      }

      // 年初来安値
      org = yearlyLowStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopStartIfMatch(s, "更新");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.YEARLY_LOW, Double.parseDouble(s));
        }
      }

      // 純資産
      org = netAssetsStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        if (!s.endsWith("百万円")) {
          // TODO: error or unknown data format
        }
        s = Util.substringChopEndIfMatch(s, "百万円"); // million yen
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.NET_ASSETS, Double.parseDouble(s));
        }
      }

      // 売買単位
      org = unitOfTradingStr;
      if ((s = org) != null) {
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.UNIT_OF_TRADING, Double.parseDouble(s));
        }
      }

      // 運用会社
      org = managementCompanyStr;
      if ((s = org) != null) {
        s = s.trim();
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.MANAGEMENT_COMPANY, s);
        }
      }

      // 投資対象資産
      org = typeOfAssetsToBeInvestedStr;
      if ((s = org) != null) {
        s = s.trim();
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.TYPE_OF_ASSETS_TO_BE_INVESTED, s);
        }
      }

      // 投資対象地域
      org = regionToBeInvestedStr;
      if ((s = org) != null) {
        s = s.trim();
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.REGION_TO_BE_INVESTED, s);
        }
      }

      // 連動対象
      org = underlyingIndexStr;
      if ((s = org) != null) {
        s = s.trim();
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.UNDERLYING_INDEX, s);
        }
      }

      // 決算頻度
      org = settlementFrequencyStr;
      if ((s = org) != null) {
        s = Util.substringChopEndIfMatch(s, "回");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.SETTLEMENT_FREQUENCY, Integer.parseInt(s));
        }
      }

      // 決算月
      org = settlementMonthStr; // Comma separated numerics, January is 1.
      if ((s = org) != null) {
        s = Util.substringChopEndIfMatch(s, "月");
        s = s.trim();
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.SETTLEMENT_MONTH, s);
        }
      }

      // 上場年月日
      org = listedDateStr;
      if ((s = org) != null) {
        s = Util.substringChopEndIfMatch(s, "日");
        s = s.trim();
        int year;
        int month;
        int day;
        if (s.length() != 0) {
          String[] p = s.split("年");
          if (p.length != 2) {
            throw new InvalidDataException(
                "Error: listedDateStr is invalid. listedDateStr=" + listedDateStr);
          }
          year = Integer.parseInt(p[0]);

          String[] q = p[1].split("月");
          if (p.length != 2) {
            throw new InvalidDataException(
                "Error: listedDateStr is invalid. listedDateStr=" + listedDateStr);
          }
          month = Integer.parseInt(q[0]) - 1; /* because January==0 */
          day = Integer.parseInt(q[1]);
          Calendar cal = CalendarUtil.createDay(year, month, day);

          if (!isNoDataInDetail(s)) {
            record.put(DetailEnum.LISTED_DATE, cal);
          }
        }
      }

      // 信託報酬(税抜)
      org = trustFeeStr;
      if ((s = org) != null) {
        s = Util.substringChopEndIfMatch(s, "%");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.TRUST_FEE, Double.parseDouble(s));
        }
      }

      // 信用買残
      org = marginDebtBalanceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.MARGIN_DEBT_BALANCE, Double.parseDouble(s));
        }
      }

      // 信用買残 前週比
      org = marginDebtBalanceRatioComparisonWithPreviousWeekStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(
              DetailEnum.MARGIN_DEBT_BALANCE_RATIO_COMPARISON_WITH_PREVIOUS_WEEK,
              Double.parseDouble(s));
        }
      }

      // 信用売残
      org = marginSellingBalanceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.MARGIN_SELLING_BALANCE, Double.parseDouble(s));
        }
      }

      // 信用売残 前週比
      org = marginSellingBalanceRatioComparisonWithPreviousWeekStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "株");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(
              DetailEnum.MARGIN_SELLING_BALANCE_RATIO_COMPARISON_WITH_PREVIOUS_WEEK,
              Double.parseDouble(s));
        }
      }

      // 貸借倍率
      org = ratioOfMarginBalanceStr;
      if ((s = org) != null) {
        s = Util.substringBeforeLastOpeningRoundParentheses(s);
        s = Util.substringChopEndIfMatch(s, "倍");
        s = Util.removeCommaAndTrim(s);
        if (!isNoDataInDetail(s)) {
          record.put(DetailEnum.RATIO_OF_MARGIN_BALANCE, Double.parseDouble(s));
        }
      }
    } catch (NumberFormatException e) {
      // TODO: debug
      System.out.println(
          "##### NumberFormatException was caused by : org="
              + org
              + " stockCodeStr="
              + stockCodeStr);
      throw e;
    }

    return record;
  }