private void establishConnection(String url, boolean willRetryOnFailure) throws SQLException
 {
  if (!isEncryptionEnabled())
   jdbc = DriverManager.getConnection(url);
  else if (0 == encryptionPassword.length)
   throw new IllegalStateException(
     "The password is no longer available. Please set the password again before reconnecting.");
  else
  {
   Throwable status = null;
   final int length = encryptionPassword.length;
   final char[] passwordCopy = new char[length + 1];
   try
   {
    int errorPos = copyPassword(passwordCopy, encryptionPassword);
    if (0 <= errorPos)
     throw new IllegalArgumentException(
       "Character code " + (int)encryptionPassword[errorPos]
 	+ " is not allowed in a password, but found at position " + errorPos);
    passwordCopy[length] = ' ';
    // prepare the file password
    Properties properties = new Properties();
    // this violates the Properties contract, but does not leave copies of password in memory 
    properties.put("password", passwordCopy);
    jdbc = DriverManager.getConnection(url, properties);
   }
   catch (Throwable failure)
   {
    status = failure;
    if (failure instanceof Error)
     throw (Error)failure;
    if (failure instanceof SQLException)
     throw (SQLException)failure;
    if (failure instanceof RuntimeException)
     throw (RuntimeException)failure;    
    throw new Error("Unexpected object type thrown while connecting to \"" + url + '"', failure);    
   }
   finally
   {
    Arrays.fill(passwordCopy, '\0');
    if (!willRetryOnFailure || null == status)
     clearPassword();
   }
  }
 }