protected Criterion registerSourceKeyword(
      final Map<String, Account> accounts,
      final String accountId,
      final long campaignId,
      final long adGroupId,
      final long keywordId,
      final String keywordName) {
    Account account = accounts.get(accountId);
    if (account == null) {
      LOGGER.warn("Unknown accountId = {}. Keyword is skipped. Keyword = {}", accountId);
      return null;
    }

    Campaign campaign = account.getCampaigns().get(campaignId);
    if (campaign == null) {
      campaign = new CampaignImpl(account, campaignId);
    }

    AdGroup adGroup = campaign.getAdGroups().get(adGroupId);
    if (adGroup == null) {
      adGroup = new AdGroupImpl(campaign, adGroupId);
    }

    return new CriterionImpl(adGroup, keywordId, keywordName);
  }
  private Map<Long, AdGroupPerformance> initializeBaseReport(
      IDsaTrackerUserConfiguration userConfig, final Map<String, Account> accounts)
      throws Exception {
    if (userConfig.getDsaTracker().reinitializeBaseReport) {
      File baseReportFile = fsUtils.getResultFile(userConfig, "DsaBaseReport");
      LOGGER.info("Reinitialize base report");

      // update adGroups bids
      if (!userConfig.getIdleMode()) {
        adGroupBidUploaderService.uploadBids(
            userConfig,
            accounts
                .values()
                .stream()
                .flatMap(accountData -> accountData.getCampaigns().values().stream())
                .flatMap(campaignData -> campaignData.getAdGroups().values().stream()));
      }

      if (!configuration.dsaTracker.singleRunMod) {
        LOGGER.info(
            "Wait for data to accumulate (waitTime = "
                + userConfig.getDsaTracker().waitTime
                + " sec)...");
        Thread.sleep(userConfig.getDsaTracker().waitTime * 1000);
      }

      LocalDateTime dateOne = now();
      LocalDateTime dateTwo = dateOne.minusDays(REPORT_DAYS);
      Map<Long, AdGroupPerformance> baseReport =
          performanceDataLoader.downloadPerformanceData(
              accounts, dateTwo.toLocalDate(), dateOne.toLocalDate());

      for (Long key : baseReport.keySet()) {
        if (baseReport.get(key).adGroup == null) baseReport.remove(key);
      }

      for (Account account : accounts.values()) {
        for (Campaign campaign : account.getCampaigns().values()) {
          for (AdGroup adGroup : campaign.getAdGroups().values()) {
            if (baseReport.get(adGroup.getAdGroupId()) != null) continue;
            AdGroupPerformance adGroupPerformance = new AdGroupPerformance();
            Long campaignId = campaign.getCampaignId();
            Long adGroupId = adGroup.getAdGroupId();
            adGroupPerformance.adGroup =
                new AdGroupImpl(
                    new CampaignImpl(new AccountImpl(account.getAccountId()), campaignId),
                    adGroupId);
            adGroupPerformance.adGroup.setMetrics(
                new DsaMetrics() {
                  {
                    setMaxBid(0.0);
                  }
                });
            adGroupPerformance.hasConversions = false;
            adGroupPerformance.averageCpc = 0;
            adGroupPerformance.averagePosition = 0;
            adGroupPerformance.clicks = 0;
            adGroupPerformance.cost = 0;
            adGroupPerformance.impressions = 0;

            baseReport.put(adGroupId, adGroupPerformance);
          }
        }
      }

      baseReport
          .values()
          .forEach(
              r -> {
                DsaMetrics metrics = (DsaMetrics) r.adGroup.getMetrics();
                r.maxBaseCpc =
                    metrics.getMaxBid() * (1 + userConfig.getDsaTracker().maxCpcBidChange);
                r.minBaseCpc =
                    metrics.getMaxBid() * (1 - userConfig.getDsaTracker().maxCpcBidChange);
              });

      dsaTrackerUtils.saveBaseReport(baseReportFile, baseReport);
      ((DsaTrackerUserConfiguration) userConfig).baseReportFilePath =
          baseReportFile.getAbsolutePath();

      return baseReport;
    } else {
      LOGGER.info("Load base report from previous launch");
      File baseReportFile = new File(((DsaTrackerUserConfiguration) userConfig).baseReportFilePath);
      if (!baseReportFile.exists()) {
        throw new FileNotFoundException("Basic landscape report file does not exist");
      }

      return dsaTrackerUtils.loadBaseReport(baseReportFile, accounts);
    }
  }