Merge branch 'master' of github.com:jclouds/jclouds into 1.5.x

* 'master' of github.com:jclouds/jclouds:
  support beta versions
diff --git a/core/src/main/java/org/jclouds/JcloudsVersion.java b/core/src/main/java/org/jclouds/JcloudsVersion.java
index 6aaf244..be7e72b 100644
--- a/core/src/main/java/org/jclouds/JcloudsVersion.java
+++ b/core/src/main/java/org/jclouds/JcloudsVersion.java
@@ -39,10 +39,11 @@
     static final String VERSION_RESOURCE_FILE = "META-INF/maven/org.jclouds/jclouds-core/pom.properties";
     private static final String VERSION_PROPERTY_NAME = "version";
 
-    // x.y.z or x.y.z-alpha.n or x.y.z-rc.n or x.y.z-SNAPSHOT - see http://semver.org
+    // x.y.z or x.y.z-alpha.n or x.y.z-beta.n or x.y.z-rc.n or x.y.z-SNAPSHOT - see http://semver.org
     private static final Pattern SEMANTIC_VERSION_PATTERN =
-        Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(?:-(alpha|rc)\\.(\\d+)|-SNAPSHOT)?");
+        Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(?:-(alpha|beta|rc)\\.(\\d+)|-SNAPSHOT)?");
     private static final String ALPHA_VERSION_IDENTIFIER = "alpha";
+    private static final String BETA_VERSION_IDENTIFIER = "beta";
 
     private static final JcloudsVersion INSTANCE = new JcloudsVersion();
 
@@ -50,11 +51,18 @@
     public final int minorVersion;
     public final int patchVersion;
     public final boolean alpha;
+    public final boolean beta;
 
     /**
      * Non-null iff {@link #alpha} is {@code true}
      */
     public final @Nullable Integer alphaVersion;
+
+    /**
+     * Non-null iff {@link #beta} is {@code true}
+     */
+    public final @Nullable Integer betaVersion;
+
     public final boolean releaseCandidate;
 
     /**
@@ -90,28 +98,41 @@
         checkArgument(versionMatcher.matches(), "Version '%s' did not match expected pattern '%s'", 
                 version, SEMANTIC_VERSION_PATTERN);
         this.version = version;
-        // a match will produce three or five matching groups (alpha/release candidate identifier and version optional)
+        // a match will produce three or five matching groups (alpha/beta/release candidate identifier and version optional)
         majorVersion = Integer.valueOf(versionMatcher.group(1));
         minorVersion = Integer.valueOf(versionMatcher.group(2));
         patchVersion = Integer.valueOf(versionMatcher.group(3));
 
-        String alphaOrReleaseCandidateVersionIfPresent = versionMatcher.group(4);
-        if (alphaOrReleaseCandidateVersionIfPresent != null) {
+        String alphaOrBetaOrReleaseCandidateVersionIfPresent = versionMatcher.group(4);
+        if (alphaOrBetaOrReleaseCandidateVersionIfPresent != null) {
             Integer alphaOrReleaseCandidateVersion = Integer.valueOf(versionMatcher.group(5));
-            if (alphaOrReleaseCandidateVersionIfPresent.equals(ALPHA_VERSION_IDENTIFIER)) {
+            if (alphaOrBetaOrReleaseCandidateVersionIfPresent.equals(ALPHA_VERSION_IDENTIFIER)) {
                 alpha = true;
                 alphaVersion = alphaOrReleaseCandidateVersion;
+                beta = false;
+                betaVersion = null;
+                releaseCandidate = false;
+                releaseCandidateVersion = null;
+            } else if (alphaOrBetaOrReleaseCandidateVersionIfPresent.equals(BETA_VERSION_IDENTIFIER)) {
+                alpha = false;
+                alphaVersion = null;
+                beta = true;
+                betaVersion = alphaOrReleaseCandidateVersion;
                 releaseCandidate = false;
                 releaseCandidateVersion = null;
             } else {
                 alpha = false;
                 alphaVersion = null;
+                beta = false;
+                betaVersion = null;
                 releaseCandidate = true;
                 releaseCandidateVersion = alphaOrReleaseCandidateVersion;
             }
         } else {
             alpha = false;
             alphaVersion = null;
+            beta = false;
+            betaVersion = null;
             releaseCandidate = false;
             releaseCandidateVersion = null;
         }
@@ -128,4 +149,4 @@
     public static JcloudsVersion get() {
         return INSTANCE;
     }
-}
\ No newline at end of file
+}
diff --git a/core/src/test/java/org/jclouds/JcloudsVersionTest.java b/core/src/test/java/org/jclouds/JcloudsVersionTest.java
index 9f7bac8..96db0fb 100644
--- a/core/src/test/java/org/jclouds/JcloudsVersionTest.java
+++ b/core/src/test/java/org/jclouds/JcloudsVersionTest.java
@@ -61,6 +61,11 @@
     }
 
     @Test(expectedExceptions = { IllegalArgumentException.class })
+    public void testFailsIfBetSanapshot() {
+        new JcloudsVersion("1.2.3-beta.5-SNAPSHOT");
+    }
+
+    @Test(expectedExceptions = { IllegalArgumentException.class })
     public void testFailsIfReleaseCandidateSnapshot() {
         new JcloudsVersion("1.2.3-rc.4-SNAPSHOT");
     }
@@ -95,7 +100,9 @@
     public void testSupportsReleaseVersion() {
         JcloudsVersion version = new JcloudsVersion("1.2.3");
         assertFalse(version.alpha, "Expected non-alpha");
+        assertFalse(version.beta, "Expected non-beta");
         assertNull(version.alphaVersion);
+        assertNull(version.betaVersion);
         assertFalse(version.releaseCandidate, "Expected non-release candidate");
         assertNull(version.releaseCandidateVersion);
     }
@@ -113,6 +120,18 @@
     }
 
     @Test
+    public void testRecognisesBeta() {
+        JcloudsVersion version = new JcloudsVersion("1.2.3-beta.5");
+        assertTrue(version.beta, "Expected beta");
+    }
+
+    @Test
+    public void testExtractsBetaVersion() {
+        JcloudsVersion version = new JcloudsVersion("1.2.3-beta.5");
+        assertEquals(Integer.valueOf(5), version.betaVersion);
+    }
+
+    @Test
     public void testRecognisesReleaseCandidate() {
         JcloudsVersion version = new JcloudsVersion("1.2.3-rc.4");
         assertTrue(version.releaseCandidate, "Expected release candidate");
@@ -140,4 +159,4 @@
                     : delegate.getResourceAsStream(name));
         }
     }
-}
\ No newline at end of file
+}