@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());
  }
  @Override
  public boolean verifyToken(PresentationToken t) throws TokenVerificationException {

    ObjectFactory of = new ObjectFactory();
    // System.out.println("Bridging verify token: "+t);
    try {
      //            String xml = XmlUtils.toXml(of.createPresentationToken(t), false);
      //            System.out.println(xml+"\n\n");

      String[] pseudonymEngines = this.getPseudonymEngines(t);

      boolean tokenContainsUProve = false;
      PresentationTokenWithCommitments idemixToken = of.createPresentationTokenWithCommitments();
      PresentationToken uproveToken = of.createPresentationToken();
      if (t.getVersion() == null) {
        uproveToken.setVersion("1.0");
        idemixToken.setVersion("1.0");
      } else {
        idemixToken.setVersion(t.getVersion());
        uproveToken.setVersion(t.getVersion());
      }
      PresentationTokenDescription desc = t.getPresentationTokenDescription();
      PresentationTokenDescription iDesc = of.createPresentationTokenDescription();
      PresentationTokenDescription uDesc = of.createPresentationTokenDescription();
      iDesc.setMessage(desc.getMessage());
      uDesc.setMessage(desc.getMessage());
      iDesc.setPolicyUID(desc.getPolicyUID());
      uDesc.setPolicyUID(desc.getPolicyUID());
      iDesc.setTokenUID(desc.getTokenUID());
      uDesc.setTokenUID(desc.getTokenUID());

      for (int i = 0; i < pseudonymEngines.length; i++) {
        PseudonymInToken pit = t.getPresentationTokenDescription().getPseudonym().get(i);
        if ("UPROVE".equals(pseudonymEngines[i])) {
          uDesc.getPseudonym().add(pit);
        } else {
          iDesc.getPseudonym().add(pit);
        }
      }

      this.verifierRevocation.clearCredentialInToken();

      Set<URI> idemixCredentialAliases = new HashSet<URI>();
      Set<URI> uproveCredentialAliases = new HashSet<URI>();
      for (CredentialInToken cit : desc.getCredential()) {

        this.verifierRevocation.addCredentialInToken(cit);

        /*
        try{
        	System.out.println("original: "+XmlUtils.toXml(of.createCredentialInToken(cit)));
        }catch(Exception e){System.out.println("failed to print original cit");};
         */
        if ((this.keyManager.getIssuerParameters(cit.getIssuerParametersUID()))
            .getAlgorithmID()
            .equals(CryptoUriUtil.getIdemixMechanism())) {
          idemixCredentialAliases.add(cit.getAlias());
          iDesc.getCredential().add(cit);
        } else {
          uproveCredentialAliases.add(cit.getAlias());
          uDesc.getCredential().add(cit);
          tokenContainsUProve = true;

          // Add issuer parameters to Idemix Structure store
          try {
            this.storeUProveIssuerParameters(cit.getIssuerParametersUID());
          } catch (Exception e) {
            System.out.println(
                "Failed to store UProve issuer parameters in Idemix structure store");
            throw new RuntimeException(e);
          }
        }
      }

      for (AttributePredicate ap : desc.getAttributePredicate()) {
        for (Object o : ap.getAttributeOrConstantValue()) {
          if (o instanceof AttributePredicate.Attribute) {
            iDesc.getAttributePredicate().add(ap);
            break;
          }
        }
      }

      // TODO This might require some changes to work with revocation
      for (VerifierDrivenRevocationInToken vdr : desc.getVerifierDrivenRevocation()) {
        for (AttributeInRevocation air : vdr.getAttribute()) {
          if (idemixCredentialAliases.contains(air.getCredentialAlias())) {
            iDesc.getVerifierDrivenRevocation().add(vdr);
            break;
          } else {
            uDesc.getVerifierDrivenRevocation().add(vdr);
          }
        }
      }

      // TODO Look at the uprove crypto evidence, if there are committed indices,
      // check with cred spec if they are for revocation handles
      // if so, do some stuff that allows poltransl and the other idemix parts to work

      idemixToken.setPresentationTokenDescriptionWithCommitments(this.addCommitments(iDesc));
      uproveToken.setPresentationTokenDescription(uDesc);

      boolean verifies = false;
      CryptoParams tcp = t.getCryptoEvidence();
      CryptoParams icp = of.createCryptoParams();
      boolean cryptoEvidenceContainsIdemix = false;
      for (Object o : tcp.getAny()) {
        try {
          if (o instanceof JAXBElement) {
            JAXBElement<?> jaxb = (JAXBElement<?>) o;
            Object wrapped = jaxb.getValue();
            if (wrapped instanceof CredentialInTokenWithCommitments) {
              cryptoEvidenceContainsIdemix = true;
              CredentialInTokenWithCommitments citwc = (CredentialInTokenWithCommitments) wrapped;
              idemixToken
                  .getPresentationTokenDescriptionWithCommitments()
                  .getCredential()
                  .add(
                      citwc); // (CredentialInTokenWithCommitments)XmlUtils.getObjectFromXML(credIn,
                              // false));
            } else {
              System.err.println(
                  "Element is JaxB : "
                      + jaxb.getValue()
                      + " : "
                      + jaxb.getDeclaredType()
                      + " : "
                      + jaxb.getScope()
                      + " : "
                      + jaxb.getName());
            }
            continue;
          }
          Element e = (Element) o;
          String elementName = e.getLocalName() != null ? e.getLocalName() : e.getNodeName();
          if ("UProveCredentialAndPseudonym".equals(elementName)) {
            String credAlias =
                ((Element) e.getElementsByTagName("Proof").item(0))
                    .getElementsByTagName("CredentialAlias")
                    .item(0)
                    .getTextContent();
            CredentialSpecification credSpec = null;
            CredentialInToken c = null;

            for (CredentialInToken cit : t.getPresentationTokenDescription().getCredential()) {
              if (cit.getAlias().toString().equals(credAlias)) {
                credSpec = this.keyManager.getCredentialSpecification(cit.getCredentialSpecUID());
                c = cit;
                break;
              }
            }

            if (credSpec == null) {
              throw new RuntimeException("Could not find credential specification.");
            }

            List<Integer> inspectableAttributes = new ArrayList<Integer>();
            Map<Integer, URI> indexToInspectorKey = new HashMap<Integer, URI>();
            Map<Integer, URI> indexToAttributeType = new HashMap<Integer, URI>();
            // TODO here we have to also look at any inspectable attributes.
            // If there are any, we need to create an inspectable information element etc.
            int revocationindex = -1;
            for (int i = 0;
                i < credSpec.getAttributeDescriptions().getAttributeDescription().size();
                i++) {
              AttributeDescription ad =
                  credSpec.getAttributeDescriptions().getAttributeDescription().get(i);

              if (ad.getType()
                  .toString()
                  .equals("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle")) {
                revocationindex = i;
              }
              for (AttributeInToken da : c.getDisclosedAttribute()) {
                if (da.getAttributeType().equals(ad.getType())
                    && (da.getInspectorPublicKeyUID() != null)) {
                  inspectableAttributes.add(i);
                  indexToInspectorKey.put(i, da.getInspectorPublicKeyUID());
                  indexToAttributeType.put(i, da.getAttributeType());
                }
              }
            }
            Set<Integer> committedValues = new HashSet<Integer>();
            committedValues.addAll(inspectableAttributes);
            if (!committedValues.contains(revocationindex) && (revocationindex != -1)) {
              committedValues.add(revocationindex);
            }
            Map<Integer, Integer> indexToIndexInProof = this.mapIndices(committedValues);

            if (e.getElementsByTagName("CommittedAttributesIndices").getLength() > 0) {
              Element cai = (Element) e.getElementsByTagName("CommittedAttributesIndices").item(0);
              NodeList nl = cai.getChildNodes();
              for (int j = 0; j < nl.getLength(); j++) {
                Element ind = null;
                try {
                  ind = (Element) nl.item(j);
                } catch (ClassCastException ex) {
                  // If we end up here, it is most likely because we got a TextElement which is
                  // empty due
                  // to malformed xml (such as \r or \n)
                  continue;
                }
                int committedIndex = Integer.parseInt(ind.getTextContent()) - 1;
                Element root = null;
                // make addToRoot method, to allow for inspectable revocationinformation
                if (committedIndex == revocationindex) {
                  root = ind.getOwnerDocument().createElement("RevocationInformation");
                } else if (inspectableAttributes.contains(committedIndex)) {
                  root = ind.getOwnerDocument().createElement("InspectableInformation");
                  root.setAttribute(
                      "InspectorPublicKey", indexToInspectorKey.get(committedIndex).toString());
                  root.setAttribute(
                      "AttributeType", indexToAttributeType.get(committedIndex).toString());
                } else {
                  // TODO: @Michael - explain this code a little :)
                  continue;
                }
                root.setAttribute("CredentialAlias", c.getAlias().toString());
                root.setAttribute("CredentialSpecUID", credSpec.getSpecificationUID().toString());
                root.setAttribute("IssuerParamsUID", c.getIssuerParametersUID().toString());

                Element tilde = root.getOwnerDocument().createElement("TildeO");
                root.appendChild(tilde);
                NodeList tildes = e.getElementsByTagName("TildeO").item(0).getChildNodes();
                //
                // System.out.println("got the tildeO nodes: "+tildes.getLength());

                tilde.appendChild(
                    tildes.item(indexToIndexInProof.get(committedIndex)).cloneNode(true));
                tilde = root.getOwnerDocument().createElement("TildeValues");
                root.appendChild(tilde);
                tildes = e.getElementsByTagName("TildeValues").item(0).getChildNodes();
                tilde.appendChild(
                    tildes.item((indexToIndexInProof.get(committedIndex) * 3)).cloneNode(true));
                icp.getAny().add(root);
              }
            }
          }

          if ("IdmxProof".equals(elementName)) {
            cryptoEvidenceContainsIdemix = true;
            icp.getAny().add(o);
          }
          if ("CredentialInTokenWithCommitments".equals(elementName)
              || "abc:CredentialInTokenWithCommitments".equals(elementName)) {
            cryptoEvidenceContainsIdemix = true;
            // magic code adding the CrednetialInToken
            TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            // create string from xml tree
            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(e.getOwnerDocument());
            trans.transform(source, result);
            String xmlString = sw.toString();

            InputStream credIn = new ByteArrayInputStream(xmlString.getBytes());
            idemixToken
                .getPresentationTokenDescriptionWithCommitments()
                .getCredential()
                .add((CredentialInTokenWithCommitments) XmlUtils.getObjectFromXML(credIn, false));
          }
          if ("VerifiableEncryption".equals(elementName)) {
            icp.getAny().add(o);
          }
        } catch (Exception e) {
          e.printStackTrace();
          // TODO @jdn, I think your revocation code causes some some serialization problems
          // /Michael
          // throw new RuntimeException(e);
        }
      }

      if (cryptoEvidenceContainsIdemix) {
        idemixToken.setCryptoEvidence(icp);

        //    System.out.println("\n\nNow verifying idmtoken!!");
        //	System.out.println(XmlUtils.toXml(of.createPresentationTokenWithCommitments(idemixToken),
        // false)+"\n\n");

        // System.out.println("about to call idmix engine for verification");
        // System.out.println("we have "+idemixToken.getCryptoEvidence().getAny().size()+" crypto
        // evidence");
        if (idemixToken.getCryptoEvidence().getAny().size() == 0) {
          verifies = true;
        } else {
          verifies = this.idemixEngine.verifyTokenWithCommitments(idemixToken);
        }
        System.out.println("idemix verifies: " + verifies);
      }

      if (tokenContainsUProve) {
        //                CryptoParams tcp = t.getCryptoEvidence();
        tcp = t.getCryptoEvidence();
        CryptoParams ucp = of.createCryptoParams();
        for (Object o : tcp.getAny()) {
          try {
            Element e = (Element) o;
            if (e.getNodeName().startsWith("UProve")) {
              ucp.getAny().add(o);
            }
          } catch (Exception e) {
          }
        }
        uproveToken.setCryptoEvidence(ucp);
        // System.out.println("Now verifying uprove");

        // xml = XmlUtils.toXml(of.createPresentationToken(uproveToken), false);
        // System.out.println(xml+"\n\n");

        boolean ver = this.uproveEngine.verifyToken(uproveToken);
        // System.out.println("uprove verifies: "+ver);
        if (cryptoEvidenceContainsIdemix) {
          verifies = verifies && ver;
        } else {
          verifies = ver;
        }
      }

      // System.out.println("DELEGATION VERIFIER.verifies:::: "+verifies);
      return verifies;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }