public void authorizeAccount(String accountName, AuthorizationCallback callback) throws MultiCloudException, OAuth2SettingsException, InterruptedException {
		synchronized (lock) {
			if (auth != null) {
				throw new MultiCloudException("Concurrent authorization forbidden.");
			}
		}
		AccountSettings account = accountManager.getAccountSettings(accountName);
		if (account == null) {
			throw new MultiCloudException("User account not found.");
		}
		if (account.isAuthorized()) {
			throw new MultiCloudException("User account already authorized.");
		}
		CloudSettings settings = cloudManager.getCloudSettings(account.getSettingsId());
		if (settings == null) {
			throw new MultiCloudException("Cloud storage settings not found.");
		}
		synchronized (lock) {
			auth = new OAuth2(Utils.cloudSettingsToOAuth2Settings(settings), credentialStore);
		}
		if (callback != null) {
			auth.setAuthCallback(callback);
		}
		OAuth2Error error = new OAuth2Error();
		try {
			error = auth.authorize(null);
		} catch (Exception e) {
			synchronized (lock) {
				auth = null;
			}
			throw e;
		}
		if (error.getType() != OAuth2ErrorType.SUCCESS) {
			synchronized (lock) {
				auth = null;
			}
			throw new MultiCloudException("Authorization failed.");
		} else {
			if (!Utils.isNullOrEmpty(account.getTokenId())) {
				credentialStore.deleteCredential(account.getTokenId());
			}
			account.setTokenId(auth.getObtainedStoreKey());
		}
		synchronized (lock) {
			auth = null;
		}
		accountManager.saveAccountSettings();
	}