docs: public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext context) throws PaymentApiException {
          // Don't hold the account lock while fetching the payment methods from the gateway as those could change anyway
          final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
          final List<PaymentMethodInfoPlugin> pluginPms;
          try {
              pluginPms = pluginApi.getPaymentMethods(account.getId(), true, properties, callContext);
              // The method should never return null by convention, but let's not trust the plugin...
              if (pluginPms == null) {
                  log.debug("No payment methods defined on the account {} for plugin {}", account.getId(), pluginName);
                  return ImmutableList.<PaymentMethod>of();
              }
          } catch (final PaymentPluginApiException e) {
              throw new PaymentApiException(ErrorCode.PAYMENT_REFRESH_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
          }
  
          try {
              final PluginDispatcherReturnType<List<PaymentMethod>> result = new WithAccountLock<List<PaymentMethod>, PaymentApiException>(paymentConfig).processAccountWithLock(locker, account.getId(), new DispatcherCallback<PluginDispatcherReturnType<List<PaymentMethod>>, PaymentApiException>() {
                  @Override
                  public PluginDispatcherReturnType<List<PaymentMethod>> doOperation() throws PaymentApiException {
  
                      UUID defaultPaymentMethodId = null;
  
                      final List<PaymentMethodInfoPlugin> pluginPmsWithId = new ArrayList<PaymentMethodInfoPlugin>();
                      final List<PaymentMethodModelDao> finalPaymentMethods = new ArrayList<PaymentMethodModelDao>();
                      for (final PaymentMethodInfoPlugin cur : pluginPms) {
                          // If the kbPaymentId is NULL, the plugin does not know about it, so we create a new UUID
                          final UUID paymentMethodId = cur.getPaymentMethodId() != null ? cur.getPaymentMethodId() : UUIDs.randomUUID();
                          final String externalKey = cur.getExternalPaymentMethodId() != null ? cur.getExternalPaymentMethodId() : paymentMethodId.toString();
                          final PaymentMethod input = new DefaultPaymentMethod(paymentMethodId, externalKey, account.getId(), pluginName);
                          final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(input.getId(), input.getExternalKey(), input.getCreatedDate(), input.getUpdatedDate(),
                                                                                          input.getAccountId(), input.getPluginName(), input.isActive());
                          finalPaymentMethods.add(pmModel);
  
                          pluginPmsWithId.add(new DefaultPaymentMethodInfoPlugin(cur, paymentMethodId));
  
                          // Note: we do not unset the default payment method in Kill Bill even if isDefault is false here.
                          // Some gateways don't support the concept of "default" payment methods, in that case the plugin
                          // will always return false - it's Kill Bill in that case which is responsible to manage default payment methods
                          if (cur.isDefault()) {
                              defaultPaymentMethodId = paymentMethodId;
                          }
                      }
  
                      final List<PaymentMethodModelDao> refreshedPaymentMethods = paymentDao.refreshPaymentMethods(pluginName,
                                                                                                                   finalPaymentMethods,
                                                                                                                   context);
  
                      try {
                          pluginApi.resetPaymentMethods(account.getId(), pluginPmsWithId, properties, callContext);
                      } catch (final PaymentPluginApiException e) {
                          throw new PaymentApiException(ErrorCode.PAYMENT_REFRESH_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
                      }
                      try {
                          updateDefaultPaymentMethodIfNeeded(pluginName, account, defaultPaymentMethodId, context);
                      } catch (final AccountApiException e) {
                          throw new PaymentApiException(e);
                      }
                      final List<PaymentMethod> result = ImmutableList.<PaymentMethod>copyOf(Collections2.transform(refreshedPaymentMethods, new Function<PaymentMethodModelDao, PaymentMethod>() {
                          @Override
                          public PaymentMethod apply(final PaymentMethodModelDao input) {
                              return new DefaultPaymentMethod(input, null);
                          }
                      }));
                      return PluginDispatcher.createPluginDispatcherReturnType(result);
                  }
              });
              return result.getReturnType();
          } catch (final Exception e) {
              throw new PaymentApiException(e, ErrorCode.PAYMENT_INTERNAL_ERROR, MoreObjects.firstNonNull(e.getMessage(), ""));
          }
      }