// engine method
 public void initialize(AlgorithmParameterSpec params, SecureRandom random)
     throws InvalidAlgorithmParameterException {
   if (serviceIterator == null) {
     spi.initialize(params, random);
     return;
   }
   Exception failure = null;
   KeyPairGeneratorSpi mySpi = spi;
   do {
     try {
       mySpi.initialize(params, random);
       initType = I_PARAMS;
       initKeySize = 0;
       initParams = params;
       initRandom = random;
       return;
     } catch (Exception e) {
       if (failure == null) {
         failure = e;
       }
       mySpi = nextSpi(mySpi, false);
     }
   } while (mySpi != null);
   if (failure instanceof RuntimeException) {
     throw (RuntimeException) failure;
   }
   // must be an InvalidAlgorithmParameterException
   throw (InvalidAlgorithmParameterException) failure;
 }
 // engine method
 public KeyPair generateKeyPair() {
   if (serviceIterator == null) {
     return spi.generateKeyPair();
   }
   RuntimeException failure = null;
   KeyPairGeneratorSpi mySpi = spi;
   do {
     try {
       return mySpi.generateKeyPair();
     } catch (RuntimeException e) {
       if (failure == null) {
         failure = e;
       }
       mySpi = nextSpi(mySpi, true);
     }
   } while (mySpi != null);
   throw failure;
 }
 /**
  * Update the active spi of this class and return the next implementation for failover. If no
  * more implemenations are available, this method returns null. However, the active spi of this
  * class is never set to null.
  */
 private KeyPairGeneratorSpi nextSpi(KeyPairGeneratorSpi oldSpi, boolean reinit) {
   synchronized (lock) {
     // somebody else did a failover concurrently
     // try that spi now
     if ((oldSpi != null) && (oldSpi != spi)) {
       return spi;
     }
     if (serviceIterator == null) {
       return null;
     }
     while (serviceIterator.hasNext()) {
       Service s = serviceIterator.next();
       try {
         Object inst = s.newInstance(null);
         // ignore non-spis
         if (inst instanceof KeyPairGeneratorSpi == false) {
           continue;
         }
         if (inst instanceof KeyPairGenerator) {
           continue;
         }
         KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi) inst;
         if (reinit) {
           if (initType == I_SIZE) {
             spi.initialize(initKeySize, initRandom);
           } else if (initType == I_PARAMS) {
             spi.initialize(initParams, initRandom);
           } else if (initType != I_NONE) {
             throw new AssertionError("KeyPairGenerator initType: " + initType);
           }
         }
         provider = s.getProvider();
         this.spi = spi;
         return spi;
       } catch (Exception e) {
         // ignore
       }
     }
     disableFailover();
     return null;
   }
 }
 // engine method
 public void initialize(int keysize, SecureRandom random) {
   if (serviceIterator == null) {
     spi.initialize(keysize, random);
     return;
   }
   RuntimeException failure = null;
   KeyPairGeneratorSpi mySpi = spi;
   do {
     try {
       mySpi.initialize(keysize, random);
       initType = I_SIZE;
       initKeySize = keysize;
       initParams = null;
       initRandom = random;
       return;
     } catch (RuntimeException e) {
       if (failure == null) {
         failure = e;
       }
       mySpi = nextSpi(mySpi, false);
     }
   } while (mySpi != null);
   throw failure;
 }