/**
   * Load a trusted list for the specified URL
   *
   * @param url
   * @param signingCertList
   * @return
   * @throws java.io.IOException
   */
  private TrustStatusList getTrustStatusList(
      final String url, final List<X509Certificate> signingCertList) {

    byte[] bytes = dataLoader.get(url);
    if (bytes == null) {

      throw new DSSNullReturnedException(url);
    }
    final Document doc = DSSXMLUtils.buildDOM(bytes);

    boolean coreValidity = true;
    if (checkSignature) {

      coreValidity = false;
      if (signingCertList != null) {

        final CommonTrustedCertificateSource commonTrustedCertificateSource =
            new CommonTrustedCertificateSource();
        for (final X509Certificate x509Certificate : signingCertList) {

          commonTrustedCertificateSource.addCertificate(x509Certificate);
        }
        final CertificateVerifier certificateVerifier = new CommonCertificateVerifier(true);
        certificateVerifier.setTrustedCertSource(commonTrustedCertificateSource);

        final DSSDocument dssDocument = new InMemoryDocument(bytes);
        final XMLDocumentValidator xmlDocumentValidator = new XMLDocumentValidator(dssDocument);
        xmlDocumentValidator.setCertificateVerifier(certificateVerifier);
        // To increase the security: the default {@code XPathQueryHolder} is used.
        final List<XPathQueryHolder> xPathQueryHolders = xmlDocumentValidator.getXPathQueryHolder();
        xPathQueryHolders.clear();
        final XPathQueryHolder xPathQueryHolder = new XPathQueryHolder();
        xPathQueryHolders.add(xPathQueryHolder);

        final List<AdvancedSignature> signatures = xmlDocumentValidator.getSignatures();
        if (signatures.size() == 0) {

          throw new DSSException("Not ETSI compliant signature. The Xml is not signed.");
        }

        xmlDocumentValidator.validateDocument();
        final SimpleReport simpleReport = xmlDocumentValidator.getSimpleReport();
        final List<String> signatureIdList = simpleReport.getSignatureIds();
        final String signatureId = signatureIdList.get(0);
        final String indication = simpleReport.getIndication(signatureId);
        coreValidity = Indication.VALID.equals(indication);
        LOG.info("The TSL signature validity: " + coreValidity);
        if (!coreValidity) {

          LOG.info("The TSL signature validity details:\n" + simpleReport);
          System.out.println(xmlDocumentValidator.getDiagnosticData());
          throw new DSSException("Not ETSI compliant signature. The signature is not valid.");
        }
      }
    }
    final TrustStatusList tsl = TrustServiceListFactory.newInstance(doc);
    tsl.setWellSigned(coreValidity);
    return tsl;
  }
  /**
   * Adds a service entry (current or history) to the list of certificate tokens.
   *
   * @param cert the certificate which identifies the trusted service
   * @param trustedService Object defining the trusted service
   * @param tsProvider Object defining the trusted service provider, must be the parent of the
   *     trusted service
   * @param tlWellSigned Indicates if the signature of trusted list is valid
   */
  private synchronized void addCertificate(
      final X509Certificate cert,
      final AbstractTrustService trustedService,
      final TrustServiceProvider tsProvider,
      final boolean tlWellSigned) {

    try {
      final ServiceInfo serviceInfo = getServiceInfo(trustedService, tsProvider, tlWellSigned);
      super.addCertificate(cert, serviceInfo);
    } catch (DSSNotETSICompliantException ex) {

      LOG.error(
          "The entry for "
              + trustedService.getServiceName()
              + " doesn't respect ETSI specification "
              + ex.getLocalizedMessage());
    }
  }