Add support for Keystone V3
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApiMetadata.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApiMetadata.java
index fec4e6a..1487af0 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApiMetadata.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApiMetadata.java
@@ -16,17 +16,18 @@
  */
 package org.jclouds.openstack.neutron.v2;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
-import org.jclouds.openstack.keystone.v2_0.config.AuthenticationApiModule;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.neutron.v2.config.NeutronHttpApiModule;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
@@ -59,6 +60,7 @@
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(SERVICE_TYPE, ServiceType.NETWORK);
       properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       return properties;
    }
 
@@ -76,8 +78,8 @@
             .defaultEndpoint("http://localhost:5000/v2.0/")
             .defaultProperties(NeutronApiMetadata.defaultProperties())
             .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-               .add(AuthenticationApiModule.class)
-               .add(KeystoneAuthenticationModule.class)
+               .add(AuthenticationModule.class)
+               .add(ServiceCatalogModule.class)
                .add(RegionModule.class)
                .add(NeutronHttpApiModule.class).build());
       }
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FWaaSApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FWaaSApi.java
index 35307b1..a4f45db 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FWaaSApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FWaaSApi.java
@@ -31,8 +31,8 @@
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.CreateFirewall;
 import org.jclouds.openstack.neutron.v2.domain.CreateFirewallPolicy;
 import org.jclouds.openstack.neutron.v2.domain.CreateFirewallRule;
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FloatingIPApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FloatingIPApi.java
index ffd5c9e..a00bc04 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FloatingIPApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/FloatingIPApi.java
@@ -31,7 +31,7 @@
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.FloatingIP;
 import org.jclouds.openstack.neutron.v2.domain.FloatingIPs;
 import org.jclouds.openstack.neutron.v2.fallbacks.EmptyFloatingIPsFallback;
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/RouterApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/RouterApi.java
index b79553d..383c70e 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/RouterApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/RouterApi.java
@@ -31,7 +31,7 @@
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.Router;
 import org.jclouds.openstack.neutron.v2.domain.RouterInterface;
 import org.jclouds.openstack.neutron.v2.domain.Routers;
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/lbaas/v1/LBaaSApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/lbaas/v1/LBaaSApi.java
index 6f6d767..f67c6e3 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/lbaas/v1/LBaaSApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/lbaas/v1/LBaaSApi.java
@@ -32,7 +32,7 @@
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.lbaas.v1.HealthMonitor;
 import org.jclouds.openstack.neutron.v2.domain.lbaas.v1.HealthMonitors;
 import org.jclouds.openstack.neutron.v2.domain.lbaas.v1.Member;
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java
index 2706517..af908fc 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java
@@ -31,7 +31,7 @@
 import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.Network;
 import org.jclouds.openstack.neutron.v2.domain.Networks;
 import org.jclouds.openstack.neutron.v2.fallbacks.EmptyNetworksFallback;
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/PortApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/PortApi.java
index 3797810..3cd0e35 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/PortApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/PortApi.java
@@ -16,13 +16,23 @@
  */
 package org.jclouds.openstack.neutron.v2.features;
 
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
 import org.jclouds.Fallbacks;
 import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.Port;
 import org.jclouds.openstack.neutron.v2.domain.Ports;
 import org.jclouds.openstack.neutron.v2.fallbacks.EmptyPortsFallback;
@@ -36,16 +46,8 @@
 import org.jclouds.rest.annotations.Transform;
 import org.jclouds.rest.annotations.WrapWith;
 
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
+import com.google.common.annotations.Beta;
+import com.google.common.collect.FluentIterable;
 
 /**
  * Provides access to Port operations for the OpenStack Networking (Neutron) v2 API.
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApi.java
index 4b9803c..3646c17 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApi.java
@@ -30,7 +30,7 @@
 import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.Rule;
 import org.jclouds.openstack.neutron.v2.domain.Rules;
 import org.jclouds.openstack.neutron.v2.domain.SecurityGroup;
diff --git a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SubnetApi.java b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SubnetApi.java
index ffb7dcd..62fa7bb 100644
--- a/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SubnetApi.java
+++ b/apis/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/SubnetApi.java
@@ -16,12 +16,24 @@
  */
 package org.jclouds.openstack.neutron.v2.features;
 
-import com.google.common.collect.FluentIterable;
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
 import org.jclouds.Fallbacks;
 import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.neutron.v2.domain.Subnet;
 import org.jclouds.openstack.neutron.v2.domain.Subnets;
 import org.jclouds.openstack.neutron.v2.fallbacks.EmptySubnetsFallback;
@@ -35,17 +47,7 @@
 import org.jclouds.rest.annotations.Transform;
 import org.jclouds.rest.annotations.WrapWith;
 
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
+import com.google.common.collect.FluentIterable;
 
 /**
  * Provides access to Subnet operations for the OpenStack Networking (Neutron) v2 API.
diff --git a/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApiLiveTest.java b/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApiLiveTest.java
index 2cb30fc..37ebe3d 100644
--- a/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApiLiveTest.java
+++ b/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/features/SecurityGroupApiLiveTest.java
@@ -17,6 +17,8 @@
 
 package org.jclouds.openstack.neutron.v2.features;
 
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.size;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
@@ -29,6 +31,8 @@
 import org.jclouds.openstack.neutron.v2.internal.BaseNeutronApiLiveTest;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Predicate;
+
 /**
  * Tests parsing and Guice wiring of RouterApi
  */
@@ -67,8 +71,12 @@
 
             assertEquals(securityGroup.getName(), "jclouds-test");
             assertEquals(securityGroup.getDescription(), "jclouds test security group");
-
-            assertEquals(securityGroup.getRules().size(), 1);
+            assertEquals(size(filter(securityGroup.getRules(), new Predicate<Rule>() {
+               @Override
+               public boolean apply(Rule input) {
+                  return RuleDirection.INGRESS.equals(input.getDirection());
+               }
+            })), 1);
 
             Rule newSecGroupRule = null;
 
diff --git a/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiLiveTest.java b/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiLiveTest.java
index f220a92..d544aba 100644
--- a/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiLiveTest.java
+++ b/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiLiveTest.java
@@ -16,13 +16,15 @@
  */
 package org.jclouds.openstack.neutron.v2.internal;
 
+import java.util.Properties;
+
 import org.jclouds.apis.BaseApiLiveTest;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.logging.config.LoggingModule;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.neutron.v2.NeutronApi;
 import org.testng.annotations.Test;
 
-import java.util.Properties;
-
 /**
  * Tests behavior of {@code NeutronApi}
  *
@@ -35,6 +37,11 @@
    }
 
    @Override
+   protected LoggingModule getLoggingModule() {
+      return new SLF4JLoggingModule();
+   }
+
+   @Override
    protected Properties setupProperties() {
       Properties props = super.setupProperties();
       setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE);
diff --git a/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiMockTest.java b/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiMockTest.java
index d180e55..be7d245 100644
--- a/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiMockTest.java
+++ b/apis/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/internal/BaseNeutronApiMockTest.java
@@ -16,12 +16,12 @@
  */
 package org.jclouds.openstack.neutron.v2.internal;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
 import org.jclouds.openstack.neutron.v2.NeutronApi;
 import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
 
diff --git a/apis/openstack-neutron/src/test/resources/logback.xml b/apis/openstack-neutron/src/test/resources/logback.xml
index 02685ca..5c37355 100644
--- a/apis/openstack-neutron/src/test/resources/logback.xml
+++ b/apis/openstack-neutron/src/test/resources/logback.xml
@@ -1,35 +1,42 @@
 <?xml version="1.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.
-
--->
-<configuration>
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+<configuration scan="false">
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds.log</file>
         <encoder>
-            <pattern>-  %msg%n</pattern>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
         </encoder>
     </appender>
-    <root level="info">
-        <appender-ref ref="STDOUT"/>
-    </root>
-    <logger name="jclouds.compute" level="debug"/>
-    <logger name="net.schmizz" level="warn"/>
-    <logger name="jclouds.wire" level="debug"/>
-    <logger name="jclouds.headers" level="debug"/>
-    <logger name="jclouds.ssh" level="debug"/>
-</configuration>
+    <appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds-wire.log</file>
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+    <appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds-compute.log</file>
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
 
+    <logger name="org.jclouds">
+        <level value="DEBUG" />
+        <appender-ref ref="FILE" />
+    </logger>
+    <logger name="jclouds.compute">
+        <level value="DEBUG" />
+        <appender-ref ref="COMPUTEFILE" />
+    </logger>
+    <logger name="jclouds.wire">
+        <level value="DEBUG" />
+        <appender-ref ref="WIREFILE" />
+    </logger>
+    <logger name="jclouds.headers">
+        <level value="DEBUG" />
+        <appender-ref ref="WIREFILE" />
+    </logger>
+
+    <root>
+        <level value="INFO" />
+    </root>
+</configuration>
\ No newline at end of file