diff --git a/drupalorg_drush.drush.inc b/drupalorg_drush.drush.inc
index 1b24f78..b315ebe 100644
--- a/drupalorg_drush.drush.inc
+++ b/drupalorg_drush.drush.inc
@@ -123,6 +123,9 @@ function drupalorg_drush_make_validate_info($info) {
         'DrushMakeDo_ProjectPatch',
         'DrushMakeDo_ProjectUpdateXML',
       ),
+      'download' => array(
+        'DrushMakeDo_DownloadWhitelist',
+      ),
     );
     $pass = TRUE;
     foreach ($transformers['top'] as $transformer) {
@@ -136,6 +139,12 @@ function drupalorg_drush_make_validate_info($info) {
           $object = new $transformer('make');
           $pass = $pass && $object->verify($project_data, $project, $info['core']);
         }
+        if (isset($project_data['download'])) {
+          foreach ($transformers['download'] as $transformer) {
+            $object = new $transformer('make');
+            $pass = $pass && $object->verify($project_data['download'], $project, $info['core']);
+          }
+        }
         $info['projects'][$project] = $project_data;
       }
     }
@@ -223,16 +232,11 @@ abstract class DrushMakeDo_Transformer {
    * TRUE if the version string is bad, FALSE otherwise.
    */
   protected function validVersion($name, $version_string) {
-    // Development snapshots not allowed.
-    if (preg_match('/.*-dev$/', $version_string)) {
-      make_error('BUILD_ERROR', dt('%project branch releases not allowed.', array('%project' => $name)));
-      return FALSE;
-    }
     // Basic sanity checking on release version strings. We need this because
     // make supports projects[foo][version] = 1, which downloads the latest
     // stable release on the major version 1 branch. We require a specific
     // release.
-    elseif (!preg_match('/^\d+\.\d+(-[a-z0-9]+)?$/', $version_string)) {
+    if (!preg_match('/^\d+\.((\d+)|x)(-[a-z0-9]+)?(-dev)?$/', $version_string)) {
       make_error('BUILD_ERROR', dt('%project version format incorrect -- specifying an official release version is required.', array('%project' => $name)));
       return FALSE;
     }
@@ -283,12 +287,39 @@ class DrushMakeDo_TopWhitelist extends DrushMakeDo_Whitelist {
 }
 class DrushMakeDo_ProjectWhitelist extends DrushMakeDo_Whitelist {
   // The list of currently allowed project-level attributes.
-  protected $attribute_whitelist = array('version', 'subdir', 'patch');
+  protected $attribute_whitelist = array('version', 'subdir', 'patch', 'download');
   protected $level = 'project';
   function error_message($attribute, $name) {
     return dt("The project-level attribute '%attribute' on project '%project' is not allowed.", array('%attribute' => $attribute, '%project' => $name));
   }
 }
+
+/**
+ * Verify that download level attributes such as
+ * `$project['foo']['download']['url']` are not allowed. (Meaning
+ * only git from d.o. can be specified.)
+ */
+class DrushMakeDo_DownloadWhitelist extends DrushMakeDo_Whitelist {
+  // The list of currently allowed project-download-level attributes.
+  protected $attribute_whitelist = array('revision', 'branch', 'tag', 'type');
+  protected $level = 'download';
+
+  /**
+   * Need special handling for the type attribute (it can be set, but
+   * must be 'git').
+   */
+  function verify(&$makefile, $name = NULL) {
+    if (($pass = parent::verify($makefile, $name)) && isset($makefile['type'])) {
+      $pass = $makefile['type'] === 'git';
+    }
+    return $pass;
+  }
+
+  function error_message($attribute, $name) {
+    return dt("The project-download-level attribute '%attribute' on project '%project' is not allowed.", array('%attribute' => $attribute, '%project' => $project));
+  }
+}
+
 class DrushMakeDo_CoreVersion extends DrushMakeDo_Transformer {
   function verify(&$makefile) {
     return $this->validVersion(dt('Drupal core'), $makefile['core_release']);
diff --git a/tests/drupalorgTest.php b/tests/drupalorgTest.php
index 99adac4..5ca4bd1 100644
--- a/tests/drupalorgTest.php
+++ b/tests/drupalorgTest.php
@@ -44,8 +44,8 @@ class drupalorgDrushMakeTestCase extends Drush_CommandTestCase {
     $this->runMakefileTest('do-fail-attribute');
   }
 
-  function testMakeDoFailDev() {
-    $this->runMakefileTest('do-fail-dev');
+  function testMakeDoPassDev() {
+    $this->runMakefileTest('do-pass-dev');
   }
 
   function testMakeDoFailLibrary() {
@@ -64,11 +64,13 @@ class drupalorgDrushMakeTestCase extends Drush_CommandTestCase {
     $this->runMakefileTest('do-succeed');
   }
 
-  // TODO: This test should be fixed to succeed when dev branches are allowed.
-  function testMakeDoSucceedBranch() {
+  function testMakeDoFailBranch() {
     $this->runMakefileTest('do-fail-branch');
   }
 
+  function testMakeDoSucceedBranch(){
+    $this->runMakefileTest('do-succeed-branch');
+  }
 
   function getMakefile($key) {
     static $tests = array(
@@ -78,10 +80,10 @@ class drupalorgDrushMakeTestCase extends Drush_CommandTestCase {
         'fail'    => TRUE,
         'options' => array(),
       ),
-      'do-fail-dev' => array(
-        'name'     => 'D.o: Fail dev',
-        'makefile' => 'do-fail-dev.make',
-        'fail'    => TRUE,
+      'do-pass-dev' => array(
+        'name'     => 'D.o: pass dev',
+        'makefile' => 'do-pass-dev.make',
+        'md5' => '85e90b3c8be145b8c7c42573f8a3cef7',
         'options' => array(),
       ),
       'do-fail-library' => array(
@@ -108,12 +110,22 @@ class drupalorgDrushMakeTestCase extends Drush_CommandTestCase {
         'md5' => 'b67274358560a07dd88a1947855e4ea2',
         'options' => array(),
       ),
-      // TODO: This test should be fixed to succeed when dev branches are allowed.
       'do-fail-branch' => array(
-        'name' => 'D.o: Branch with revision',
+        'name' => "D.o: Branch with 'url' specified",
         'makefile' => 'do-fail-branch.make',
         'fail'    => TRUE,
-        'md5' => 'a4e5615ab8c30860b112dc6c9c4b5c96',
+        'options' => array(),
+      ),
+      'do-fail-no-branch' => array(
+        'name' => 'D.o: Branch with no revision',
+        'makefile' => 'do-fail-no-branch.make',
+        'fail' => TRUE,
+        'options' => array(),
+      ),
+      'do-succeed-branch' => array(
+        'name' => 'D.o: Branch with revision specified',
+        'makefile' => 'do-succeed-branch.make',
+        'md5' => '4206537eb194438ed9bf54afa5694d99',
         'options' => array(),
       ),
     );
diff --git a/tests/makefiles/do-fail-branch.make b/tests/makefiles/do-fail-branch.make
index 542a161..0f37eef 100644
--- a/tests/makefiles/do-fail-branch.make
+++ b/tests/makefiles/do-fail-branch.make
@@ -3,4 +3,6 @@ api = 2
 
 projects[views][version] = "3.x-dev"
 projects[views][download][type] = "git"
-projects[views][download][revision] = "f332f59"
\ No newline at end of file
+projects[views][download][revision] = "f332f59"
+; Will fail since the 'url' attribute is not allowed.
+projects[views][download][url] = "git://git.drupal.org/project/views.git"
\ No newline at end of file
diff --git a/tests/makefiles/do-fail-dev.make b/tests/makefiles/do-fail-dev.make
deleted file mode 100644
index 87d9381..0000000
--- a/tests/makefiles/do-fail-dev.make
+++ /dev/null
@@ -1,4 +0,0 @@
-core = 6.16
-api = 2
-
-projects[cck][version] = 2.x-dev
\ No newline at end of file
diff --git a/tests/makefiles/do-fail-no-branch.make b/tests/makefiles/do-fail-no-branch.make
new file mode 100644
index 0000000..0e048b3
--- /dev/null
+++ b/tests/makefiles/do-fail-no-branch.make
@@ -0,0 +1,6 @@
+core = 7.10
+api = 2
+
+; Should fail since 'version' isn't specified.
+projects[views][download][type] = "git"
+projects[views][download][revision] = "f332f59"
diff --git a/tests/makefiles/do-pass-dev.make b/tests/makefiles/do-pass-dev.make
new file mode 100644
index 0000000..87d9381
--- /dev/null
+++ b/tests/makefiles/do-pass-dev.make
@@ -0,0 +1,4 @@
+core = 6.16
+api = 2
+
+projects[cck][version] = 2.x-dev
\ No newline at end of file
diff --git a/tests/makefiles/do-succeed-branch.make b/tests/makefiles/do-succeed-branch.make
new file mode 100644
index 0000000..a649bed
--- /dev/null
+++ b/tests/makefiles/do-succeed-branch.make
@@ -0,0 +1,6 @@
+core = 7.10
+api = 2
+
+projects[views][version] = "3.x-dev"
+projects[views][download][type] = "git"
+projects[views][download][revision] = "f332f59"
