@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());
  }
  /**
   * Performs the whole more or less adopted from the ancient tutorial.
   *
   * <p>Please don't change the order of the calls as it is relevant! To run this test you have to:
   * - have the services running (on tomcat) - have write access to the location where the STORAGE
   * resides - the STORAGE must be EMPTIED/CLEARED before running this. - the configuration needs to
   * be set-up to use FAKE identity and FAKE attribute source (because we check against hardcoded
   * values used in the Fake*Providers. (Please don't change the values in Fake*Providers without
   * reflecting the changes here and vice versa)).
   *
   * <p>Notes: This integration test tests the whole flow from setup to generation of
   * CredentialSpecification to IssuanceRequest to Verification. However, this test does not check
   * any intermediate results (other than ensuring that the webservices responded with the correct
   * status code) because this test assumes that if the final Verification process succeeds, the
   * test was successful. In other words: This test will obtain a Credential from the Issuance
   * service and verifies the obtained Credential against a PresentationPolicy at the Verification
   * service.
   *
   * @throws UnsupportedEncodingException
   * @throws InterruptedException
   * @throws JAXBException
   * @throws NamingException
   * @throws UniformInterfaceException
   * @throws ClientHandlerException
   */
  @Test
  public void flowTest()
      throws UnsupportedEncodingException, InterruptedException, JAXBException,
          ClientHandlerException, UniformInterfaceException, NamingException {
    System.out.println("hi there");

    /*
     * Test if all three services are running by calling /status/ on each
     * service and expecting a 200 response.
     */
    testUserStatus();
    testIssuanceStatus();
    testVerificationStatus();

    /*
     * Ok, if we are here all services are at least running
     */

    /* Test authentication */
    testAuthentication(readTextFile("/simpleAuth.xml"));

    /*
     * Get an attributeInfoCollection and convert it to a
     * credentialSpecification
     */
    final String attributeInfoCollection = testAttributeInfoCollection();
    final String credSpec = testGenCredSpec(attributeInfoCollection);

    /* Store/Get credentialSpecification at issuer */
    testStoreCredSpecAtIssuer(credSpec);
    testGetCredSpecFromIssuer();

    /* Store/Get queryRule at issuer */
    testStoreQueryRuleAtIssuer(readTextFile("/queryRule.xml"));
    testGetQueryRuleFromIssuer();

    /* Store/Get IssuancePolicy at issuer */
    testStoreIssuancePolicyAtIssuer(readTextFile("/issuancePolicy.xml"));
    testGetIssuancePolicyFromIssuer();

    /*
     * Ok, if we are here the first phase of setup is done.
     */

    /* Generate the SystemParameters */
    final String systemParameters = testSetupSystemParametersIssuer();

    /* Store CredentialSpecification at User and Verifier */
    testStoreCredSpecAtUser(credSpec);
    testStoreCredSpecAtVerifier(credSpec);

    /* Store SystemParameters at User and Verifier */
    testStoreSysParamsAtUser(systemParameters);
    testStoreSysParamsAtVerifier(systemParameters);

    /* Setup IssuerParameters */
    final String issuerParameters =
        testSetupIssuerParametersIssuer(readTextFile("/issuerParametersInput.xml"));
    System.out.println("--- issuerParameters");
    System.out.println(issuerParameters);

    /* Store IssuerParameters at User and Verifier */
    testStoreIssParamsAtUser(issuerParameters);
    testStoreIssParamsAtVerifier(issuerParameters);

    /*
     * Ok, phase two of setup is done (which means setup is done). Now the
     * actual issuance protocol can take place.
     */

    for (int i = 0; i < 3; i++) {
      final String issuanceMessageAndBoolean =
          testIssuanceRequest(readTextFile("/issuanceRequest.xml"));

      /* Extract issuance message */
      final String firstIssuanceMessage = testExtractIssuanceMessage(issuanceMessageAndBoolean);
      System.out.println("--- firstIssuanceMessage");
      System.out.println(firstIssuanceMessage);

      /* Issuance steps in the protocol */
      final String issuanceReturn = testIssuanceStepUser1(firstIssuanceMessage);
      String contextString = getContextString(issuanceReturn);
      System.out.println("--- issuanceReturn");
      System.out.println(issuanceReturn);
      System.out.println(contextString);

      String uiIssuanceReturn = readTextFile("/uiIssuanceReturn.xml");
      uiIssuanceReturn = replaceContextString(uiIssuanceReturn, contextString);
      System.out.println("--- uiIssuanceReturn");
      System.out.println(uiIssuanceReturn);

      final String secondIssuanceMessage = testIssuanceStepUserUi1(uiIssuanceReturn);
      System.out.println("--- secondIssuanceMessage");
      System.out.println(secondIssuanceMessage);

      final String thirdIssuanceMessageAndBoolean = testIssuanceStepIssuer1(secondIssuanceMessage);
      final String thirdIssuanceMessage =
          testExtractIssuanceMessage(thirdIssuanceMessageAndBoolean);

      @SuppressWarnings("unused")
      final String fourthIssuanceMessageAndBoolean = testIssuanceStepUser2(thirdIssuanceMessage);

      /* Verification stuff */
      final String presentationPolicyAlternatives =
          testCreatePresentationPolicy(readTextFile("/presentationPolicyAlternatives.xml"));
      testCreatePresentationPolicy(readTextFile("/presentationPolicyAlternatives.xml"));

      final String presentationReturn = testCreatePresentationToken(presentationPolicyAlternatives);
      contextString = getContextString(presentationReturn);
      System.out.println(contextString);

      String uiPresentationReturn = readTextFile("/uiPresentationReturn.xml");
      uiPresentationReturn = replaceContextString(uiPresentationReturn, contextString);

      final String presentationToken = testCreatePresentationTokenUi(uiPresentationReturn);

      final String rPresentationToken = presentationToken.replaceAll("<\\?xml(.*)\\?>", "");
      final String rPresentationPolicyAlternatives =
          presentationPolicyAlternatives.replaceAll("<\\?xml(.*)\\?>", "");

      String ppapt = "";
      ppapt += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
      ppapt +=
          "<PresentationPolicyAlternativesAndPresentationToken xmlns=\"http://abc4trust.eu/wp2/abcschemav1.0\" Version=\"1.0\">";
      ppapt += rPresentationPolicyAlternatives;
      ppapt += rPresentationToken;
      ppapt += "</PresentationPolicyAlternativesAndPresentationToken>";

      final String presentationTokenDescription = testVerifyTokenAgainstPolicy(ppapt);
      System.out.println(presentationTokenDescription);

      /* Verification stuff 2 */
      System.out.println("***********");
      System.out.println("***********");
      System.out.println("***********");
      System.out.println("***********");
      System.out.println("***********");

      testStorePresentationPolicyAlternatives(presentationPolicyAlternatives);

      System.out.println("!!!!!!!");

      for (int j = 0; j < 3; j++) {
        testStoreRedirectURI(
            "http://srv-lab-t-425.zhaw.ch:8080/zhaw-p2abc-webservices/demo-resource/page");
        final String presentationPolicyAlternatives_ = testRequestResource();

        final PresentationPolicyAlternatives ppa =
            (PresentationPolicyAlternatives)
                RESTHelper.fromXML(
                    PresentationPolicyAlternatives.class, presentationPolicyAlternatives_);

        final ApplicationData apd =
            ppa.getPresentationPolicy().get(0).getMessage().getApplicationData();
        System.out.println("APD: " + apd.getContent().get(0));

        final String presentationReturn_ =
            testCreatePresentationToken(presentationPolicyAlternatives_);
        final String contextString_ = getContextString(presentationReturn_);
        System.out.println(contextString_);

        String uiPresentationReturn_ = readTextFile("/uiPresentationReturn.xml");
        uiPresentationReturn_ = replaceContextString(uiPresentationReturn_, contextString_);

        final String presentationToken_ = testCreatePresentationTokenUi(uiPresentationReturn_);
        /*
         * PresentationToken presentationToken2 = (PresentationToken)
         * RESTHelper.fromXML(PresentationToken.class,
         * presentationToken_); System.out.println(";VI 0 is " +
         * presentationToken2
         * .getPresentationTokenDescription().getMessage
         * ().getVerifierIdentity().getContent().get(0));
         * presentationToken2
         * .getPresentationTokenDescription().getMessage
         * ().getVerifierIdentity().getContent().clear();
         * presentationToken2
         * .getPresentationTokenDescription().getMessage
         * ().getVerifierIdentity().getContent().add("urn:verifier:1");
         * presentationToken_ =
         * RESTHelper.toXML(PresentationToken.class,
         * of.createPresentationToken(presentationToken2));
         */

        final String presentationTokenDescription_ = testRequestResource2(presentationToken_);
        System.out.println("**#*#*#*#*#**#*#");
        System.out.println(presentationTokenDescription_);
      }

      testLoadSettingsVerification();
      testLoadSettingsUser();

      System.gc();
    }

    /* Test user credentials */
    CredentialCollection credCol =
        (CredentialCollection)
            RESTHelper.getRequest(userServiceURL + "credential/list", CredentialCollection.class);
    System.out.println("Found " + credCol.credentials.size() + " credentials!");
    List<Credential> creds = credCol.credentials;
    assertEquals(creds.size(), 3);
    for (final Credential c : creds) {
      String credUID = c.getCredentialDescription().getCredentialUID().toString();
      System.out.println(credUID);
      credUID = credUID.split("/")[1];
      final Credential c1 =
          (Credential)
              RESTHelper.getRequest(userServiceURL + "credential/get/" + credUID, Credential.class);
      assertEquals(
          c1.getCredentialDescription().getCredentialUID().toString().endsWith(credUID), true);
      RESTHelper.deleteRequest(userServiceURL + "credential/delete/" + credUID);
    }

    credCol =
        (CredentialCollection)
            RESTHelper.getRequest(userServiceURL + "credential/list", CredentialCollection.class);
    System.out.println("Found " + credCol.credentials.size() + " credentials!");
    creds = credCol.credentials;
    assertEquals(creds.size(), 0);

    // while(true) {
    // Thread.sleep(100);
    // }
  }