private Credential refreshAccessToken() throws IOException {
    HttpTransport transport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();
    TokenResponse response = new TokenResponse();

    try {
      response =
          new GoogleRefreshTokenRequest(
                  transport, jsonFactory, REFRESH_TOKEN, CLIENT_ID, CLIENT_SECRET)
              .execute();
    } catch (TokenResponseException e) {
      if (e.getDetails() != null) {
        System.err.println("Error: " + e.getDetails().getError());
        if (e.getDetails().getErrorDescription() != null) {
          System.err.println(e.getDetails().getErrorDescription());
        }
        if (e.getDetails().getErrorUri() != null) {
          System.err.println(e.getDetails().getErrorUri());
        }
      } else {
        System.err.println(e.getMessage());
      }
    }

    return new GoogleCredential.Builder()
        .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
        .setJsonFactory(jsonFactory)
        .setTransport(transport)
        .build()
        .setAccessToken(response.getAccessToken());
  }
  public boolean init(StepMetaInterface smi, StepDataInterface sdi) {
    meta = (GaInputStepMeta) smi;
    data = (GaInputStepData) sdi;

    if (!super.init(smi, sdi)) {
      return false;
    }

    // Look for deprecated field types and log error(s) for them
    String[] types = environmentSubstitute(meta.getFeedFieldType());
    if (types != null) {
      for (String type : types) {
        if (GaInputStepMeta.DEPRECATED_FIELD_TYPE_CONFIDENCE_INTERVAL.equals(type)) {
          logError(
              BaseMessages.getString(
                  PKG,
                  "GoogleAnalytics.Warn.FieldTypeNotSupported",
                  GaInputStepMeta.DEPRECATED_FIELD_TYPE_CONFIDENCE_INTERVAL));
        }
      }
    }

    String appName = environmentSubstitute(meta.getGaAppName());
    String serviceAccount = environmentSubstitute(meta.getOAuthServiceAccount());
    String OAuthKeyFile = environmentSubstitute(meta.getOAuthKeyFile());

    if (log.isDetailed()) {
      logDetailed(
          BaseMessages.getString(PKG, "GoogleAnalyticsDialog.AppName.Label") + ": " + appName);
      logDetailed(
          BaseMessages.getString(PKG, "GoogleAnalyticsDialog.OauthAccount.Label")
              + ": "
              + serviceAccount);
      logDetailed(
          BaseMessages.getString(PKG, "GoogleAnalyticsDialog.KeyFile.Label") + ": " + OAuthKeyFile);
    }

    try {
      // Create an Analytics object, and fetch what we can for later (account name, e.g.)
      analytics =
          GoogleAnalyticsApiFacade.createFor(appName, serviceAccount, OAuthKeyFile).getAnalytics();
      // There is necessarily an account name associated with this, so any NPEs or other exceptions
      // mean bail out
      accountName =
          analytics.management().accounts().list().execute().getItems().iterator().next().getName();
    } catch (TokenResponseException tre) {
      Exception exceptionToLog = tre;
      if (tre.getDetails() != null && tre.getDetails().getError() != null) {
        exceptionToLog =
            new IOException(
                BaseMessages.getString(
                    PKG, "GoogleAnalytics.Error.OAuth2.Auth", tre.getDetails().getError()),
                tre);
      }
      logError(BaseMessages.getString(PKG, "GoogleAnalytics.Error.AccessingGaApi"), exceptionToLog);
      return false;
    } catch (Exception e) {
      logError(BaseMessages.getString(PKG, "GoogleAnalytics.Error.AccessingGaApi"), e);
      return false;
    }
    return true;
  }