code: private Cipher getCipher(int mode, Key key) {
  
          if (cipher == null) {
  
              try {
  
                  // Get a Cipher instance:
                  cipher = Cipher.getInstance(cipherName);
  
              } catch (NoSuchAlgorithmException e) {
                  if (SecurityProvider.addProvider()) {
                      cipher = getCipher(mode, key);
                  } else {
                      throw new IllegalStateException("Algorithm unavailable: " + cipherName, e);
                  }
              } catch (NoSuchPaddingException e) {
                  throw new IllegalStateException("Padding method unavailable: " + cipherName, e);
              }
          }
  
          // Initialise the Cipher
          try {
              cipher.init(mode, key);
          } catch (InvalidKeyException e) {
              throw new IllegalArgumentException("Invalid key used to initialise cipher.", e);
          }
  
          return cipher;
      }
docs: This method returns a {@link Cipher} instance, for {@value #CIPHER_ALGORITHM} in mode
  {@value #CIPHER_MODE}, with padding {@value #CIPHER_PADDING}.
  <p>
  It then initialises the {@link Cipher} in either {@link Cipher#ENCRYPT_MODE} or
  {@link Cipher#DECRYPT_MODE}), as specified by the mode parameter, with the given
  {@link SecretKey}.
  
  @param mode One of {@link Cipher#ENCRYPT_MODE} or {@link Cipher#DECRYPT_MODE}).
  @param key  Either a {@link PublicKey} or a {@link PrivateKey} to be used with the
  {@link Cipher}.
  @return A lazily-instantiated, cached {@link Cipher} instance.