protected Supplier<Set<? extends Image>> supplyImageCache(
     AtomicReference<AuthorizationException> authException,
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     final Supplier<Set<? extends Image>> imageSupplier) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, imageSupplier, seconds, TimeUnit.SECONDS);
 }
  @Provides
  @Singleton
  @Memoized
  public Supplier<Map<String, OSType>> listOSTypes(
      AtomicReference<AuthorizationException> authException,
      @Named(PROPERTY_SESSION_INTERVAL) long seconds,
      final CloudStackClient client) {
    return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
        authException,
        new Supplier<Map<String, OSType>>() {
          @Override
          public Map<String, OSType> get() {
            GuestOSClient guestOSClient = client.getGuestOSClient();
            return Maps.uniqueIndex(
                guestOSClient.listOSTypes(),
                new Function<OSType, String>() {

                  @Override
                  public String apply(OSType arg0) {
                    return arg0.getId();
                  }
                });
          }

          @Override
          public String toString() {
            return Objects.toStringHelper(client.getGuestOSClient())
                .add("method", "listOSTypes")
                .toString();
          }
        },
        seconds,
        TimeUnit.SECONDS);
  }
  @Provides
  @Singleton
  @Memoized
  public Supplier<Map<Integer, Datacenter>> getAvailableRegionsIndexedById(
      final AtomicReference<AuthorizationException> authException,
      @Named(PROPERTY_SESSION_INTERVAL) final long seconds,
      @Memoized final Supplier<Enterprise> currentEnterprise) {
    Supplier<Map<Integer, Datacenter>> availableRegionsMapSupplier =
        Suppliers.compose(
            new Function<List<Datacenter>, Map<Integer, Datacenter>>() {
              @Override
              public Map<Integer, Datacenter> apply(final List<Datacenter> datacenters) {
                // Index available regions by id
                return Maps.uniqueIndex(
                    datacenters,
                    new Function<Datacenter, Integer>() {
                      @Override
                      public Integer apply(final Datacenter input) {
                        return input.getId();
                      }
                    });
              }
            },
            new Supplier<List<Datacenter>>() {
              @Override
              public List<Datacenter> get() {
                // Get the list of regions available for the user's tenant
                return currentEnterprise.get().listAllowedDatacenters();
              }
            });

    return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
        authException, availableRegionsMapSupplier, seconds, TimeUnit.SECONDS);
  }
 @Provides
 @Singleton
 protected Supplier<Map<URI, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>> provideURIToVDC(
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     AtomicReference<AuthorizationException> authException,
     URItoVDC supplier) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, supplier, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 @Memoized
 protected Supplier<Set<? extends Hardware>> supplySizeCache(
     AtomicReference<AuthorizationException> authException,
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     final Supplier<Set<? extends Hardware>> hardwareSupplier) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, hardwareSupplier, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 @Keys
 protected Supplier<Map<String, ReferenceType>> provideOrgToKeysListCache(
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     AtomicReference<AuthorizationException> authException,
     OrgNameToKeysListSupplier supplier) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, supplier, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 protected Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>>
     provideOrgCatalogItemMapSupplierCache(
         @Named(PROPERTY_SESSION_INTERVAL) long seconds,
         AtomicReference<AuthorizationException> authException,
         OrgCatalogSupplier supplier) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, supplier, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @org.jclouds.trmk.vcloud_0_8.endpoints.Org
 @Singleton
 protected Supplier<Map<String, ReferenceType>> provideVDCtoORG(
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     AtomicReference<AuthorizationException> authException,
     OrgNameToOrgSupplier supplier) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, supplier, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 @Memoized
 public Supplier<User> getCurrentUser(
     AtomicReference<AuthorizationException> authException,
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     final GetCurrentUser getCurrentUser) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, getCurrentUser, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 @Memoized
 public Supplier<Map<String, Network>> listNetworks(
     AtomicReference<AuthorizationException> authException,
     @Named(PROPERTY_SESSION_INTERVAL) long seconds,
     final NetworksForCurrentUser networksForCurrentUser) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException, networksForCurrentUser, seconds, TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 @Memoized
 public Supplier<Enterprise> getCurrentEnterprise(
     final AtomicReference<AuthorizationException> authException,
     @Named(PROPERTY_SESSION_INTERVAL) final long seconds,
     @Memoized final Supplier<User> currentUser) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException,
       new Supplier<Enterprise>() {
         @Override
         public Enterprise get() {
           return currentUser.get().getEnterprise();
         }
       },
       seconds,
       TimeUnit.SECONDS);
 }
 @Provides
 @Singleton
 @Memoized
 public Supplier<User> getCurrentUser(
     final AtomicReference<AuthorizationException> authException,
     @Named(PROPERTY_SESSION_INTERVAL) final long seconds,
     final ApiContext<AbiquoApi> context) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
       authException,
       new Supplier<User>() {
         @Override
         public User get() {
           return wrap(context, User.class, context.getApi().getAdminApi().getCurrentUser());
         }
       },
       seconds,
       TimeUnit.SECONDS);
 }
  @Provides
  @Singleton
  protected Supplier<VCloudSession> provideVCloudTokenCache(
      @Named(PROPERTY_SESSION_INTERVAL) long seconds,
      AtomicReference<AuthorizationException> authException,
      final TerremarkVCloudLoginClient login) {
    return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
        authException,
        new Supplier<VCloudSession>() {

          @Override
          public VCloudSession get() {
            return login.login();
          }

          @Override
          public String toString() {
            return Objects.toStringHelper(login).add("method", "login").toString();
          }
        },
        seconds,
        TimeUnit.SECONDS);
  }