You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/07/01 21:15:10 UTC

[23/24] JCLOUDS-151 - CloudStack refactored to remove async, *Client renamed to *Api.

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
index 0da11fb..ddc7f7a 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
@@ -38,7 +38,7 @@ import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
-import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.CloudStackApi;
 import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
 import org.jclouds.cloudstack.domain.AsyncCreateResponse;
 import org.jclouds.cloudstack.domain.Capabilities;
@@ -81,7 +81,7 @@ import com.google.common.collect.ImmutableSet.Builder;
 import com.google.common.primitives.Ints;
 
 /**
- * defines the connection between the {@link CloudStackClient} implementation
+ * defines the connection between the {@link CloudStackApi} implementation
  * and the jclouds {@link ComputeService}
  */
 @Singleton
@@ -92,7 +92,7 @@ public class CloudStackComputeServiceAdapter implements
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
    protected Logger logger = Logger.NULL;
 
-   private final CloudStackClient client;
+   private final CloudStackApi client;
    private final Predicate<String> jobComplete;
    private final Supplier<Map<String, Network>> networkSupplier;
    private final BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult;
@@ -108,7 +108,7 @@ public class CloudStackComputeServiceAdapter implements
    private final GroupNamingConvention.Factory namingConvention;
 
    @Inject
-   public CloudStackComputeServiceAdapter(CloudStackClient client, Predicate<String> jobComplete,
+   public CloudStackComputeServiceAdapter(CloudStackApi client, Predicate<String> jobComplete,
                                           @Memoized Supplier<Map<String, Network>> networkSupplier,
                                           BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult,
                                           StaticNATVirtualMachineInNetwork.Factory staticNATVMInNetwork,
@@ -181,8 +181,8 @@ public class CloudStackComputeServiceAdapter implements
                .fingerprint(fingerprintPrivateKey(pem)).privateKey(pem).build();
             keyPairCache.asMap().put(keyPair.getName(), keyPair);
             options.keyPair(keyPair.getName());
-         } else if (client.getSSHKeyPairClient().getSSHKeyPair(templateOptions.getKeyPair()) != null) {
-            keyPair = client.getSSHKeyPairClient().getSSHKeyPair(templateOptions.getKeyPair());
+         } else if (client.getSSHKeyPairApi().getSSHKeyPair(templateOptions.getKeyPair()) != null) {
+            keyPair = client.getSSHKeyPairApi().getSSHKeyPair(templateOptions.getKeyPair());
          }
          if (keyPair != null) {
             keyPairCache.asMap().put(keyPair.getName(), keyPair);
@@ -217,7 +217,7 @@ public class CloudStackComputeServiceAdapter implements
 
       logger.debug("serviceOfferingId %s, templateId %s, zoneId %s, options %s%n", serviceOfferingId, templateId,
          zoneId, options);
-      AsyncCreateResponse job = client.getVirtualMachineClient().deployVirtualMachineInZone(zoneId, serviceOfferingId,
+      AsyncCreateResponse job = client.getVirtualMachineApi().deployVirtualMachineInZone(zoneId, serviceOfferingId,
          templateId, options);
       VirtualMachine vm = blockUntilJobCompletesAndReturnResult.<VirtualMachine>apply(job);
       logger.debug("--- virtualmachine: %s", vm);
@@ -231,13 +231,13 @@ public class CloudStackComputeServiceAdapter implements
       }
       
       if (templateOptions.shouldSetupStaticNat()) {
-         Capabilities capabilities = client.getConfigurationClient().listCapabilities();
+         Capabilities capabilities = client.getConfigurationApi().listCapabilities();
          // TODO: possibly not all network ids, do we want to do this
          for (String networkId : options.getNetworkIds()) {
             logger.debug(">> creating static NAT for virtualMachine(%s) in network(%s)", vm.getId(), networkId);
             PublicIPAddress ip = staticNATVMInNetwork.create(networks.get(networkId)).apply(vm);
             logger.trace("<< static NATed IPAddress(%s) to virtualMachine(%s)", ip.getId(), vm.getId());
-            vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId());
+            vm = client.getVirtualMachineApi().getVirtualMachine(vm.getId());
             List<Integer> ports = Ints.asList(templateOptions.getInboundPorts());
             if (capabilities.getCloudStackVersion().startsWith("2")) {
                logger.debug(">> setting up IP forwarding for IPAddress(%s) rules(%s)", ip.getId(), ports);
@@ -256,24 +256,24 @@ public class CloudStackComputeServiceAdapter implements
    @Override
    public Iterable<ServiceOffering> listHardwareProfiles() {
       // TODO: we may need to filter these
-      return client.getOfferingClient().listServiceOfferings();
+      return client.getOfferingApi().listServiceOfferings();
    }
 
    @Override
    public Iterable<Template> listImages() {
       // TODO: we may need to filter these further
       // we may also want to see if we can work with ssh keys
-      return filter(client.getTemplateClient().listTemplates(), isReady());
+      return filter(client.getTemplateApi().listTemplates(), isReady());
    }
 
    @Override
    public Template getImage(String id) {
-      return get(client.getTemplateClient().listTemplates(id(id)), 0, null);
+      return get(client.getTemplateApi().listTemplates(id(id)), 0, null);
    }
 
    @Override
    public Iterable<VirtualMachine> listNodes() {
-      return client.getVirtualMachineClient().listVirtualMachines();
+      return client.getVirtualMachineApi().listVirtualMachines();
    }
 
    @Override
@@ -290,13 +290,13 @@ public class CloudStackComputeServiceAdapter implements
    @Override
    public Iterable<Zone> listLocations() {
       // TODO: we may need to filter these
-      return client.getZoneClient().listZones();
+      return client.getZoneApi().listZones();
    }
 
    @Override
    public VirtualMachine getNode(String id) {
       String virtualMachineId = id;
-      return client.getVirtualMachineClient().getVirtualMachine(virtualMachineId);
+      return client.getVirtualMachineApi().getVirtualMachine(virtualMachineId);
    }
 
    @Override
@@ -334,13 +334,13 @@ public class CloudStackComputeServiceAdapter implements
    public void disassociateIPAddresses(Set<String> ipAddresses) {
       for (String ipAddress : ipAddresses) {
          logger.debug(">> disassociating IPAddress(%s)", ipAddress);
-         client.getAddressClient().disassociateIPAddress(ipAddress);
+         client.getAddressApi().disassociateIPAddress(ipAddress);
       }
    }
 
    public void destroyVirtualMachine(String virtualMachineId) {
 
-      String destroyVirtualMachine = client.getVirtualMachineClient().destroyVirtualMachine(virtualMachineId);
+      String destroyVirtualMachine = client.getVirtualMachineApi().destroyVirtualMachine(virtualMachineId);
       if (destroyVirtualMachine != null) {
          logger.debug(">> destroying virtualMachine(%s) job(%s)", virtualMachineId, destroyVirtualMachine);
          awaitCompletion(destroyVirtualMachine);
@@ -353,7 +353,7 @@ public class CloudStackComputeServiceAdapter implements
    public void disableStaticNATOnIPAddresses(Set<String> ipAddresses) {
       Builder<String> jobsToTrack = ImmutableSet.builder();
       for (String ipAddress : ipAddresses) {
-         String disableStaticNAT = client.getNATClient().disableStaticNATOnPublicIP(ipAddress);
+         String disableStaticNAT = client.getNATApi().disableStaticNATOnPublicIP(ipAddress);
          if (disableStaticNAT != null) {
             logger.debug(">> disabling static NAT IPAddress(%s) job(%s)", ipAddress, disableStaticNAT);
             jobsToTrack.add(disableStaticNAT);
@@ -368,12 +368,12 @@ public class CloudStackComputeServiceAdapter implements
       // immutable doesn't permit duplicates
       Set<String> ipAddresses = Sets.newLinkedHashSet();
 
-      Set<IPForwardingRule> forwardingRules = client.getNATClient().getIPForwardingRulesForVirtualMachine(
+      Set<IPForwardingRule> forwardingRules = client.getNATApi().getIPForwardingRulesForVirtualMachine(
          virtualMachineId);
       for (IPForwardingRule rule : forwardingRules) {
          if (!"Deleting".equals(rule.getState())) {
             ipAddresses.add(rule.getIPAddressId());
-            String deleteForwardingRule = client.getNATClient().deleteIPForwardingRule(rule.getId());
+            String deleteForwardingRule = client.getNATApi().deleteIPForwardingRule(rule.getId());
             if (deleteForwardingRule != null) {
                logger.debug(">> deleting IPForwardingRule(%s) job(%s)", rule.getId(), deleteForwardingRule);
                jobsToTrack.add(deleteForwardingRule);
@@ -388,15 +388,15 @@ public class CloudStackComputeServiceAdapter implements
       // immutable doesn't permit duplicates
       Set<String> ipAddresses = Sets.newLinkedHashSet();
 
-      String publicIpId = client.getVirtualMachineClient().getVirtualMachine(virtualMachineId).getPublicIPId();
+      String publicIpId = client.getVirtualMachineApi().getVirtualMachine(virtualMachineId).getPublicIPId();
       if (publicIpId != null) {
-         Set<FirewallRule> firewallRules = client.getFirewallClient()
-            .listFirewallRules(ListFirewallRulesOptions.Builder.ipAddressId(client.getVirtualMachineClient().getVirtualMachine(virtualMachineId).getPublicIPId()));
+         Set<FirewallRule> firewallRules = client.getFirewallApi()
+            .listFirewallRules(ListFirewallRulesOptions.Builder.ipAddressId(client.getVirtualMachineApi().getVirtualMachine(virtualMachineId).getPublicIPId()));
 
          for (FirewallRule rule : firewallRules) {
             if (rule.getState() != FirewallRule.State.DELETING) {
                ipAddresses.add(rule.getIpAddressId());
-               client.getFirewallClient().deleteFirewallRule(rule.getId());
+               client.getFirewallApi().deleteFirewallRule(rule.getId());
                logger.debug(">> deleting FirewallRule(%s)", rule.getId());
             }
          }
@@ -419,7 +419,7 @@ public class CloudStackComputeServiceAdapter implements
    @Override
    public void rebootNode(String id) {
       String virtualMachineId = id;
-      String job = client.getVirtualMachineClient().rebootVirtualMachine(virtualMachineId);
+      String job = client.getVirtualMachineApi().rebootVirtualMachine(virtualMachineId);
       if (job != null) {
          logger.debug(">> rebooting virtualMachine(%s) job(%s)", virtualMachineId, job);
          awaitCompletion(job);
@@ -429,7 +429,7 @@ public class CloudStackComputeServiceAdapter implements
    @Override
    public void resumeNode(String id) {
       String virtualMachineId = id;
-      String job = client.getVirtualMachineClient().startVirtualMachine(id);
+      String job = client.getVirtualMachineApi().startVirtualMachine(id);
       if (job != null) {
          logger.debug(">> starting virtualMachine(%s) job(%s)", virtualMachineId, job);
          awaitCompletion(job);
@@ -439,7 +439,7 @@ public class CloudStackComputeServiceAdapter implements
    @Override
    public void suspendNode(String id) {
       String virtualMachineId = id;
-      String job = client.getVirtualMachineClient().stopVirtualMachine(id);
+      String job = client.getVirtualMachineApi().stopVirtualMachine(id);
       if (job != null) {
          logger.debug(">> stopping virtualMachine(%s) job(%s)", virtualMachineId, job);
          awaitCompletion(job);

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackHttpApiModule.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackHttpApiModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackHttpApiModule.java
new file mode 100644
index 0000000..967e4b1
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackHttpApiModule.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.config;
+
+import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
+
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.jclouds.Constants;
+import org.jclouds.cloudstack.CloudStackApi;
+import org.jclouds.cloudstack.CloudStackDomainApi;
+import org.jclouds.cloudstack.CloudStackGlobalApi;
+import org.jclouds.cloudstack.domain.LoginResponse;
+import org.jclouds.cloudstack.features.SessionApi;
+import org.jclouds.cloudstack.filters.AddSessionKeyAndJSessionIdToRequest;
+import org.jclouds.cloudstack.filters.AuthenticationFilter;
+import org.jclouds.cloudstack.filters.QuerySigner;
+import org.jclouds.cloudstack.handlers.CloudStackErrorHandler;
+import org.jclouds.cloudstack.handlers.InvalidateSessionAndRetryOn401AndLogoutOnClose;
+import org.jclouds.cloudstack.loaders.LoginWithPasswordCredentials;
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.http.annotation.ClientError;
+import org.jclouds.http.annotation.Redirection;
+import org.jclouds.http.annotation.ServerError;
+import org.jclouds.location.Provider;
+import org.jclouds.location.suppliers.ImplicitLocationSupplier;
+import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
+import org.jclouds.rest.ConfiguresHttpApi;
+import org.jclouds.rest.ApiContext;
+import org.jclouds.rest.config.HttpApiModule;
+import org.jclouds.rest.internal.ApiContextImpl;
+
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Inject;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+import com.google.inject.Singleton;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Named;
+
+/**
+ * Configures the cloudstack connection.
+ * 
+ * @author Adrian Cole
+ */
+@ConfiguresHttpApi
+public class CloudStackHttpApiModule extends HttpApiModule<CloudStackApi> {
+
+   @Override
+   protected void configure() {
+      bind(new TypeLiteral<ApiContext<CloudStackDomainApi>>() {
+      }).to(new TypeLiteral<ApiContextImpl<CloudStackDomainApi>>() {
+      });
+      bind(new TypeLiteral<ApiContext<CloudStackGlobalApi>>() {
+      }).to(new TypeLiteral<ApiContextImpl<CloudStackGlobalApi>>() {
+      });
+      bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
+      // session client is used directly for filters and retry handlers, so let's bind it explicitly
+      bindHttpApi(binder(), SessionApi.class);
+      bindHttpApi(binder(), CloudStackDomainApi.class);
+      bindHttpApi(binder(), CloudStackGlobalApi.class);
+      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(InvalidateSessionAndRetryOn401AndLogoutOnClose.class);
+      
+      super.configure();
+   }
+
+   @Override
+   protected void installLocations() {
+      super.installLocations();
+      bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
+   }
+
+   @Override
+   protected void bindErrorHandlers() {
+      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(CloudStackErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(CloudStackErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(CloudStackErrorHandler.class);
+   }
+
+   @Singleton
+   static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider<CredentialType> {
+      /**
+       * use optional injection to supply a default value for credential type. so that we don't have
+       * to set a default property.
+       */
+      @Inject(optional = true)
+      @Named(CloudStackProperties.CREDENTIAL_TYPE)
+      String credentialType = CredentialType.API_ACCESS_KEY_CREDENTIALS.toString();
+
+      @Override
+      public CredentialType get() {
+         return CredentialType.fromValue(credentialType);
+      }
+   }
+
+   /**
+    * we use the type of credentials specified at login to determine which way we want to filter the
+    * request. <br/>
+    * for ex, if we are getting passwords, we know we will need to login/logout. Otherwise we are
+    * signing requests.
+    */
+   @Provides
+   @Singleton
+   protected AuthenticationFilter authenticationFilterForCredentialType(CredentialType credentialType,
+            AddSessionKeyAndJSessionIdToRequest addSessionKeyAndJSessionIdToRequest, QuerySigner querySigner) {
+      switch (credentialType) {
+         case PASSWORD_CREDENTIALS:
+            return addSessionKeyAndJSessionIdToRequest;
+         case API_ACCESS_KEY_CREDENTIALS:
+            return querySigner;
+         default:
+            throw new IllegalArgumentException("credential type not supported: " + credentialType);
+      }
+   }
+
+   // PROPERTY_SESSION_INTERVAL is default to 60 seconds
+   @Provides
+   @Singleton
+   protected LoadingCache<Credentials, LoginResponse> provideLoginResponseCache(
+            LoginWithPasswordCredentials getLoginResponse,
+            @Named(Constants.PROPERTY_SESSION_INTERVAL) int seconds) {
+      return CacheBuilder.newBuilder().expireAfterWrite(seconds, TimeUnit.SECONDS).build(getLoginResponse);
+   }
+
+   // Temporary conversion of a cache to a supplier until there is a single-element cache
+   // http://code.google.com/p/guava-libraries/issues/detail?id=872
+   @Provides
+   @Singleton
+   protected Supplier<LoginResponse> provideLoginResponseSupplier(final LoadingCache<Credentials, LoginResponse> cache,
+         @Provider final Supplier<Credentials> creds) {
+      return new Supplier<LoginResponse>() {
+         @Override
+         public LoginResponse get() {
+            return cache.getUnchecked(creds.get());
+         }
+      };
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java
deleted file mode 100644
index db5ff89..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.config;
-
-import static org.jclouds.rest.config.BinderUtils.bindSyncToAsyncHttpApi;
-
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.jclouds.Constants;
-import org.jclouds.cloudstack.CloudStackAsyncClient;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.CloudStackDomainAsyncClient;
-import org.jclouds.cloudstack.CloudStackDomainClient;
-import org.jclouds.cloudstack.CloudStackGlobalAsyncClient;
-import org.jclouds.cloudstack.CloudStackGlobalClient;
-import org.jclouds.cloudstack.domain.LoginResponse;
-import org.jclouds.cloudstack.features.AccountAsyncClient;
-import org.jclouds.cloudstack.features.AccountClient;
-import org.jclouds.cloudstack.features.AddressAsyncClient;
-import org.jclouds.cloudstack.features.AddressClient;
-import org.jclouds.cloudstack.features.AsyncJobAsyncClient;
-import org.jclouds.cloudstack.features.AsyncJobClient;
-import org.jclouds.cloudstack.features.ConfigurationAsyncClient;
-import org.jclouds.cloudstack.features.ConfigurationClient;
-import org.jclouds.cloudstack.features.DomainAccountAsyncClient;
-import org.jclouds.cloudstack.features.DomainAccountClient;
-import org.jclouds.cloudstack.features.DomainDomainAsyncClient;
-import org.jclouds.cloudstack.features.DomainDomainClient;
-import org.jclouds.cloudstack.features.DomainLimitAsyncClient;
-import org.jclouds.cloudstack.features.DomainLimitClient;
-import org.jclouds.cloudstack.features.DomainUserAsyncClient;
-import org.jclouds.cloudstack.features.DomainUserClient;
-import org.jclouds.cloudstack.features.EventAsyncClient;
-import org.jclouds.cloudstack.features.EventClient;
-import org.jclouds.cloudstack.features.FirewallAsyncClient;
-import org.jclouds.cloudstack.features.FirewallClient;
-import org.jclouds.cloudstack.features.GlobalAccountAsyncClient;
-import org.jclouds.cloudstack.features.GlobalAccountClient;
-import org.jclouds.cloudstack.features.GlobalAlertAsyncClient;
-import org.jclouds.cloudstack.features.GlobalAlertClient;
-import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient;
-import org.jclouds.cloudstack.features.GlobalCapacityClient;
-import org.jclouds.cloudstack.features.GlobalConfigurationAsyncClient;
-import org.jclouds.cloudstack.features.GlobalConfigurationClient;
-import org.jclouds.cloudstack.features.GlobalDomainAsyncClient;
-import org.jclouds.cloudstack.features.GlobalDomainClient;
-import org.jclouds.cloudstack.features.GlobalHostAsyncClient;
-import org.jclouds.cloudstack.features.GlobalHostClient;
-import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient;
-import org.jclouds.cloudstack.features.GlobalOfferingClient;
-import org.jclouds.cloudstack.features.GlobalPodAsyncClient;
-import org.jclouds.cloudstack.features.GlobalPodClient;
-import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient;
-import org.jclouds.cloudstack.features.GlobalStoragePoolClient;
-import org.jclouds.cloudstack.features.GlobalUsageAsyncClient;
-import org.jclouds.cloudstack.features.GlobalUsageClient;
-import org.jclouds.cloudstack.features.GlobalUserAsyncClient;
-import org.jclouds.cloudstack.features.GlobalUserClient;
-import org.jclouds.cloudstack.features.GlobalVlanAsyncClient;
-import org.jclouds.cloudstack.features.GlobalVlanClient;
-import org.jclouds.cloudstack.features.GlobalZoneAsyncClient;
-import org.jclouds.cloudstack.features.GlobalZoneClient;
-import org.jclouds.cloudstack.features.GuestOSAsyncClient;
-import org.jclouds.cloudstack.features.GuestOSClient;
-import org.jclouds.cloudstack.features.HypervisorAsyncClient;
-import org.jclouds.cloudstack.features.HypervisorClient;
-import org.jclouds.cloudstack.features.ISOAsyncClient;
-import org.jclouds.cloudstack.features.ISOClient;
-import org.jclouds.cloudstack.features.LimitAsyncClient;
-import org.jclouds.cloudstack.features.LimitClient;
-import org.jclouds.cloudstack.features.LoadBalancerAsyncClient;
-import org.jclouds.cloudstack.features.LoadBalancerClient;
-import org.jclouds.cloudstack.features.NATAsyncClient;
-import org.jclouds.cloudstack.features.NATClient;
-import org.jclouds.cloudstack.features.NetworkAsyncClient;
-import org.jclouds.cloudstack.features.NetworkClient;
-import org.jclouds.cloudstack.features.OfferingAsyncClient;
-import org.jclouds.cloudstack.features.OfferingClient;
-import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
-import org.jclouds.cloudstack.features.SSHKeyPairClient;
-import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
-import org.jclouds.cloudstack.features.SecurityGroupClient;
-import org.jclouds.cloudstack.features.SessionAsyncClient;
-import org.jclouds.cloudstack.features.SessionClient;
-import org.jclouds.cloudstack.features.SnapshotAsyncClient;
-import org.jclouds.cloudstack.features.SnapshotClient;
-import org.jclouds.cloudstack.features.TemplateAsyncClient;
-import org.jclouds.cloudstack.features.TemplateClient;
-import org.jclouds.cloudstack.features.VMGroupAsyncClient;
-import org.jclouds.cloudstack.features.VMGroupClient;
-import org.jclouds.cloudstack.features.VirtualMachineAsyncClient;
-import org.jclouds.cloudstack.features.VirtualMachineClient;
-import org.jclouds.cloudstack.features.VolumeAsyncClient;
-import org.jclouds.cloudstack.features.VolumeClient;
-import org.jclouds.cloudstack.features.ZoneAsyncClient;
-import org.jclouds.cloudstack.features.ZoneClient;
-import org.jclouds.cloudstack.filters.AddSessionKeyAndJSessionIdToRequest;
-import org.jclouds.cloudstack.filters.AuthenticationFilter;
-import org.jclouds.cloudstack.filters.QuerySigner;
-import org.jclouds.cloudstack.handlers.CloudStackErrorHandler;
-import org.jclouds.cloudstack.handlers.InvalidateSessionAndRetryOn401AndLogoutOnClose;
-import org.jclouds.cloudstack.loaders.LoginWithPasswordCredentials;
-import org.jclouds.domain.Credentials;
-import org.jclouds.http.HttpErrorHandler;
-import org.jclouds.http.HttpRetryHandler;
-import org.jclouds.http.annotation.ClientError;
-import org.jclouds.http.annotation.Redirection;
-import org.jclouds.http.annotation.ServerError;
-import org.jclouds.location.Provider;
-import org.jclouds.location.suppliers.ImplicitLocationSupplier;
-import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
-import org.jclouds.rest.ConfiguresRestClient;
-import org.jclouds.rest.RestContext;
-import org.jclouds.rest.config.RestClientModule;
-import org.jclouds.rest.internal.RestContextImpl;
-
-import com.google.common.base.Supplier;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Inject;
-import com.google.inject.Provides;
-import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.TypeLiteral;
-import com.google.inject.name.Named;
-
-/**
- * Configures the cloudstack connection.
- * 
- * @author Adrian Cole
- */
-@ConfiguresRestClient
-public class CloudStackRestClientModule extends RestClientModule<CloudStackClient, CloudStackAsyncClient> {
-
-   public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
-            .put(ZoneClient.class, ZoneAsyncClient.class)//
-            .put(GlobalZoneClient.class, GlobalZoneAsyncClient.class)//
-            .put(TemplateClient.class, TemplateAsyncClient.class)//
-            .put(OfferingClient.class, OfferingAsyncClient.class)//
-            .put(NetworkClient.class, NetworkAsyncClient.class)//
-            .put(VirtualMachineClient.class, VirtualMachineAsyncClient.class)//
-            .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
-            .put(AsyncJobClient.class, AsyncJobAsyncClient.class)//
-            .put(AddressClient.class, AddressAsyncClient.class)//
-            .put(NATClient.class, NATAsyncClient.class)//
-            .put(FirewallClient.class, FirewallAsyncClient.class)//
-            .put(LoadBalancerClient.class, LoadBalancerAsyncClient.class)//
-            .put(GuestOSClient.class, GuestOSAsyncClient.class)//
-            .put(HypervisorClient.class, HypervisorAsyncClient.class)//
-            .put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
-            .put(GlobalConfigurationClient.class, GlobalConfigurationAsyncClient.class)//
-            .put(AccountClient.class, AccountAsyncClient.class)//
-            .put(DomainAccountClient.class, DomainAccountAsyncClient.class)//
-            .put(DomainUserClient.class, DomainUserAsyncClient.class)//
-            .put(DomainDomainClient.class, DomainDomainAsyncClient.class)//
-            .put(GlobalDomainClient.class, GlobalDomainAsyncClient.class)//
-            .put(GlobalAccountClient.class, GlobalAccountAsyncClient.class)//
-            .put(GlobalUserClient.class, GlobalUserAsyncClient.class)//
-            .put(EventClient.class, EventAsyncClient.class)//
-            .put(LimitClient.class, LimitAsyncClient.class)//
-            .put(DomainLimitClient.class, DomainLimitAsyncClient.class)//
-            .put(SSHKeyPairClient.class, SSHKeyPairAsyncClient.class)//
-            .put(VMGroupClient.class, VMGroupAsyncClient.class)//
-            .put(ISOClient.class, ISOAsyncClient.class)//
-            .put(VolumeClient.class, VolumeAsyncClient.class)//
-            .put(SnapshotClient.class, SnapshotAsyncClient.class)//
-            .put(GlobalAlertClient.class, GlobalAlertAsyncClient.class)//
-            .put(GlobalCapacityClient.class, GlobalCapacityAsyncClient.class)//
-            .put(GlobalOfferingClient.class, GlobalOfferingAsyncClient.class)//
-            .put(GlobalHostClient.class, GlobalHostAsyncClient.class)//
-            .put(GlobalStoragePoolClient.class, GlobalStoragePoolAsyncClient.class)//
-            .put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)//
-            .put(GlobalPodClient.class, GlobalPodAsyncClient.class)//
-            .put(GlobalVlanClient.class, GlobalVlanAsyncClient.class)//
-            .put(SessionClient.class, SessionAsyncClient.class)//
-            .build();
-
-   public CloudStackRestClientModule() {
-      super(DELEGATE_MAP);
-   }
-
-   @Override
-   protected void configure() {
-      bind(new TypeLiteral<RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient>>() {
-      }).to(new TypeLiteral<RestContextImpl<CloudStackDomainClient, CloudStackDomainAsyncClient>>() {
-      });
-      bind(new TypeLiteral<RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient>>() {
-      }).to(new TypeLiteral<RestContextImpl<CloudStackGlobalClient, CloudStackGlobalAsyncClient>>() {
-      });
-      bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
-      // session client is used directly for filters and retry handlers, so let's bind it explicitly
-      bindSyncToAsyncHttpApi(binder(), SessionClient.class, SessionAsyncClient.class);
-      bindSyncToAsyncHttpApi(binder(), CloudStackDomainClient.class, CloudStackDomainAsyncClient.class);
-      bindSyncToAsyncHttpApi(binder(), CloudStackGlobalClient.class, CloudStackGlobalAsyncClient.class);
-      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(InvalidateSessionAndRetryOn401AndLogoutOnClose.class);
-      
-      super.configure();
-   }
-
-   @Override
-   protected void installLocations() {
-      super.installLocations();
-      bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
-   }
-
-   @Override
-   protected void bindErrorHandlers() {
-      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(CloudStackErrorHandler.class);
-      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(CloudStackErrorHandler.class);
-      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(CloudStackErrorHandler.class);
-   }
-
-   @Singleton
-   static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider<CredentialType> {
-      /**
-       * use optional injection to supply a default value for credential type. so that we don't have
-       * to set a default property.
-       */
-      @Inject(optional = true)
-      @Named(CloudStackProperties.CREDENTIAL_TYPE)
-      String credentialType = CredentialType.API_ACCESS_KEY_CREDENTIALS.toString();
-
-      @Override
-      public CredentialType get() {
-         return CredentialType.fromValue(credentialType);
-      }
-   }
-
-   /**
-    * we use the type of credentials specified at login to determine which way we want to filter the
-    * request. <br/>
-    * for ex, if we are getting passwords, we know we will need to login/logout. Otherwise we are
-    * signing requests.
-    */
-   @Provides
-   @Singleton
-   protected AuthenticationFilter authenticationFilterForCredentialType(CredentialType credentialType,
-            AddSessionKeyAndJSessionIdToRequest addSessionKeyAndJSessionIdToRequest, QuerySigner querySigner) {
-      switch (credentialType) {
-         case PASSWORD_CREDENTIALS:
-            return addSessionKeyAndJSessionIdToRequest;
-         case API_ACCESS_KEY_CREDENTIALS:
-            return querySigner;
-         default:
-            throw new IllegalArgumentException("credential type not supported: " + credentialType);
-      }
-   }
-
-   // PROPERTY_SESSION_INTERVAL is default to 60 seconds
-   @Provides
-   @Singleton
-   protected LoadingCache<Credentials, LoginResponse> provideLoginResponseCache(
-            LoginWithPasswordCredentials getLoginResponse,
-            @Named(Constants.PROPERTY_SESSION_INTERVAL) int seconds) {
-      return CacheBuilder.newBuilder().expireAfterWrite(seconds, TimeUnit.SECONDS).build(getLoginResponse);
-   }
-
-   // Temporary conversion of a cache to a supplier until there is a single-element cache
-   // http://code.google.com/p/guava-libraries/issues/detail?id=872
-   @Provides
-   @Singleton
-   protected Supplier<LoginResponse> provideLoginResponseSupplier(final LoadingCache<Credentials, LoginResponse> cache,
-         @Provider final Supplier<Credentials> creds) {
-      return new Supplier<LoginResponse>() {
-         @Override
-         public LoginResponse get() {
-            return cache.getUnchecked(creds.get());
-         }
-      };
-   }
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java
index fe01500..1df6256 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java
@@ -22,7 +22,7 @@ import com.google.common.base.CaseFormat;
 
 /**
  * @author Adrian Cole
- * @see org.jclouds.cloudstack.features.OfferingClient#listNetworkOfferings
+ * @see org.jclouds.cloudstack.features.OfferingApi#listNetworkOfferings
  */
 public enum GuestIPType {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java
index 9ec6099..3fed65d 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java
@@ -22,7 +22,7 @@ import com.google.common.base.CaseFormat;
 
 /**
  * @author Adrian Cole
- * @see TemplateClient#listZones
+ * @see TemplateApi#listZones
  */
 public enum NetworkType {
    BASIC,

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java
index 5115a69..26085d5 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java
@@ -22,7 +22,7 @@ import com.google.common.base.CaseFormat;
 
 /**
  * @author Adrian Cole
- * @see OfferingClient#listServiceOfferings
+ * @see OfferingApi#listServiceOfferings
  */
 public enum StorageType {
    LOCAL,

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java
index 04b04a2..2393828 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java
@@ -20,7 +20,7 @@ import com.google.common.base.CaseFormat;
 
 /**
  * @author Adrian Cole
- * @see TemplateClient#listTemplates
+ * @see TemplateApi#listTemplates
  */
 public enum TemplateFilter {
    /**

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java
index e6b340f..912199e 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java
@@ -22,7 +22,7 @@ import com.google.common.base.CaseFormat;
 
 /**
  * @author Adrian Cole
- * @see NetworkOfferingClient#listNetworkOfferings
+ * @see NetworkOfferingApi#listNetworkOfferings
  */
 public enum TrafficType {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountApi.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountApi.java
new file mode 100644
index 0000000..b4c6570
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountApi.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.features;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.cloudstack.domain.Account;
+import org.jclouds.cloudstack.filters.AuthenticationFilter;
+import org.jclouds.cloudstack.options.ListAccountsOptions;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.OnlyElement;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+
+/**
+ * Provides synchronous access to cloudstack via their REST API.
+ * <p/>
+ * 
+ * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
+ * @author Adrian Cole
+ */
+@RequestFilters(AuthenticationFilter.class)
+@QueryParams(keys = "response", values = "json")
+public interface AccountApi {
+   /**
+    * Lists Accounts
+    * 
+    * @param options
+    *           if present, how to constrain the list.
+    * @return Accounts matching query, or empty set, if no Accounts are found
+    */
+   @Named("listAccounts")
+   @GET
+   @QueryParams(keys = { "command", "listAll" }, values = { "listAccounts", "true" })
+   @SelectJson("account")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<Account> listAccounts(ListAccountsOptions... options);
+
+   /**
+    * get a specific Account by id
+    * 
+    * @param id
+    *           Account to get
+    * @return Account or null if not found
+    */
+   @Named("listAccounts")
+   @GET
+   @QueryParams(keys = { "command", "listAll" }, values = { "listAccounts", "true" })
+   @SelectJson("account")
+   @OnlyElement
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   Account getAccount(@QueryParam("id") String id);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountAsyncClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountAsyncClient.java
deleted file mode 100644
index 74fb3e1..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountAsyncClient.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import java.util.Set;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.cloudstack.domain.Account;
-import org.jclouds.cloudstack.filters.AuthenticationFilter;
-import org.jclouds.cloudstack.options.ListAccountsOptions;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.OnlyElement;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to cloudstack via their REST API.
- * <p/>
- * 
- * @see AccountClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-@RequestFilters(AuthenticationFilter.class)
-@QueryParams(keys = "response", values = "json")
-public interface AccountAsyncClient {
-   /**
-    * @see AccountClient#listAccounts
-    */
-   @Named("listAccounts")
-   @GET
-   @QueryParams(keys = { "command", "listAll" }, values = { "listAccounts", "true" })
-   @SelectJson("account")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(EmptySetOnNotFoundOr404.class)
-   ListenableFuture<Set<Account>> listAccounts(ListAccountsOptions... options);
-
-   /**
-    * @see AccountClient#getAccount
-    */
-   @Named("listAccounts")
-   @GET
-   @QueryParams(keys = { "command", "listAll" }, values = { "listAccounts", "true" })
-   @SelectJson("account")
-   @OnlyElement
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<Account> getAccount(@QueryParam("id") String id);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountClient.java
deleted file mode 100644
index 6ad1c98..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AccountClient.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import java.util.Set;
-import org.jclouds.cloudstack.domain.Account;
-import org.jclouds.cloudstack.options.ListAccountsOptions;
-
-/**
- * Provides synchronous access to CloudStack Account features.
- * <p/>
- * 
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-public interface AccountClient {
-   /**
-    * Lists Accounts
-    * 
-    * @param options
-    *           if present, how to constrain the list.
-    * @return Accounts matching query, or empty set, if no Accounts are found
-    */
-   Set<Account> listAccounts(ListAccountsOptions... options);
-
-   /**
-    * get a specific Account by id
-    * 
-    * @param id
-    *           Account to get
-    * @return Account or null if not found
-    */
-   Account getAccount(String id);
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressApi.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressApi.java
new file mode 100644
index 0000000..704c603
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressApi.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.features;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.domain.PublicIPAddress;
+import org.jclouds.cloudstack.filters.AuthenticationFilter;
+import org.jclouds.cloudstack.functions.CloudStackFallbacks.VoidOnNotFoundOr404OrUnableToFindAccountOwner;
+import org.jclouds.cloudstack.options.AssociateIPAddressOptions;
+import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.OnlyElement;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.annotations.Unwrap;
+
+/**
+ * Provides synchronous access to cloudstack via their REST API.
+ * <p/>
+ * 
+ * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
+ * @author Adrian Cole
+ */
+@RequestFilters(AuthenticationFilter.class)
+@QueryParams(keys = "response", values = "json")
+public interface AddressApi {
+
+   /**
+    * Lists IPAddresses
+    * 
+    * @param options
+    *           if present, how to constrain the list.
+    * @return IPAddresses matching query, or empty set, if no IPAddresses are
+    *         found
+    */
+   @Named("listPublicIpAddresses")
+   @GET
+   @QueryParams(keys = { "command", "listAll" }, values = { "listPublicIpAddresses", "true" })
+   @SelectJson("publicipaddress")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<PublicIPAddress> listPublicIPAddresses(ListPublicIPAddressesOptions... options);
+
+   /**
+    * get a specific IPAddress by id
+    * 
+    * @param id
+    *           IPAddress to get
+    * @return IPAddress or null if not found
+    */
+   @Named("listPublicIpAddresses")
+   @GET
+   @QueryParams(keys = { "command", "listAll" }, values = { "listPublicIpAddresses", "true" })
+   @SelectJson("publicipaddress")
+   @OnlyElement
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   PublicIPAddress getPublicIPAddress(@QueryParam("id") String id);
+
+   /**
+    * Acquires and associates a public IP to an account.
+    * 
+    * @param zoneId
+    *           the ID of the availability zone you want to acquire an public IP
+    *           address from
+    * @return IPAddress
+    */
+   @Named("associateIpAddress")
+   @GET
+   @QueryParams(keys = "command", values = "associateIpAddress")
+   @Unwrap
+   @Consumes(MediaType.APPLICATION_JSON)
+   AsyncCreateResponse associateIPAddressInZone(@QueryParam("zoneid") String zoneId,
+         AssociateIPAddressOptions... options);
+
+   /**
+    * Disassociates an ip address from the account.
+    * 
+    * @param id
+    *           the id of the public ip address to disassociate
+    */
+   @Named("disassociateIpAddress")
+   @GET
+   @QueryParams(keys = "command", values = "disassociateIpAddress")
+   @Fallback(VoidOnNotFoundOr404OrUnableToFindAccountOwner.class)
+   void disassociateIPAddress(@QueryParam("id") String id);
+   
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java
deleted file mode 100644
index 4dd1db3..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import java.util.Set;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.cloudstack.domain.AsyncCreateResponse;
-import org.jclouds.cloudstack.domain.PublicIPAddress;
-import org.jclouds.cloudstack.filters.AuthenticationFilter;
-import org.jclouds.cloudstack.functions.CloudStackFallbacks.VoidOnNotFoundOr404OrUnableToFindAccountOwner;
-import org.jclouds.cloudstack.options.AssociateIPAddressOptions;
-import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.OnlyElement;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-import org.jclouds.rest.annotations.Unwrap;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to cloudstack via their REST API.
- * <p/>
- * 
- * @see AddressClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-@RequestFilters(AuthenticationFilter.class)
-@QueryParams(keys = "response", values = "json")
-public interface AddressAsyncClient {
-
-   /**
-    * @see AddressClient#listPublicIPAddresses
-    */
-   @Named("listPublicIpAddresses")
-   @GET
-   @QueryParams(keys = { "command", "listAll" }, values = { "listPublicIpAddresses", "true" })
-   @SelectJson("publicipaddress")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(EmptySetOnNotFoundOr404.class)
-   ListenableFuture<Set<PublicIPAddress>> listPublicIPAddresses(ListPublicIPAddressesOptions... options);
-
-   /**
-    * @see AddressClient#getPublicIPAddress
-    */
-   @Named("listPublicIpAddresses")
-   @GET
-   @QueryParams(keys = { "command", "listAll" }, values = { "listPublicIpAddresses", "true" })
-   @SelectJson("publicipaddress")
-   @OnlyElement
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<PublicIPAddress> getPublicIPAddress(@QueryParam("id") String id);
-
-   /**
-    * @see AddressClient#associateIPAddressInZone
-    */
-   @Named("associateIpAddress")
-   @GET
-   @QueryParams(keys = "command", values = "associateIpAddress")
-   @Unwrap
-   @Consumes(MediaType.APPLICATION_JSON)
-   ListenableFuture<AsyncCreateResponse> associateIPAddressInZone(@QueryParam("zoneid") String zoneId,
-         AssociateIPAddressOptions... options);
-
-   /**
-    * @see AddressClient#disassociateIPAddress
-    */
-   @Named("disassociateIpAddress")
-   @GET
-   @QueryParams(keys = "command", values = "disassociateIpAddress")
-   @Fallback(VoidOnNotFoundOr404OrUnableToFindAccountOwner.class)
-   ListenableFuture<Void> disassociateIPAddress(@QueryParam("id") String id);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java
deleted file mode 100644
index 96d39b1..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import java.util.Set;
-import org.jclouds.cloudstack.domain.AsyncCreateResponse;
-import org.jclouds.cloudstack.domain.PublicIPAddress;
-import org.jclouds.cloudstack.options.AssociateIPAddressOptions;
-import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
-
-/**
- * Provides synchronous access to CloudStack IPAddress features.
- * <p/>
- * 
- * @see IPAddressAsyncClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-public interface AddressClient {
-   /**
-    * Lists IPAddresses
-    * 
-    * @param options
-    *           if present, how to constrain the list.
-    * @return IPAddresses matching query, or empty set, if no IPAddresses are
-    *         found
-    */
-   Set<PublicIPAddress> listPublicIPAddresses(ListPublicIPAddressesOptions... options);
-
-   /**
-    * get a specific IPAddress by id
-    * 
-    * @param id
-    *           IPAddress to get
-    * @return IPAddress or null if not found
-    */
-   PublicIPAddress getPublicIPAddress(String id);
-
-   /**
-    * Acquires and associates a public IP to an account.
-    * 
-    * @param zoneId
-    *           the ID of the availability zone you want to acquire an public IP
-    *           address from
-    * @return IPAddress
-    */
-   AsyncCreateResponse associateIPAddressInZone(String zoneId, AssociateIPAddressOptions... options);
-
-   /**
-    * Disassociates an ip address from the account.
-    * 
-    * @param id
-    *           the id of the public ip address to disassociate
-    */
-   void disassociateIPAddress(String id);
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobApi.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobApi.java
new file mode 100644
index 0000000..df6640b
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobApi.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.features;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.cloudstack.domain.AsyncJob;
+import org.jclouds.cloudstack.filters.AuthenticationFilter;
+import org.jclouds.cloudstack.functions.ParseAsyncJobFromHttpResponse;
+import org.jclouds.cloudstack.functions.ParseAsyncJobsFromHttpResponse;
+import org.jclouds.cloudstack.options.ListAsyncJobsOptions;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+
+/**
+ * Provides synchronous access to cloudstack via their REST API.
+ * <p/>
+ * 
+ * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
+ * @author Adrian Cole
+ */
+@RequestFilters(AuthenticationFilter.class)
+@QueryParams(keys = "response", values = "json")
+public interface AsyncJobApi {
+
+   /**
+    * Lists asyncJobs
+    * 
+    * @param options
+    *           if present, how to constrain the list.
+    * @return asyncJobs matching query, or empty set, if no asyncJobs are found
+    */
+   @Named("listAsyncJobs")
+   @GET
+   @QueryParams(keys = { "command", "listAll" }, values = { "listAsyncJobs", "true" })
+   @ResponseParser(ParseAsyncJobsFromHttpResponse.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<AsyncJob<?>> listAsyncJobs(ListAsyncJobsOptions... options);
+
+   /**
+    * get a specific asyncJob by id
+    * 
+    * @param id
+    *           asyncJob to get
+    * @return asyncJob or null if not found
+    */
+   @Named("queryAsyncJobResult")
+   @GET
+   @QueryParams(keys = "command", values = "queryAsyncJobResult")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseAsyncJobFromHttpResponse.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   <T> AsyncJob<T> getAsyncJob(@QueryParam("jobid") String id);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java
deleted file mode 100644
index 0182850..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import java.util.Set;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.cloudstack.domain.AsyncJob;
-import org.jclouds.cloudstack.filters.AuthenticationFilter;
-import org.jclouds.cloudstack.functions.ParseAsyncJobFromHttpResponse;
-import org.jclouds.cloudstack.functions.ParseAsyncJobsFromHttpResponse;
-import org.jclouds.cloudstack.options.ListAsyncJobsOptions;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to cloudstack via their REST API.
- * <p/>
- * 
- * @see AsyncJobClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-@RequestFilters(AuthenticationFilter.class)
-@QueryParams(keys = "response", values = "json")
-public interface AsyncJobAsyncClient {
-
-   /**
-    * @see AsyncJobClient#listAsyncJobs
-    */
-   @Named("listAsyncJobs")
-   @GET
-   @QueryParams(keys = { "command", "listAll" }, values = { "listAsyncJobs", "true" })
-   @ResponseParser(ParseAsyncJobsFromHttpResponse.class)
-   @Fallback(EmptySetOnNotFoundOr404.class)
-   ListenableFuture<Set<AsyncJob<?>>> listAsyncJobs(ListAsyncJobsOptions... options);
-
-   /**
-    * @see AsyncJobClient#getAsyncJob
-    */
-   @Named("queryAsyncJobResult")
-   @GET
-   @QueryParams(keys = "command", values = "queryAsyncJobResult")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @ResponseParser(ParseAsyncJobFromHttpResponse.class)
-   @Fallback(NullOnNotFoundOr404.class)
-   <T> ListenableFuture<AsyncJob<T>> getAsyncJob(@QueryParam("jobid") String id);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java
deleted file mode 100644
index af86679..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import java.util.Set;
-import org.jclouds.cloudstack.domain.AsyncJob;
-import org.jclouds.cloudstack.options.ListAsyncJobsOptions;
-
-/**
- * Provides synchronous access to CloudStack asyncJob features.
- * <p/>
- * 
- * @see AsyncJobAsyncClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-public interface AsyncJobClient {
-   /**
-    * Lists asyncJobs
-    * 
-    * @param options
-    *           if present, how to constrain the list.
-    * @return asyncJobs matching query, or empty set, if no asyncJobs are found
-    */
-   Set<AsyncJob<?>> listAsyncJobs(ListAsyncJobsOptions... options);
-
-   /**
-    * get a specific asyncJob by id
-    * 
-    * @param id
-    *           asyncJob to get
-    * @return asyncJob or null if not found
-    */
-   <T> AsyncJob<T> getAsyncJob(String id);
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationApi.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationApi.java
new file mode 100644
index 0000000..818bb67
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationApi.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.features;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.cloudstack.domain.Capabilities;
+import org.jclouds.cloudstack.filters.AuthenticationFilter;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+
+/**
+ * Provides synchronous access to cloudstack via their REST API.
+ * <p/>
+ * 
+ * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
+ * @author Adrian Cole
+ */
+@RequestFilters(AuthenticationFilter.class)
+@QueryParams(keys = { "response", "listAll" }, values = { "json", "true" })
+public interface ConfigurationApi {
+
+   /**
+    * Lists capabilities
+    * 
+    * @return current capabilities of this cloud
+    * 
+    */
+   @Named("listCapabilities")
+   @GET
+   @QueryParams(keys = "command", values = "listCapabilities")
+   @SelectJson("capability")
+   @Consumes(MediaType.APPLICATION_JSON)
+   Capabilities listCapabilities();
+   
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationAsyncClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationAsyncClient.java
deleted file mode 100644
index f7991d4..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationAsyncClient.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.cloudstack.domain.Capabilities;
-import org.jclouds.cloudstack.filters.AuthenticationFilter;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to cloudstack via their REST API.
- * <p/>
- * 
- * @see ConfigurationClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-@RequestFilters(AuthenticationFilter.class)
-@QueryParams(keys = { "response", "listAll" }, values = { "json", "true" })
-public interface ConfigurationAsyncClient {
-
-   /**
-    * @see ConfigurationClient#listCapabilities
-    */
-   @Named("listCapabilities")
-   @GET
-   @QueryParams(keys = "command", values = "listCapabilities")
-   @SelectJson("capability")
-   @Consumes(MediaType.APPLICATION_JSON)
-   ListenableFuture<Capabilities> listCapabilities();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationClient.java
deleted file mode 100644
index b21a0d6..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ConfigurationClient.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import org.jclouds.cloudstack.domain.Capabilities;
-
-/**
- * Provides synchronous access to CloudStack Configuration features.
- * <p/>
- * 
- * @see ConfigurationAsyncClient
- * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
- */
-public interface ConfigurationClient {
-   /**
-    * Lists capabilities
-    * 
-    * @return current capabilities of this cloud
-    * 
-    */
-   Capabilities listCapabilities();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountApi.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountApi.java
new file mode 100644
index 0000000..089df78
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountApi.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.features;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.cloudstack.domain.Account;
+import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.filters.AuthenticationFilter;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.annotations.Unwrap;
+
+/**
+ * Provides synchronous access to CloudStack Account features available to Domain
+ * Admin users.
+ *
+ * @author Adrian Cole
+ * @see <a href=
+ *      "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
+ *      />
+ */
+@RequestFilters(AuthenticationFilter.class)
+@QueryParams(keys = "response", values = "json")
+public interface DomainAccountApi extends AccountApi {
+
+   /**
+    * Enable an account
+    *
+    * @param accountName
+    *    the account name you are enabling
+    * @param domainId
+    *    the domain ID
+    */
+   @Named("enableAccount")
+   @GET
+   @QueryParams(keys = "command", values = "enableAccount")
+   @SelectJson("account")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   Account enableAccount(@QueryParam("account") String accountName, @QueryParam("domainid") String domainId);
+
+
+   /**
+    * Disable or lock an account
+    *
+    * @param accountName
+    *    the account name you are disabling
+    * @param domainId
+    *    the domain ID
+    * @param onlyLock
+    *    only lock if true disable otherwise
+    */
+   @Named("disableAccount")
+   @GET
+   @QueryParams(keys = "command", values = "disableAccount")
+   @Unwrap
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   AsyncCreateResponse disableAccount(@QueryParam("account") String accountName,
+      @QueryParam("domainid") String domainId, @QueryParam("lock") boolean onlyLock);
+   
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountAsyncClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountAsyncClient.java
deleted file mode 100644
index 984fb02..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountAsyncClient.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.cloudstack.domain.Account;
-import org.jclouds.cloudstack.domain.AsyncCreateResponse;
-import org.jclouds.cloudstack.filters.AuthenticationFilter;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-import org.jclouds.rest.annotations.Unwrap;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to CloudStack Account features available to Domain
- * Admin users.
- *
- * @author Adrian Cole
- * @see <a href=
- *      "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
- *      />
- */
-@RequestFilters(AuthenticationFilter.class)
-@QueryParams(keys = "response", values = "json")
-public interface DomainAccountAsyncClient extends AccountAsyncClient {
-
-   /**
-    * @see DomainAccountClient#enableAccount
-    */
-   @Named("enableAccount")
-   @GET
-   @QueryParams(keys = "command", values = "enableAccount")
-   @SelectJson("account")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<Account> enableAccount(@QueryParam("account") String accountName, @QueryParam("domainid") String domainId);
-
-
-   /**
-    * @see DomainAccountAsyncClient#disableAccount
-    */
-   @Named("disableAccount")
-   @GET
-   @QueryParams(keys = "command", values = "disableAccount")
-   @Unwrap
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<AsyncCreateResponse> disableAccount(@QueryParam("account") String accountName,
-      @QueryParam("domainid") String domainId, @QueryParam("lock") boolean onlyLock);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c6986efd/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountClient.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountClient.java
deleted file mode 100644
index 94e6cc6..0000000
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/DomainAccountClient.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.cloudstack.features;
-
-import org.jclouds.cloudstack.domain.Account;
-import org.jclouds.cloudstack.domain.AsyncCreateResponse;
-
-/**
- * Provides synchronous access to CloudStack Account features available to Domain
- * Admin users.
- * 
- * @author Adrian Cole
- * @see <a href=
- *      "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
- *      />
- */
-public interface DomainAccountClient extends AccountClient {
-
-   /**
-    * Enable an account
-    *
-    * @param accountName
-    *    the account name you are enabling
-    * @param domainId
-    *    the domain ID
-    */
-   Account enableAccount(String accountName, String domainId);
-
-   /**
-    * Disable or lock an account
-    *
-    * @param accountName
-    *    the account name you are disabling
-    * @param domainId
-    *    the domain ID
-    * @param onlyLock
-    *    only lock if true disable otherwise
-    */
-   AsyncCreateResponse disableAccount(String accountName, String domainId, boolean onlyLock);
-
-}