/**
   * Returns the prefix for all persistently stored properties of the account with the specified id.
   *
   * @param bundleContext a currently valid bundle context.
   * @param accountID the AccountID of the account whose properties we're looking for.
   * @param sourcePackageName a String containing the package name of the concrete factory class
   *     that extends us.
   * @return a String indicating the ConfigurationService property name prefix under which all
   *     account properties are stored or null if no account corresponding to the specified id was
   *     found.
   */
  public static String findAccountPrefix(
      BundleContext bundleContext, AccountID accountID, String sourcePackageName) {
    ServiceReference confReference =
        bundleContext.getServiceReference(ConfigurationService.class.getName());
    ConfigurationService configurationService =
        (ConfigurationService) bundleContext.getService(confReference);

    // first retrieve all accounts that we've registered
    List<String> storedAccounts =
        configurationService.getPropertyNamesByPrefix(sourcePackageName, true);

    // find an account with the corresponding id.
    for (String accountRootPropertyName : storedAccounts) {
      // unregister the account in the configuration service.
      // all the properties must have been registered in the following
      // hierarchy:
      // net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
      String accountUID =
          configurationService.getString(
              accountRootPropertyName // node id
                  + "."
                  + ACCOUNT_UID); // propname

      if (accountID.getAccountUniqueID().equals(accountUID)) {
        return accountRootPropertyName;
      }
    }
    return null;
  }
  /**
   * Saves the password for the specified account after scrambling it a bit so that it is not
   * visible from first sight (Method remains highly insecure).
   *
   * <p>TODO Delegate the implementation to {@link AccountManager} because it knows the format in
   * which the password (among the other account properties) is to be saved.
   *
   * @param bundleContext a currently valid bundle context.
   * @param accountID the <tt>AccountID</tt> of the account whose password is to be stored
   * @param password the password to be stored
   * @throws IllegalArgumentException if no account corresponding to <tt>accountID</tt> has been
   *     previously stored.
   * @throws OperationFailedException if anything goes wrong while storing the specified
   *     <tt>password</tt>
   */
  protected void storePassword(BundleContext bundleContext, AccountID accountID, String password)
      throws IllegalArgumentException, OperationFailedException {
    String accountPrefix = findAccountPrefix(bundleContext, accountID, getFactoryImplPackageName());

    if (accountPrefix == null) {
      throw new IllegalArgumentException(
          "No previous records found for account ID: "
              + accountID.getAccountUniqueID()
              + " in package"
              + getFactoryImplPackageName());
    }

    CredentialsStorageService credentialsStorage =
        ServiceUtils.getService(bundleContext, CredentialsStorageService.class);

    if (!credentialsStorage.storePassword(accountPrefix, password)) {
      throw new OperationFailedException(
          "CredentialsStorageService failed to storePassword",
          OperationFailedException.GENERAL_ERROR);
    }
  }