/**
   * Loads TSL certificates If configuration mode is TEST then TSL signature is not checked.
   *
   * @return TSL source
   */
  public TSLCertificateSource getTSL() {
    logger.debug("");
    if (tslCertificateSource != null) {
      logger.debug("Using TSL cached copy");
      return tslCertificateSource;
    }

    tslCertificateSource = new TSLCertificateSource();
    tslCertificateSource.setTslRefreshPolicy(TSLRefreshPolicy.WHEN_NECESSARY);

    String tslLocation = getTslLocation();
    if (Protocol.isHttpUrl(tslLocation)) {
      FileCacheDataLoader dataLoader = new FileCacheDataLoader();
      dataLoader.setConnectTimeout(getConnectionTimeout());
      dataLoader.setFileCacheDirectory(TSLCertificateSource.fileCacheDirectory);
      tslCertificateSource.setTslRefreshPolicy(TSLRefreshPolicy.NEVER);
      tslCertificateSource.setDataLoader(dataLoader);
    } else {
      tslCertificateSource.setDataLoader(new CommonsDataLoader());
    }

    tslCertificateSource.setLotlUrl(tslLocation);

    tslCertificateSource.setCheckSignature(false);

    try {
      tslCertificateSource.init();
    } catch (DSSException e) {
      logger.error(e.getMessage());
      throw new DigiDoc4JException(e.getMessage());
    }

    return tslCertificateSource;
  }
  /** Load the certificates contained in all the TSL referenced by the LOTL */
  public void init() {

    diagnosticInfo.clear();

    X509Certificate lotlCert = null;
    if (checkSignature) {

      lotlCert = readLOTLCertificate();
    }
    TrustStatusList lotl;
    try {

      LOG.info("Downloading LOTL from url= {}", lotlUrl);
      final ArrayList<X509Certificate> x509CertificateList = new ArrayList<X509Certificate>();
      x509CertificateList.add(lotlCert);
      lotl = getTrustStatusList(lotlUrl, x509CertificateList);
    } catch (DSSException e) {

      LOG.error("The LOTL cannot be loaded: " + e.getMessage(), e);
      throw e;
    }
    diagnosticInfo.put(lotlUrl, "Loaded " + new Date().toString());
    final int size = lotl.getOtherTSLPointers().size();
    //        final ExecutorService executorService = Executors.newFixedThreadPool(size);
    //        List<Future> futures = new ArrayList<Future>(size);
    for (final PointerToOtherTSL pointerToTSL : lotl.getOtherTSLPointers()) {
      //            Runnable runnable = new Runnable() {
      //                public void run() {

      final String url = pointerToTSL.getTslLocation();
      final String territory = pointerToTSL.getTerritory();
      final List<X509Certificate> signingCertList = pointerToTSL.getDigitalIdentity();
      try {

        loadTSL(url, territory, signingCertList);
      } catch (DSSException e) {
        LOG.error("Error loading trusted list for {} at {}", new Object[] {territory, url, e});
        // do nothing continue with the next trusted list.
      }

      //                }
      //            };
      //            final Future submit = executorService.submit(runnable);
      //            futures.add(submit);
    }

    //        executorService.shutdown();
    //        while (!executorService.isTerminated()){
    //            try {
    //                Thread.sleep(100);
    //            } catch (InterruptedException e) {
    //                throw new RuntimeException(e);
    //            }
    //        }
    //        LOG.info("Parallel download of Trusted list done");
    loadAdditionalLists();
    LOG.info("Loading completed: {} trusted lists", size);
    LOG.info("                 : {} certificates", certPool.getNumberOfCertificates());
  }
  public void doRefreshPrivateKeys() {

    try {
      final SignatureTokenConnection tokenConnection = getModel().getTokenConnection();
      getModel().setPrivateKeys(tokenConnection.getKeys());
    } catch (final DSSException e) {
      // FIXME
      LOG.error(e.getMessage(), e);
    }
  }
  /**
   * Adds all the service entries (current and history) of all the providers of the trusted list to
   * the list of CertificateSource
   *
   * @param trustStatusList
   */
  private void loadAllCertificatesFromOneTSL(final TrustStatusList trustStatusList) {

    for (final TrustServiceProvider trustServiceProvider :
        trustStatusList.getTrustServicesProvider()) {

      for (final AbstractTrustService trustService : trustServiceProvider.getTrustServiceList()) {

        if (LOG.isTraceEnabled()) {
          LOG.trace("### " + trustService.getServiceName());
          LOG.trace("------> " + trustService.getType());
          LOG.trace("------> " + trustService.getStatus());
        }

        for (final Object digitalIdentity : trustService.getDigitalIdentity()) {

          try {

            X509Certificate x509Certificate = null;
            if (digitalIdentity instanceof X509Certificate) {

              x509Certificate = (X509Certificate) digitalIdentity;
            } else if (digitalIdentity instanceof X500Principal) {

              final X500Principal x500Principal = (X500Principal) digitalIdentity;
              final List<CertificateToken> certificateTokens = certPool.get(x500Principal);
              if (certificateTokens.size() > 0) {
                x509Certificate = certificateTokens.get(0).getCertificate();
              } else {
                LOG.warn(
                    "There is currently no certificate with the given X500Principal: '{}' within the certificate pool!",
                    x500Principal);
              }
            }
            if (x509Certificate != null) {

              addCertificate(
                  x509Certificate,
                  trustService,
                  trustServiceProvider,
                  trustStatusList.isWellSigned());
            }
          } catch (DSSException e) {

            // There is a problem when loading the certificate, we continue with the next one.
            LOG.warn(e.getLocalizedMessage());
          }
        }
      }
    }
  }