@Test
  public void testReIssuance() throws Exception {
    int keyLength = 2048;
    SecretWrapper uproveSecretWrapper = new SecretWrapper(IntegrationTestUtil.getUProveSecret());

    UProveUtils uproveUtils = new UProveUtils();

    // Get Injectors,
    Injector revocationInjector =
        Guice.createInjector(
            IntegrationModuleFactory.newModule(
                new Random(1231), CryptoEngine.IDEMIX, uproveUtils.getUserServicePort()));
    RevocationProxyAuthority revocationProxyAuthority =
        revocationInjector.getInstance(RevocationProxyAuthority.class);

    Injector governmentInjector =
        Guice.createInjector(
            BridgingModuleFactory.newModule(
                new Random(1231),
                IssuerCryptoEngine.UPROVE,
                uproveUtils.getIssuerServicePort(),
                revocationProxyAuthority));

    Injector fakeInjector =
        Guice.createInjector(
            IntegrationModuleFactory.newModule(
                new Random(1231), CryptoEngine.IDEMIX, uproveUtils.getUserServicePort()));

    Injector userInjector =
        Guice.createInjector(
            BridgingModuleFactory.newModule(
                new Random(1231), uproveUtils.getUserServicePort(), revocationProxyAuthority));

    Injector verifierInjector =
        Guice.createInjector(
            BridgingModuleFactory.newModule(
                new Random(1231), uproveUtils.getVerifierServicePort(), revocationProxyAuthority));

    IssuerAbcEngine governmentEngine = governmentInjector.getInstance(IssuerAbcEngine.class);

    SystemParameters systemParameters =
        governmentEngine.setupSystemParameters(keyLength, CryptoUriUtil.getUproveMechanism());

    IssuerAbcEngine fakeEngine = fakeInjector.getInstance(IssuerAbcEngine.class);
    SystemParameters ideMixSystemParameters =
        fakeEngine.setupSystemParameters(keyLength, CryptoUriUtil.getIdemixMechanism());

    systemParameters.getAny().addAll(ideMixSystemParameters.getAny());

    // Load secret and store it.
    CredentialManager userCredentialManager = userInjector.getInstance(CredentialManager.class);

    IssuanceHelper issuanceHelper = new IssuanceHelper();

    // Setup key managers.
    KeyManager issuerKeyManager = governmentInjector.getInstance(KeyManager.class);
    KeyManager userKeyManager = userInjector.getInstance(KeyManager.class);
    KeyManager verifierKeyManager = verifierInjector.getInstance(KeyManager.class);
    KeyManager revocationKeyManager = revocationInjector.getInstance(KeyManager.class);

    issuerKeyManager.storeSystemParameters(systemParameters);
    userKeyManager.storeSystemParameters(systemParameters);
    verifierKeyManager.storeSystemParameters(systemParameters);
    revocationKeyManager.storeSystemParameters(systemParameters);

    // Setup issuance policies.
    IssuancePolicy issuancePolicyIdCard =
        getObjectFromXML(IntegrationTestUtil.ISSUANCE_POLICY_ID_CARD, true);

    URI idCardIssuancePolicyUid =
        issuancePolicyIdCard.getCredentialTemplate().getIssuerParametersUID();

    // Load credential specifications.
    CredentialSpecification credSpecIdCard =
        getObjectFromXML(IntegrationTestUtil.CREDENTIAL_SPECIFICATION_ID_CARD, true);

    // Store credential specifications.
    URI credSpecIdCardUID = credSpecIdCard.getSpecificationUID();
    issuerKeyManager.storeCredentialSpecification(credSpecIdCardUID, credSpecIdCard);
    verifierKeyManager.storeCredentialSpecification(credSpecIdCardUID, credSpecIdCard);

    // Generate revocation parameters.
    RevocationAbcEngine revocationEngine =
        revocationInjector.getInstance(RevocationAbcEngine.class);
    URI revParamsUid = IntegrationTestUtil.REVOCATION_PARAMETERS_UID;

    Reference revocationInfoReference = new Reference();
    revocationInfoReference.setReferenceType(URI.create("https"));
    revocationInfoReference.getReferences().add(URI.create("example.org"));
    Reference nonRevocationEvidenceReference = new Reference();
    nonRevocationEvidenceReference.setReferenceType(URI.create("https"));
    nonRevocationEvidenceReference.getReferences().add(URI.create("example.org"));
    Reference nonRrevocationUpdateReference = new Reference();
    nonRrevocationUpdateReference.setReferenceType(URI.create("https"));
    nonRrevocationUpdateReference.getReferences().add(URI.create("example.org"));
    RevocationAuthorityParameters revocationAuthorityParameters =
        revocationEngine.setupRevocationAuthorityParameters(
            keyLength,
            CryptoUriUtil.getIdemixMechanism(),
            revParamsUid,
            revocationInfoReference,
            nonRevocationEvidenceReference,
            nonRrevocationUpdateReference);

    // Generate issuer parameters.
    URI hash = new URI("urn:abc4trust:1.0:hashalgorithm:sha-256");
    IssuerParameters issuerParametersGovernment =
        governmentEngine.setupIssuerParameters(
            credSpecIdCard,
            systemParameters,
            idCardIssuancePolicyUid,
            hash,
            CryptoUriUtil.getUproveMechanism(),
            revParamsUid,
            null);

    issuerKeyManager.storeRevocationAuthorityParameters(
        revParamsUid, revocationAuthorityParameters);
    userKeyManager.storeRevocationAuthorityParameters(revParamsUid, revocationAuthorityParameters);
    verifierKeyManager.storeRevocationAuthorityParameters(
        revParamsUid, revocationAuthorityParameters);

    issuerKeyManager.storeIssuerParameters(idCardIssuancePolicyUid, issuerParametersGovernment);
    userKeyManager.storeIssuerParameters(idCardIssuancePolicyUid, issuerParametersGovernment);
    verifierKeyManager.storeIssuerParameters(idCardIssuancePolicyUid, issuerParametersGovernment);

    if (uproveSecretWrapper.isSecretOnSmartcard()) {
      // add smartcard to manager
      CardStorage cardStorage = userInjector.getInstance(CardStorage.class);
      cardStorage.addSmartcard(
          uproveSecretWrapper.getSoftwareSmartcard(), uproveSecretWrapper.getPin());

      // sign issuer attributes and add to smartcard
      uproveSecretWrapper.addIssuerParameters(issuerParametersGovernment);
    } else {
      userCredentialManager.storeSecret(uproveSecretWrapper.getSecret());
      // URI secretUid = secret.getSecretDescription().getSecretUID();
    }

    // Get identity card.
    String birthday = "1995-05-05Z";
    CredentialDescription cd3 =
        IntegrationTestUtil.issueAndStoreIdCard(
            governmentInjector, userInjector, issuanceHelper, birthday);

    Credential c = userCredentialManager.getCredential(cd3.getCredentialUID());
    System.out.println("Printing credential: " + c);
    System.out.println(
        "Cred Desc: "
            + XmlUtils.toXml(of.createCredentialDescription(c.getCredentialDescription())));
    System.out.println("CryptoParams size: " + c.getCryptoParams().getAny().size());
    System.out.println(
        "Arraylist size: " + ((ArrayList<?>) c.getCryptoParams().getAny().get(0)).size());

    // The verifier needs to retrive the latest revocation information
    // in order to put in the UID in the presentation policy.
    RevocationInformation revocationInformation =
        revocationEngine.updateRevocationInformation(revParamsUid);

    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
    useOneToken(
        userInjector,
        verifierInjector,
        issuanceHelper,
        revocationInformation,
        cd3.getCredentialUID());
  }
 private void storeUProveIssuerParameters(URI issuerParamsUID) throws Exception {
   IssuerParametersComposite ipc = null;
   IssuerParameters params = this.keyManager.getIssuerParameters(issuerParamsUID);
   UProveUtils utils = new UProveUtils();
   ipc = utils.convertIssuerParameters(params);
   StructureStore.getInstance().add(issuerParamsUID.toString(), ipc);
 }
  @Test()
  public void test() throws Exception {
    UProveUtils uproveUtils = new UProveUtils();
    Injector issuerInjector =
        Guice.createInjector(
            IntegrationModuleFactory.newModule(
                new Random(1231), uproveUtils.getIssuerServicePort()));
    Injector userInjector =
        Guice.createInjector(
            IntegrationModuleFactory.newModule(new Random(1231), uproveUtils.getUserServicePort()));
    Injector verifierInjector =
        Guice.createInjector(
            IntegrationModuleFactory.newModule(
                new Random(1231), uproveUtils.getVerifierServicePort()));

    // Step 1. Load the credit card specification into the keystore.
    CredentialSpecification creditCardSpec =
        (CredentialSpecification)
            XmlUtils.getObjectFromXML(
                this.getClass()
                    .getResourceAsStream(
                        "/eu/abc4trust/sampleXml/uprove/credentialSpecificationCreditcardVisa.xml"),
                true);

    KeyManager keyManager = issuerInjector.getInstance(KeyManager.class);
    keyManager.storeCredentialSpecification(creditCardSpec.getSpecificationUID(), creditCardSpec);

    KeyManager userKeyManager = userInjector.getInstance(KeyManager.class);
    userKeyManager.storeCredentialSpecification(
        creditCardSpec.getSpecificationUID(), creditCardSpec);

    // Step 2. Load the issuance policy and attributes.
    IssuancePolicy ip =
        (IssuancePolicy)
            XmlUtils.getObjectFromXML(
                this.getClass()
                    .getResourceAsStream(
                        "/eu/abc4trust/sampleXml/uprove/issuancePolicyCreditcardVisa.xml"),
                true);

    // Populate CreditCard attribute values..
    List<Attribute> issuerAtts = new ArrayList<Attribute>();
    this.populateAttributes(issuerAtts);

    // Step 3. Init the issuer
    IssuerAbcEngine issuerEngine = issuerInjector.getInstance(IssuerAbcEngine.class);

    ReloadTokensInMemoryCommunicationStrategy reloadTokens =
        (ReloadTokensInMemoryCommunicationStrategy)
            userInjector.getInstance(ReloadTokensCommunicationStrategy.class);
    reloadTokens.setIssuerAbcEngine(issuerEngine);
    reloadTokens.setIssuancePolicy(ip);

    int idemixKeyLength = 2048;
    int uproveKeylength = 2048;
    URI cryptographicMechanism = CryptoUriUtil.getUproveMechanism();
    SystemParameters sysParam =
        SystemParametersUtil.generatePilotSystemParameters_WithIdemixSpecificKeySize(
            idemixKeyLength, uproveKeylength);

    userKeyManager.storeSystemParameters(sysParam);
    keyManager.storeSystemParameters(sysParam);

    URI uid = ip.getCredentialTemplate().getIssuerParametersUID();

    URI hash = CryptoUriUtil.getHashSha256();
    URI revocationId = new URI("issuer-cpr-rev-id");

    IssuerParameters issuerParameters =
        issuerEngine.setupIssuerParameters(
            creditCardSpec, sysParam, uid, hash, cryptographicMechanism, revocationId, null);

    // Store received issuer parameters in all keymanagers...
    keyManager.storeIssuerParameters(issuerParameters.getParametersUID(), issuerParameters);
    userKeyManager.storeIssuerParameters(issuerParameters.getParametersUID(), issuerParameters);

    KeyManager verifierKeyManager = verifierInjector.getInstance(KeyManager.class);
    verifierKeyManager.storeIssuerParameters(issuerParameters.getParametersUID(), issuerParameters);
    verifierKeyManager.storeSystemParameters(sysParam);

    // Step 4. Issue a credit card credential.
    UserAbcEngine userEngine = userInjector.getInstance(UserAbcEngine.class);

    this.doIssuanceProtocol(issuerEngine, userEngine, ip, issuerAtts);

    // Step 5. Generate a PresentationToken using a simple HotelBooking Policy with creditcard only
    // credential

    PresentationPolicyAlternatives presentationPolicyAlternatives =
        (PresentationPolicyAlternatives)
            XmlUtils.getObjectFromXML(
                this.getClass()
                    .getResourceAsStream(
                        "/eu/abc4trust/sampleXml/uprove/presentationPolicySimpleHotelBookingCreditCardOnly.xml"),
                true);

    PresentationToken presentationToken =
        userEngine.createPresentationToken(presentationPolicyAlternatives);

    // FIXME: Using createPresentationToken again with the same presentationPolicyAlternatives
    // causes a crash in MockIdentitySelection

    // PresentationToken presentationToken1 =
    // userEngine.createPresentationToken(presentationPolicyAlternatives);

    PresentationPolicyAlternatives presentationPolicyAlternatives2 =
        (PresentationPolicyAlternatives)
            XmlUtils.getObjectFromXML(
                this.getClass()
                    .getResourceAsStream(
                        "/eu/abc4trust/sampleXml/uprove/presentationPolicySimpleHotelBookingCreditCardOnlyNoPseudonym.xml"),
                true);

    PresentationToken presentationToken2 =
        userEngine.createPresentationToken(presentationPolicyAlternatives2);

    // We have run out of UProveTokens and must renew credential
    if (presentationToken2 == null) {
      this.doIssuanceProtocol(issuerEngine, userEngine, ip, issuerAtts);
      presentationToken2 = userEngine.createPresentationToken(presentationPolicyAlternatives2);
    }

    // Step 6. Verify the generated PresentationToken

    // Init the Issuer engine
    VerifierAbcEngine verifierEngine = verifierInjector.getInstance(VerifierAbcEngine.class);
    boolean verifyOK = true;
    try {
      PresentationTokenDescription verifyResult =
          verifierEngine.verifyTokenAgainstPolicy(
              presentationPolicyAlternatives, presentationToken, false);
      assertNotNull(verifyResult);
    } catch (TokenVerificationException ex) {
      verifyOK = false;
      System.out.println("Token Verify FAILED!!");
    }
    assertTrue(verifyOK);

    try {
      PresentationTokenDescription verifyResult2 =
          verifierEngine.verifyTokenAgainstPolicy(
              presentationPolicyAlternatives2, presentationToken2, false);
      assertNotNull(verifyResult2);
    } catch (TokenVerificationException ex) {
      verifyOK = false;
      System.out.println("Token Verify FAILED!!");
    }
    assertTrue(verifyOK);

    //        // try to shut down UProve Services...
    //        int exitCode = userInjector.getInstance(UProveBindingManager.class).stop();
    //        assertEquals("U-Prove exe must have exit code 0", 0, exitCode);
    //        exitCode = issuerInjector.getInstance(UProveBindingManager.class).stop();
    //        assertEquals("U-Prove exe must have exit code 0", 0, exitCode);
    //        exitCode = verifierInjector.getInstance(UProveBindingManager.class).stop();
    //        assertEquals("U-Prove exe must have exit code 0", 0, exitCode);

  }