class CredentialManagerImpl implements CredentialManager,
		Observable<KeystoreChangedEvent> {

	@Override
	public void changeMasterPassword(String newMasterPassword)
			throws CMException {
		// Need to make sure we are initialized before we do anything else
		// as Credential Manager can be created but not initialized
		initialize();

		String oldMasterPassword = masterPassword;
		KeyStore oldKeystore = keystore;
		KeyStore oldTruststore = truststore;

		try {
			synchronized (keystore) {
				// Create a new keystore and copy all items from the current
				// one, encrypting them with the new password
				KeyStore newKeystore = null;
				try {
					// Try to create Taverna's Keystore as Bouncy Castle
					// UBER-type keystore.
					newKeystore = KeyStore.getInstance("UBER", "BC");
				} catch (Exception ex) {
					// The requested keystore type is not available from
					// security providers.
					String exMessage = "Failed to instantiate a new Bouncy Castle Keystore when changing master password.";
					throw new CMException(exMessage, ex);
				}
				try {
					// Initialize a new empty keystore
					newKeystore.load(null, null);
				} catch (Exception ex) {
					String exMessage = "Failed to create a new empty Keystore to copy over the entries from the current one.";
					throw new CMException(exMessage, ex);
				}

				Enumeration<String> aliases = keystore.aliases();
				while (aliases.hasMoreElements()) {
					String alias = aliases.nextElement();
					if (REALLY_DISABLED) {
						if (alias.startsWith("password#")) { // a password entry
							SecretKeySpec passwordKey = (((SecretKeySpec) keystore
									.getKey(alias, masterPassword.toCharArray())));
							newKeystore.setKeyEntry(alias, passwordKey,
									newMasterPassword.toCharArray(), null);
						} else if (alias.startsWith("keypair#")) { // a private key entry
							// Get the private key for the alias
							PrivateKey privateKey = (PrivateKey) keystore
									.getKey(alias, masterPassword.toCharArray());
							// Get the related public key's certificate chain
							Certificate[] certChain = keystore
									.getCertificateChain(alias);
							newKeystore.setKeyEntry(alias, privateKey,
									newMasterPassword.toCharArray(), certChain);
						}
					}
					// Do all entries at once, not reason to separate password &
					// key pair entries
					newKeystore.setEntry(
							alias,
							keystore.getEntry(alias,
									new KeyStore.PasswordProtection(
											masterPassword.toCharArray())),
							new KeyStore.PasswordProtection(newMasterPassword
									.toCharArray()));
				}
				try (FileOutputStream fos = new FileOutputStream(keystoreFile)) {
					newKeystore.store(fos, newMasterPassword.toCharArray());
				}
				keystore = newKeystore;
			}

			// Truststore does not need to be re-encrypeted item by item as
			// entries there are not encrypted, just the whole truststore
			synchronized (truststore) {
				try (FileOutputStream fos = new FileOutputStream(truststoreFile)) {
					truststore.store(fos, newMasterPassword.toCharArray());
				}
			}

			// Set the new master password as well
			masterPassword = newMasterPassword;
		} catch (Exception ex) {
			// rollback
			keystore = oldKeystore;
			truststore = oldTruststore;
			masterPassword = oldMasterPassword;
			saveKeystore(KEYSTORE);
			saveKeystore(TRUSTSTORE);

			String exMessage = "Failed to change maaster password - reverting to the old one";
			logger.error(exMessage, ex);
			throw (new CMException(exMessage));
		}
	}

	public  CredentialManagerImpl();

}