diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py
index 7590fb1298927ff34d34b066e120ebc328e94508..ce7d0197f022c2088cc23065f649d7a70921c9a2 100644
--- a/lib/spack/llnl/util/lang.py
+++ b/lib/spack/llnl/util/lang.py
@@ -119,9 +119,8 @@ def caller_locals():
 
 
 def get_calling_package_name():
-    """Make sure that the caller is a class definition, and return
-       the module's name.  This is useful for getting the name of
-       spack packages from inside a relation function.
+    """Make sure that the caller is a class definition, and return the
+       module's name.
     """
     stack = inspect.stack()
     try:
@@ -144,8 +143,9 @@ def get_calling_package_name():
 def attr_required(obj, attr_name):
     """Ensure that a class has a required attribute."""
     if not hasattr(obj, attr_name):
-        tty.die("No required attribute '%s' in class '%s'"
-                % (attr_name, obj.__class__.__name__))
+        raise RequiredAttributeError(
+            "No required attribute '%s' in class '%s'"
+            % (attr_name, obj.__class__.__name__))
 
 
 def attr_setdefault(obj, name, value):
@@ -259,3 +259,8 @@ def in_function(function_name):
         return False
     finally:
         del stack
+
+
+class RequiredAttributeError(ValueError):
+    def __init__(self, message):
+        super(RequiredAttributeError, self).__init__(message)
diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index d0cf8804ba79116d0c5f4818f55a97aa76ec94b6..50fe453cfb7530ad3cc3f8f66b38344ab3bcb9c6 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -32,7 +32,7 @@
 # TODO: maybe this should be separated out and should go in build_environment.py?
 # TODO: it's not clear where all the stuff that needs to be included in packages
 #       should live.  This file is overloaded for spack core vs. for packages.
-__all__ = ['Package', 'when', 'provides', 'depends_on',
+__all__ = ['Package', 'when', 'provides', 'depends_on', 'version',
            'patch', 'Version', 'working_dir', 'which', 'Executable',
            'filter_file', 'change_sed_delimiter']
 
@@ -146,6 +146,6 @@
 #
 from llnl.util.filesystem import working_dir
 from spack.package import Package
-from spack.relations import depends_on, provides, patch
+from spack.relations import *
 from spack.multimethod import when
 from spack.version import Version
diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py
index cc9a1342e74f5f492c3018d231ba052337655326..1a1a19a4b62dd4d671f809e552104bfc1b89a32f 100644
--- a/lib/spack/spack/cmd/create.py
+++ b/lib/spack/spack/cmd/create.py
@@ -70,7 +70,7 @@ class ${class_name}(Package):
     homepage = "http://www.example.com"
     url      = "${url}"
 
-    versions = ${versions}
+${versions}
 
     def install(self, spec, prefix):
         # FIXME: Modify the configure line to suit your build system here.
@@ -114,13 +114,11 @@ def __call__(self, stage):
             self.configure = '%s\n        # %s' % (autotools, cmake)
 
 
-def make_version_dict(ver_hash_tuples):
-    max_len = max(len(str(v)) for v,hfg in ver_hash_tuples)
-    width = max_len + 2
-    format = "%-" + str(width) + "s : '%s',"
-    sep = '\n                 '
-    return '{ ' + sep.join(format % ("'%s'" % v, h)
-                           for v, h in ver_hash_tuples) + ' }'
+def make_version_calls(ver_hash_tuples):
+    """Adds a version() call to the package for each version found."""
+    max_len = max(len(str(v)) for v, h in ver_hash_tuples)
+    format = "    version(%%-%ds, '%%s')" % (max_len + 2)
+    return '\n'.join(format % ("'%s'" % v, h) for v, h in ver_hash_tuples)
 
 
 def get_name():
@@ -195,7 +193,7 @@ def create(parser, args):
                 configure=guesser.configure,
                 class_name=mod_to_class(name),
                 url=url,
-                versions=make_version_dict(ver_hash_tuples)))
+                versions=make_version_calls(ver_hash_tuples)))
 
     # If everything checks out, go ahead and edit.
     spack.editor(pkg_path)
diff --git a/lib/spack/spack/cmd/edit.py b/lib/spack/spack/cmd/edit.py
index c96cf75c9bc30302eeefdf90ba3b5dd97f03186b..3647186a3cda534588dea295da9b3488461af9f6 100644
--- a/lib/spack/spack/cmd/edit.py
+++ b/lib/spack/spack/cmd/edit.py
@@ -44,7 +44,7 @@ class ${class_name}(Package):
     homepage = "http://www.example.com"
     url      = "http://www.example.com/${name}-1.0.tar.gz"
 
-    versions = { '1.0' : '0123456789abcdef0123456789abcdef' }
+    version('1.0', '0123456789abcdef0123456789abcdef')
 
     def install(self, spec, prefix):
         configure("--prefix=%s" % prefix)
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index f5775ef1bfcc47499ec8819f694fd8438608036d..eb497711b72c91dc033c4f058633f8c4343d65a7 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -72,7 +72,7 @@ def concretize_version(self, spec):
         if valid_versions:
             spec.versions = ver([valid_versions[-1]])
         else:
-            spec.versions = ver([pkg.default_version])
+            raise NoValidVerionError(spec)
 
 
     def concretize_architecture(self, spec):
@@ -158,3 +158,11 @@ def __init__(self, compiler_spec):
         super(UnavailableCompilerVersionError, self).__init__(
             "No available compiler version matches '%s'" % compiler_spec,
             "Run 'spack compilers' to see available compiler Options.")
+
+
+class NoValidVerionError(spack.error.SpackError):
+    """Raised when there is no available version for a package that
+       satisfies a spec."""
+    def __init__(self, spec):
+        super(NoValidVerionError, self).__init__(
+            "No available version of %s matches '%s'" % (spec.name, spec.versions))
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 79a6c2362ebb030b88690c3284b67973789eca5c..90e77b5e8268e223ace7b3be627039a7da2e39f2 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -296,9 +296,12 @@ class SomePackage(Package):
     """
 
     #
-    # These variables are defaults for the various relations defined on
-    # packages.  Subclasses will have their own versions of these.
+    # These variables are defaults for the various "relations".
     #
+    """Map of information about Versions of this package.
+       Map goes: Version -> VersionDescriptor"""
+    versions = {}
+
     """Specs of dependency packages, keyed by name."""
     dependencies = {}
 
@@ -317,16 +320,10 @@ class SomePackage(Package):
     """By default we build in parallel.  Subclasses can override this."""
     parallel = True
 
-    """Dirty hack for forcing packages with uninterpretable URLs
-       TODO: get rid of this.
-    """
-    force_url = False
-
 
     def __init__(self, spec):
         # These attributes are required for all packages.
         attr_required(self.__class__, 'homepage')
-        attr_required(self.__class__, 'url')
 
         # this determines how the package should be built.
         self.spec = spec
@@ -337,24 +334,32 @@ def __init__(self, spec):
         if '.' in self.name:
             self.name = self.name[self.name.rindex('.') + 1:]
 
-        # Make sure URL is an allowed type
-        validate_package_url(self.url)
-
-        # patch up the URL with a new version if the spec version is concrete
-        if self.spec.versions.concrete:
-            self.url = self.url_for_version(self.spec.version)
-
         # This is set by scraping a web page.
         self._available_versions = None
 
-        # versions should be a dict from version to checksum, for safe versions
-        # of this package.  If it's not present, make it an empty dict.
-        if not hasattr(self, 'versions'):
-            self.versions = {}
-
-        if not isinstance(self.versions, dict):
-            raise ValueError("versions attribute of package %s must be a dict!"
-                             % self.name)
+        # Sanity check some required variables that could be
+        # overridden by package authors.
+        def sanity_check_dict(attr_name):
+            if not hasattr(self, attr_name):
+                raise PackageError("Package %s must define %s" % attr_name)
+
+            attr = getattr(self, attr_name)
+            if not isinstance(attr, dict):
+                raise PackageError("Package %s has non-dict %s attribute!"
+                                   % (self.name, attr_name))
+        sanity_check_dict('versions')
+        sanity_check_dict('dependencies')
+        sanity_check_dict('conflicted')
+        sanity_check_dict('patches')
+
+        # Check versions in the versions dict.
+        for v in self.versions:
+            assert(isinstance(v, Version))
+
+        # Check version descriptors
+        for v in sorted(self.versions):
+            vdesc = self.versions[v]
+            assert(isinstance(vdesc, spack.relations.VersionDescriptor))
 
         # Version-ize the keys in versions dict
         try:
@@ -366,6 +371,10 @@ def __init__(self, spec):
         # stage used to build this package.
         self._stage = None
 
+        # patch up self.url based on the actual version
+        if self.spec.concrete:
+            self.url = self.url_for_version(self.version)
+
         # Set a default list URL (place to find available versions)
         if not hasattr(self, 'list_url'):
             self.list_url = None
@@ -374,18 +383,6 @@ def __init__(self, spec):
             self.list_depth = 1
 
 
-    @property
-    def default_version(self):
-        """Get the version in the default URL for this package,
-           or fails."""
-        try:
-            return url.parse_version(self.__class__.url)
-        except UndetectableVersionError:
-            raise PackageError(
-                "Couldn't extract a default version from %s." % self.url,
-                " You must specify it explicitly in the package file.")
-
-
     @property
     def version(self):
         if not self.spec.concrete:
@@ -514,16 +511,50 @@ def url_version(self, version):
            override this, e.g. for boost versions where you need to ensure that there
            are _'s in the download URL.
         """
-        if self.force_url:
-            return self.default_version
         return str(version)
 
 
     def url_for_version(self, version):
-        """Gives a URL that you can download a new version of this package from."""
-        if self.force_url:
-            return self.url
-        return url.substitute_version(self.__class__.url, self.url_version(version))
+        """Returns a URL that you can download a new version of this package from."""
+        if not isinstance(version, Version):
+            version = Version(version)
+
+        def nearest_url(version):
+            """Finds the URL for the next lowest version with a URL.
+               If there is no lower version with a URL, uses the
+               package url property. If that isn't there, uses a
+               *higher* URL, and if that isn't there raises an error.
+            """
+            url = getattr(self, 'url', None)
+            for v in sorted(self.versions):
+                if v > version and url:
+                    break
+                if self.versions[v].url:
+                    url = self.versions[v].url
+            if not url:
+                raise PackageVersionError(v)
+            return url
+
+        if version in self.versions:
+            vdesc = self.versions[version]
+            if not vdesc.url:
+                base_url = nearest_url(version)
+                vdesc.url = url.substitute_version(
+                    base_url, self.url_version(version))
+            return vdesc.url
+        else:
+            return nearest_url(version)
+
+
+    @property
+    def default_url(self):
+        if self.concrete:
+            return self.url_for_version(self.version)
+        else:
+            url = getattr(self, 'url', None)
+            if url:
+                return url
+
 
 
     def remove_prefix(self):
@@ -548,7 +579,7 @@ def do_fetch(self):
         self.stage.fetch()
 
         if spack.do_checksum and self.version in self.versions:
-            digest = self.versions[self.version]
+            digest = self.versions[self.version].checksum
             self.stage.check(digest)
             tty.msg("Checksum passed for %s@%s" % (self.name, self.version))
 
@@ -779,6 +810,9 @@ def do_clean_dist(self):
 
 
     def fetch_available_versions(self):
+        if not hasattr(self, 'url'):
+            raise VersionFetchError(self.__class__)
+
         # If not, then try to fetch using list_url
         if not self._available_versions:
             try:
@@ -865,7 +899,6 @@ def print_pkg(message):
     print message
 
 
-
 class FetchError(spack.error.SpackError):
     """Raised when something goes wrong during fetch."""
     def __init__(self, message, long_msg=None):
@@ -889,3 +922,19 @@ class InvalidPackageDependencyError(PackageError):
        its dependencies."""
     def __init__(self, message):
         super(InvalidPackageDependencyError, self).__init__(message)
+
+
+class PackageVersionError(PackageError):
+    """Raised when a version URL cannot automatically be determined."""
+    def __init__(self, version):
+        super(PackageVersionError, self).__init__(
+            "Cannot determine a URL automatically for version %s." % version,
+            "Please provide a url for this version in the package.py file.")
+
+
+class VersionFetchError(PackageError):
+    """Raised when a version URL cannot automatically be determined."""
+    def __init__(self, cls):
+        super(VersionFetchError, self).__init__(
+            "Cannot fetch version for package %s " % cls.__name__ +
+            "because it does not define a default url.")
diff --git a/lib/spack/spack/relations.py b/lib/spack/spack/relations.py
index f46b7dfc84da8cd000417b5b8831bea4194e57c9..a7b46cfb331e109b88609d04cdfbac2f7c1669d5 100644
--- a/lib/spack/spack/relations.py
+++ b/lib/spack/spack/relations.py
@@ -68,6 +68,8 @@ class Mpileaks(Package):
         spack install mpileaks ^mvapich
         spack install mpileaks ^mpich
 """
+__all__ = [ 'depends_on', 'provides', 'patch', 'version' ]
+
 import re
 import inspect
 import importlib
@@ -77,14 +79,38 @@ class Mpileaks(Package):
 import spack
 import spack.spec
 import spack.error
+import spack.url
 
+from spack.version import Version
 from spack.patch import Patch
 from spack.spec import Spec, parse_anonymous_spec
 
 
-"""Adds a dependencies local variable in the locals of
-   the calling class, based on args. """
+class VersionDescriptor(object):
+    """A VersionDescriptor contains information to describe a
+       particular version of a package.  That currently includes a URL
+       for the version along with a checksum."""
+    def __init__(self, checksum, url):
+        self.checksum = checksum
+        self.url = url
+
+
+def version(ver, checksum, **kwargs):
+    """Adds a version and associated metadata to the package."""
+    pkg = caller_locals()
+
+    versions = pkg.setdefault('versions', {})
+    patches  = pkg.setdefault('patches', {})
+
+    ver = Version(ver)
+    url = kwargs.get('url', None)
+
+    versions[ver] = VersionDescriptor(checksum, url)
+
+
 def depends_on(*specs):
+    """Adds a dependencies local variable in the locals of
+       the calling class, based on args. """
     pkg = get_calling_package_name()
 
     dependencies = caller_locals().setdefault('dependencies', {})
diff --git a/lib/spack/spack/test/package_sanity.py b/lib/spack/spack/test/package_sanity.py
index 1a7bc5dc5e8b2f97e09a2dc485d75026b726262e..e3de6950702fdb718a4cc9d3c97527ddcde4638e 100644
--- a/lib/spack/spack/test/package_sanity.py
+++ b/lib/spack/spack/test/package_sanity.py
@@ -29,19 +29,35 @@
 
 import spack
 import spack.url as url
+from spack.packages import PackageDB
+
 
 class PackageSanityTest(unittest.TestCase):
 
-    def test_get_all_packages(self):
-        """Get all packages once and make sure that works."""
+    def check_db(self):
+        """Get all packages in a DB to make sure they work."""
         for name in spack.db.all_package_names():
             spack.db.get(name)
 
 
+    def test_get_all_packages(self):
+        """Get all packages once and make sure that works."""
+        self.check_db()
+
+
+    def test_get_all_mock_packages(self):
+        """Get the mock packages once each too."""
+        tmp = spack.db
+        spack.db = PackageDB(spack.mock_packages_path)
+        self.check_db()
+        spack.db = tmp
+
+
     def test_url_versions(self):
-        """Ensure that url_for_version does the right thing for at least the
-           default version of each package.
-        """
+        """Check URLs for regular packages, if they are explicitly defined."""
         for pkg in spack.db.all_packages():
-            v = url.parse_version(pkg.url)
-            self.assertEqual(pkg.url, pkg.url_for_version(v))
+            for v, vdesc in pkg.versions.items():
+                if vdesc.url:
+                    # If there is a url for the version check it.
+                    v_url = pkg.url_for_version(v)
+                    self.assertEqual(vdesc.url, v_url)
diff --git a/lib/spack/spack/url.py b/lib/spack/spack/url.py
index 1b8120168f29346b2070416d1ebffd9c65ca5a21..902ce9817d8ab036d7151ed57238f69c52c25cb3 100644
--- a/lib/spack/spack/url.py
+++ b/lib/spack/spack/url.py
@@ -82,12 +82,16 @@ def parse_version_string_with_indices(path):
     """Try to extract a version string from a filename or URL.  This is taken
        largely from Homebrew's Version class."""
 
-    if os.path.isdir(path):
-        stem = os.path.basename(path)
-    elif re.search(r'((?:sourceforge.net|sf.net)/.*)/download$', path):
-        stem = comp.stem(os.path.dirname(path))
-    else:
-        stem = comp.stem(path)
+    # Strip off sourceforge download stuffix.
+    if re.search(r'((?:sourceforge.net|sf.net)/.*)/download$', path):
+        path = os.path.dirname(path)
+
+    # Strip archive extension
+    path = comp.strip_extension(path)
+
+    # Take basename to avoid including parent dirs in version name
+    # Remember the offset of the stem in the full path.
+    stem = os.path.basename(path)
 
     version_types = [
         # GitHub tarballs, e.g. v1.2.3
@@ -137,10 +141,10 @@ def parse_version_string_with_indices(path):
         (r'_((\d+\.)+\d+[a-z]?)[.]orig$', stem),
 
         # e.g. http://www.openssl.org/source/openssl-0.9.8s.tar.gz
-        (r'-([^-]+)', stem),
+        (r'-([^-]+(-alpha|-beta)?)', stem),
 
         # e.g. astyle_1.23_macosx.tar.gz
-        (r'_([^_]+)', stem),
+        (r'_([^_]+(_alpha|_beta)?)', stem),
 
         # e.g. http://mirrors.jenkins-ci.org/war/1.486/jenkins.war
         (r'\/(\d\.\d+)\/', path),
@@ -152,7 +156,9 @@ def parse_version_string_with_indices(path):
         regex, match_string = vtype[:2]
         match = re.search(regex, match_string)
         if match and match.group(1) is not None:
-            return match.group(1), match.start(1), match.end(1)
+            version = match.group(1)
+            start = path.index(version)
+            return version, start, start+len(version)
 
     raise UndetectableVersionError(path)
 
diff --git a/lib/spack/spack/util/compression.py b/lib/spack/spack/util/compression.py
index 7ce8e8c65b85795841083b66f782d885cdfbaf50..a67576bd5083a3150c1381f98803e7dfc92b47dd 100644
--- a/lib/spack/spack/util/compression.py
+++ b/lib/spack/spack/util/compression.py
@@ -48,7 +48,7 @@ def decompressor_for(path):
     return tar
 
 
-def stem(path):
+def strip_extension(path):
     """Get the part of a path that does not include its compressed
        type extension."""
     for type in ALLOWED_ARCHIVE_TYPES:
diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py
index ce94303a9c61cb6357136b78ace05697e560fa02..4558f8838438b7446ecaf38c2be32122fbb3f64c 100644
--- a/lib/spack/spack/version.py
+++ b/lib/spack/spack/version.py
@@ -181,7 +181,7 @@ def a_or_n(seg):
 
         # Add possible alpha or beta indicator at the end of each segemnt
         # We treat these specially b/c they're so common.
-        wc += '[ab]?)?' * (len(segments) - 1)
+        wc += '(?:[a-z]|alpha|beta)?)?' * (len(segments) - 1)
         return wc
 
 
diff --git a/var/spack/mock_packages/callpath/package.py b/var/spack/mock_packages/callpath/package.py
index b4fd0f44825696924b6ff985394a44fc8e331596..5b6b70ba2a5cffb15efc5eef47b59fe9dd08bf7d 100644
--- a/var/spack/mock_packages/callpath/package.py
+++ b/var/spack/mock_packages/callpath/package.py
@@ -28,9 +28,9 @@ class Callpath(Package):
     homepage = "https://github.com/tgamblin/callpath"
     url      = "http://github.com/tgamblin/callpath-1.0.tar.gz"
 
-    versions = { 0.8 : 'foobarbaz',
-                 0.9 : 'foobarbaz',
-                 1.0 : 'foobarbaz' }
+    version(0.8, 'foobarbaz')
+    version(0.9, 'foobarbaz')
+    version(1.0, 'foobarbaz')
 
     depends_on("dyninst")
     depends_on("mpi")
diff --git a/var/spack/mock_packages/direct_mpich/package.py b/var/spack/mock_packages/direct_mpich/package.py
index d702e4481b7272dc428021e7c5675a0fb2aa878b..2ced82521b37d8430999409af916da3a087ced26 100644
--- a/var/spack/mock_packages/direct_mpich/package.py
+++ b/var/spack/mock_packages/direct_mpich/package.py
@@ -28,7 +28,7 @@ class DirectMpich(Package):
     homepage = "http://www.example.com"
     url      = "http://www.example.com/direct_mpich-1.0.tar.gz"
 
-    versions = { 1.0 : 'foobarbaz' }
+    version('1.0', 'foobarbaz')
 
     depends_on('mpich')
 
diff --git a/var/spack/mock_packages/dyninst/package.py b/var/spack/mock_packages/dyninst/package.py
index d32c4b55043253bfa1775755509c5a7e16856284..7657e2c33f507d56498b8ebcda1555eba3eb11d7 100644
--- a/var/spack/mock_packages/dyninst/package.py
+++ b/var/spack/mock_packages/dyninst/package.py
@@ -29,9 +29,8 @@ class Dyninst(Package):
     url      = "http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1.2/DyninstAPI-8.1.2.tgz"
     list_url = "http://www.dyninst.org/downloads/dyninst-8.x"
 
-    versions = {
-        '8.1.2' : 'bf03b33375afa66fe0efa46ce3f4b17a',
-        '8.1.1' : '1f8743e3a5662b25ce64a7edf647e77d' }
+    version('8.1.2', 'bf03b33375afa66fe0efa46ce3f4b17a')
+    version('8.1.1', '1f8743e3a5662b25ce64a7edf647e77d')
 
     depends_on("libelf")
     depends_on("libdwarf")
diff --git a/var/spack/mock_packages/fake/package.py b/var/spack/mock_packages/fake/package.py
index 88bc6d866950e1101eee0684ae80243c3b614df8..fb3c2bdd2e7e0872bafd30576c2cb1602345bc60 100644
--- a/var/spack/mock_packages/fake/package.py
+++ b/var/spack/mock_packages/fake/package.py
@@ -27,7 +27,8 @@
 class Fake(Package):
     homepage = "http://www.fake-spack-example.org"
     url      = "http://www.fake-spack-example.org/downloads/fake-1.0.tar.gz"
-    versions = { '1.0' : 'foobarbaz' }
+
+    version('1.0', 'foobarbaz')
 
     def install(self, spec, prefix):
         pass
diff --git a/var/spack/mock_packages/indirect_mpich/package.py b/var/spack/mock_packages/indirect_mpich/package.py
index a53cb9330c7e60bb986be1cf09904d923511bf3a..daf8b4b166ea036edbf15760651b965f39acafe9 100644
--- a/var/spack/mock_packages/indirect_mpich/package.py
+++ b/var/spack/mock_packages/indirect_mpich/package.py
@@ -32,7 +32,7 @@ class IndirectMpich(Package):
     homepage = "http://www.example.com"
     url      = "http://www.example.com/indirect_mpich-1.0.tar.gz"
 
-    versions = { 1.0 : 'foobarbaz' }
+    version(1.0, 'foobarbaz')
 
     depends_on('mpi')
     depends_on('direct_mpich')
diff --git a/var/spack/mock_packages/libdwarf/package.py b/var/spack/mock_packages/libdwarf/package.py
index 0f4d55fd8846f4b8683ace9c577d7af3c92cb0d0..0b8df04cfb276991883b9220ab3ebed2e5b9c4e6 100644
--- a/var/spack/mock_packages/libdwarf/package.py
+++ b/var/spack/mock_packages/libdwarf/package.py
@@ -33,10 +33,10 @@ class Libdwarf(Package):
     url      = "http://www.prevanders.net/libdwarf-20130729.tar.gz"
     list_url = homepage
 
-    versions = { 20130729 : "64b42692e947d5180e162e46c689dfbf",
-                 20130207 : 'foobarbaz',
-                 20111030 : 'foobarbaz',
-                 20070703 : 'foobarbaz' }
+    version(20130729, "64b42692e947d5180e162e46c689dfbf")
+    version(20130207, 'foobarbaz')
+    version(20111030, 'foobarbaz')
+    version(20070703, 'foobarbaz')
 
     depends_on("libelf")
 
diff --git a/var/spack/mock_packages/libelf/package.py b/var/spack/mock_packages/libelf/package.py
index 5ac07de4e3bf8cd9d61200214260f868e74d887d..94c8f942cdb39260cce2094d6d1aa0a7267fa0b5 100644
--- a/var/spack/mock_packages/libelf/package.py
+++ b/var/spack/mock_packages/libelf/package.py
@@ -28,9 +28,9 @@ class Libelf(Package):
     homepage = "http://www.mr511.de/software/english.html"
     url      = "http://www.mr511.de/software/libelf-0.8.13.tar.gz"
 
-    versions =   {'0.8.13' : '4136d7b4c04df68b686570afa26988ac',
-                  '0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7',
-                  '0.8.10' : '9db4d36c283d9790d8fa7df1f4d7b4d9' }
+    version('0.8.13', '4136d7b4c04df68b686570afa26988ac')
+    version('0.8.12', 'e21f8273d9f5f6d43a59878dc274fec7')
+    version('0.8.10', '9db4d36c283d9790d8fa7df1f4d7b4d9')
 
     def install(self, spec, prefix):
         configure("--prefix=%s" % prefix,
diff --git a/var/spack/mock_packages/mpich/package.py b/var/spack/mock_packages/mpich/package.py
index 2a8e1cebe31d714c7c77891f8a0faea69785109b..e86c1a68ac64a1a4ceb904e152a59fe670720063 100644
--- a/var/spack/mock_packages/mpich/package.py
+++ b/var/spack/mock_packages/mpich/package.py
@@ -30,11 +30,11 @@ class Mpich(Package):
     list_url   = "http://www.mpich.org/static/downloads/"
     list_depth = 2
 
-    versions = { '3.0.4' : '9c5d5d4fe1e17dd12153f40bc5b6dbc0',
-                 '3.0.3' : 'foobarbaz',
-                 '3.0.2' : 'foobarbaz',
-                 '3.0.1' : 'foobarbaz',
-                 '3.0'   : 'foobarbaz' }
+    version('3.0.4', '9c5d5d4fe1e17dd12153f40bc5b6dbc0')
+    version('3.0.3', 'foobarbaz')
+    version('3.0.2', 'foobarbaz')
+    version('3.0.1', 'foobarbaz')
+    version('3.0', 'foobarbaz')
 
     provides('mpi@:3', when='@3:')
     provides('mpi@:1', when='@1:')
diff --git a/var/spack/mock_packages/mpich2/package.py b/var/spack/mock_packages/mpich2/package.py
index 84dce4cccb7c0b6645041506fef8ed393620b48e..827b94c8a4a5edc909b1e4ef829ef1c05246a373 100644
--- a/var/spack/mock_packages/mpich2/package.py
+++ b/var/spack/mock_packages/mpich2/package.py
@@ -30,12 +30,12 @@ class Mpich2(Package):
     list_url   = "http://www.mpich.org/static/downloads/"
     list_depth = 2
 
-    versions = { '1.5' : '9c5d5d4fe1e17dd12153f40bc5b6dbc0',
-                 '1.4' : 'foobarbaz',
-                 '1.3' : 'foobarbaz',
-                 '1.2' : 'foobarbaz',
-                 '1.1' : 'foobarbaz',
-                 '1.0' : 'foobarbaz' }
+    version('1.5', '9c5d5d4fe1e17dd12153f40bc5b6dbc0')
+    version('1.4', 'foobarbaz')
+    version('1.3', 'foobarbaz')
+    version('1.2', 'foobarbaz')
+    version('1.1', 'foobarbaz')
+    version('1.0', 'foobarbaz')
 
     provides('mpi@:2.0')
     provides('mpi@:2.1', when='@1.1:')
diff --git a/var/spack/mock_packages/mpileaks/package.py b/var/spack/mock_packages/mpileaks/package.py
index c34d5991e64c364ba413ee5f438c917f08946789..c6be37bc13c9afa87fe2e69fe17235efaee2ec0e 100644
--- a/var/spack/mock_packages/mpileaks/package.py
+++ b/var/spack/mock_packages/mpileaks/package.py
@@ -28,10 +28,10 @@ class Mpileaks(Package):
     homepage = "http://www.llnl.gov"
     url      = "http://www.llnl.gov/mpileaks-1.0.tar.gz"
 
-    versions = { 1.0 : 'foobarbaz',
-                 2.1 : 'foobarbaz',
-                 2.2 : 'foobarbaz',
-                 2.3 : 'foobarbaz' }
+    version(1.0, 'foobarbaz')
+    version(2.1, 'foobarbaz')
+    version(2.2, 'foobarbaz')
+    version(2.3, 'foobarbaz')
 
     depends_on("mpi")
     depends_on("callpath")
diff --git a/var/spack/mock_packages/trivial_install_test_package/package.py b/var/spack/mock_packages/trivial_install_test_package/package.py
index b665825b32d6644ef64c047ba58f69fa0f6620b3..c4db9f5f071042b2e9031daa7bb7a68da9f6111f 100644
--- a/var/spack/mock_packages/trivial_install_test_package/package.py
+++ b/var/spack/mock_packages/trivial_install_test_package/package.py
@@ -30,7 +30,7 @@ class TrivialInstallTestPackage(Package):
     homepage = "http://www.example.com/trivial_install"
     url      = "http://www.unit-test-should-replace-this-url/trivial_install-1.0.tar.gz"
 
-    versions = { '1.0' : 'foobarbaz' }
+    version('1.0', 'foobarbaz')
 
     def install(self, spec, prefix):
         configure('--prefix=%s' % prefix)
diff --git a/var/spack/mock_packages/zmpi/package.py b/var/spack/mock_packages/zmpi/package.py
index a86bd706bbf6d79082b40425d5aefc7c201d34fd..8c6ceda6d3f6332bd525fc042a3e963fa745e131 100644
--- a/var/spack/mock_packages/zmpi/package.py
+++ b/var/spack/mock_packages/zmpi/package.py
@@ -30,7 +30,7 @@ class Zmpi(Package):
     homepage = "http://www.spack-fake-zmpi.org"
     url      = "http://www.spack-fake-zmpi.org/downloads/zmpi-1.0.tar.gz"
 
-    versions = { '1.0' : 'foobarbaz' }
+    version('1.0', 'foobarbaz')
 
     provides('mpi@:10.0')
     depends_on('fake')
diff --git a/var/spack/packages/SAMRAI/package.py b/var/spack/packages/SAMRAI/package.py
index bb88ec32923d2d9fbd50e4b7ddf2d16badca5d33..3dfb00b3917b3a6d52ecd8566069753e429a92e9 100644
--- a/var/spack/packages/SAMRAI/package.py
+++ b/var/spack/packages/SAMRAI/package.py
@@ -11,17 +11,15 @@ class Samrai(Package):
     url      = "https://computation-rnd.llnl.gov/SAMRAI/download/SAMRAI-v3.7.3.tar.gz"
     list_url = homepage
 
-    versions = {
-      '3.7.3'      : '12d574eacadf8c9a70f1bb4cd1a69df6',
-      '3.7.2'      : 'f6a716f171c9fdbf3cb12f71fa6e2737',
-      '3.6.3-beta' : 'ef0510bf2893042daedaca434e5ec6ce',
-      '3.5.2-beta' : 'd072d9d681eeb9ada15ce91bea784274',
-      '3.5.0-beta' : '1ad18a319fc573e12e2b1fbb6f6b0a19',
-      '3.4.1-beta' : '00814cbee2cb76bf8302aff56bbb385b',
-      '3.3.3-beta' : '1db3241d3e1cab913dc310d736c34388',
-      '3.3.2-beta' : 'e598a085dab979498fcb6c110c4dd26c',
-      '2.4.4'      : '04fb048ed0efe7c531ac10c81cc5f6ac',
-    }
+    version('3.7.3',      '12d574eacadf8c9a70f1bb4cd1a69df6')
+    version('3.7.2',      'f6a716f171c9fdbf3cb12f71fa6e2737')
+    version('3.6.3-beta', 'ef0510bf2893042daedaca434e5ec6ce')
+    version('3.5.2-beta', 'd072d9d681eeb9ada15ce91bea784274')
+    version('3.5.0-beta', '1ad18a319fc573e12e2b1fbb6f6b0a19')
+    version('3.4.1-beta', '00814cbee2cb76bf8302aff56bbb385b')
+    version('3.3.3-beta', '1db3241d3e1cab913dc310d736c34388')
+    version('3.3.2-beta', 'e598a085dab979498fcb6c110c4dd26c')
+    version('2.4.4',      '04fb048ed0efe7c531ac10c81cc5f6ac')
 
     depends_on("mpi")
     depends_on("zlib")
diff --git a/var/spack/packages/boost/package.py b/var/spack/packages/boost/package.py
index 71c3058d795d04f097c5dd5badc2cb7c8b218975..d3231c3baab5cb136263ba539ece885177c29063 100644
--- a/var/spack/packages/boost/package.py
+++ b/var/spack/packages/boost/package.py
@@ -14,32 +14,31 @@ class Boost(Package):
     list_url = "http://sourceforge.net/projects/boost/files/boost/"
     list_depth = 2
 
-    versions = {
-        '1.55.0' : 'd6eef4b4cacb2183f2bf265a5a03a354',
-        '1.54.0' : '15cb8c0803064faef0c4ddf5bc5ca279',
-        '1.53.0' : 'a00d22605d5dbcfb4c9936a9b35bc4c2',
-        '1.52.0' : '3a855e0f919107e0ca4de4d84ad3f750',
-        '1.51.0' : '4b6bd483b692fd138aef84ed2c8eb679',
-        '1.50.0' : '52dd00be775e689f55a987baebccc462',
-        '1.49.0' : '0d202cb811f934282dea64856a175698',
-        '1.48.0' : 'd1e9a7a7f532bb031a3c175d86688d95',
-        '1.47.0' : 'a2dc343f7bc7f83f8941e47ed4a18200',
-        '1.46.1' : '7375679575f4c8db605d426fc721d506',
-        '1.46.0' : '37b12f1702319b73876b0097982087e0',
-        '1.45.0' : 'd405c606354789d0426bc07bea617e58',
-        '1.44.0' : 'f02578f5218f217a9f20e9c30e119c6a',
-        '1.43.0' : 'dd49767bfb726b0c774f7db0cef91ed1',
-        '1.42.0' : '7bf3b4eb841b62ffb0ade2b82218ebe6',
-        '1.41.0' : '8bb65e133907db727a2a825c5400d0a6',
-        '1.40.0' : 'ec3875caeac8c52c7c129802a8483bd7',
-        '1.39.0' : 'a17281fd88c48e0d866e1a12deecbcc0',
-        '1.38.0' : '5eca2116d39d61382b8f8235915cb267',
-        '1.37.0' : '8d9f990bfb7e83769fa5f1d6f065bc92',
-        '1.36.0' : '328bfec66c312150e4c2a78dcecb504b',
-        '1.35.0' : 'dce952a7214e72d6597516bcac84048b',
-        '1.34.1' : '2d938467e8a448a2c9763e0a9f8ca7e5',
-        '1.34.0' : 'ed5b9291ffad776f8757a916e1726ad0'
-    }
+    version('1.55.0', 'd6eef4b4cacb2183f2bf265a5a03a354')
+    version('1.54.0', '15cb8c0803064faef0c4ddf5bc5ca279')
+    version('1.53.0', 'a00d22605d5dbcfb4c9936a9b35bc4c2')
+    version('1.52.0', '3a855e0f919107e0ca4de4d84ad3f750')
+    version('1.51.0', '4b6bd483b692fd138aef84ed2c8eb679')
+    version('1.50.0', '52dd00be775e689f55a987baebccc462')
+    version('1.49.0', '0d202cb811f934282dea64856a175698')
+    version('1.48.0', 'd1e9a7a7f532bb031a3c175d86688d95')
+    version('1.47.0', 'a2dc343f7bc7f83f8941e47ed4a18200')
+    version('1.46.1', '7375679575f4c8db605d426fc721d506')
+    version('1.46.0', '37b12f1702319b73876b0097982087e0')
+    version('1.45.0', 'd405c606354789d0426bc07bea617e58')
+    version('1.44.0', 'f02578f5218f217a9f20e9c30e119c6a')
+    version('1.43.0', 'dd49767bfb726b0c774f7db0cef91ed1')
+    version('1.42.0', '7bf3b4eb841b62ffb0ade2b82218ebe6')
+    version('1.41.0', '8bb65e133907db727a2a825c5400d0a6')
+    version('1.40.0', 'ec3875caeac8c52c7c129802a8483bd7')
+    version('1.39.0', 'a17281fd88c48e0d866e1a12deecbcc0')
+    version('1.38.0', '5eca2116d39d61382b8f8235915cb267')
+    version('1.37.0', '8d9f990bfb7e83769fa5f1d6f065bc92')
+    version('1.36.0', '328bfec66c312150e4c2a78dcecb504b')
+    version('1.35.0', 'dce952a7214e72d6597516bcac84048b')
+    version('1.34.1', '2d938467e8a448a2c9763e0a9f8ca7e5')
+    version('1.34.0', 'ed5b9291ffad776f8757a916e1726ad0')
+
 
     def url_for_version(self, version):
         """Handle Boost's weird URLs, which write the version two different ways."""
diff --git a/var/spack/packages/cmake/package.py b/var/spack/packages/cmake/package.py
index 70406610b6e49aef93b80632d361ea92881e88da..ca6553df84dabd64793042055f8c0f3c31a62e5a 100644
--- a/var/spack/packages/cmake/package.py
+++ b/var/spack/packages/cmake/package.py
@@ -27,7 +27,8 @@
 class Cmake(Package):
     homepage  = 'https://www.cmake.org'
     url       = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz'
-    versions  = { '2.8.10.2' : '097278785da7182ec0aea8769d06860c' }
+
+    version('2.8.10.2', '097278785da7182ec0aea8769d06860c')
 
     def install(self, spec, prefix):
         configure('--prefix='   + prefix,
diff --git a/var/spack/packages/dyninst/package.py b/var/spack/packages/dyninst/package.py
index 3f8696b6d8ab2916a46d67ba8228a24d9bb76970..069237f7ffc663363176d70adebdb53fb5c90bbb 100644
--- a/var/spack/packages/dyninst/package.py
+++ b/var/spack/packages/dyninst/package.py
@@ -29,8 +29,8 @@ class Dyninst(Package):
     url      = "http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1.2/DyninstAPI-8.1.2.tgz"
     list_url = "http://www.dyninst.org/downloads/dyninst-8.x"
 
-    versions = {'8.1.2' : 'bf03b33375afa66fe0efa46ce3f4b17a',
-                '8.1.1' : '1f8743e3a5662b25ce64a7edf647e77d' }
+    version('8.1.2', 'bf03b33375afa66fe0efa46ce3f4b17a')
+    version('8.1.1', '1f8743e3a5662b25ce64a7edf647e77d')
 
     depends_on("libelf")
     depends_on("libdwarf")
diff --git a/var/spack/packages/graphlib/package.py b/var/spack/packages/graphlib/package.py
index c959135147cf76720d54fc14dee413508771e67f..ddac0b2b66ac310959cad56df749e9a1cbae2ddb 100644
--- a/var/spack/packages/graphlib/package.py
+++ b/var/spack/packages/graphlib/package.py
@@ -5,7 +5,7 @@ class Graphlib(Package):
     homepage = "http://https://github.com/lee218llnl/graphlib"
     url      = "https://github.com/lee218llnl/graphlib/archive/v2.0.0.tar.gz"
 
-    versions = { '2.0.0' : '43c6df84f1d38ba5a5dce0ae19371a70', }
+    version('2.0.0', '43c6df84f1d38ba5a5dce0ae19371a70')
 
     def install(self, spec, prefix):
         cmake(".", *std_cmake_args)
diff --git a/var/spack/packages/hdf5/package.py b/var/spack/packages/hdf5/package.py
index 7705676dba2b639a883efd5d6fab4828d5fec1c7..615c2a7fe4b8e1b3f3e3dcd79c29ba7c811656b0 100644
--- a/var/spack/packages/hdf5/package.py
+++ b/var/spack/packages/hdf5/package.py
@@ -11,10 +11,10 @@ class Hdf5(Package):
     list_url = "http://www.hdfgroup.org/ftp/HDF5/releases"
     list_depth = 3
 
-    versions = { '1.8.13' : 'c03426e9e77d7766944654280b467289', }
+    version('1.8.13', 'c03426e9e77d7766944654280b467289')
 
     depends_on("mpi")
-    depends_on("zlib") 
+    depends_on("zlib")
 
     # TODO: currently hard-coded to use OpenMPI
     def install(self, spec, prefix):
diff --git a/var/spack/packages/launchmon/package.py b/var/spack/packages/launchmon/package.py
index 7f12f41308847943276af0e037498db623900b67..b6773a85bc5a35860058fab5b7227f249921bc0c 100644
--- a/var/spack/packages/launchmon/package.py
+++ b/var/spack/packages/launchmon/package.py
@@ -28,7 +28,7 @@ class Launchmon(Package):
     homepage = "http://sourceforge.net/projects/launchmon"
     url      = "http://downloads.sourceforge.net/project/launchmon/launchmon/1.0.1%20release/launchmon-1.0.1.tar.gz"
 
-    versions = { '1.0.1' : '2f12465803409fd07f91174a4389eb2b' }
+    version('1.0.1', '2f12465803409fd07f91174a4389eb2b')
 
     def install(self, spec, prefix):
         configure(
diff --git a/var/spack/packages/libdwarf/package.py b/var/spack/packages/libdwarf/package.py
index abd6d1f4a1dc8ca73b538a1b8c2bd5c17b4f8dc2..c4d71ebc01077769135346fc579252aeb31475e0 100644
--- a/var/spack/packages/libdwarf/package.py
+++ b/var/spack/packages/libdwarf/package.py
@@ -44,9 +44,9 @@ class Libdwarf(Package):
     url      = "http://www.prevanders.net/libdwarf-20130729.tar.gz"
     list_url = homepage
 
-    versions = { '20130729' : '4cc5e48693f7b93b7aa0261e63c0e21d',
-                 '20130207' : '64b42692e947d5180e162e46c689dfbf',
-                 '20130126' : 'ded74a5e90edb5a12aac3c29d260c5db' }
+    version('20130729', '4cc5e48693f7b93b7aa0261e63c0e21d')
+    version('20130207', '64b42692e947d5180e162e46c689dfbf')
+    version('20130126', 'ded74a5e90edb5a12aac3c29d260c5db')
 
     depends_on("libelf")
 
diff --git a/var/spack/packages/libelf/package.py b/var/spack/packages/libelf/package.py
index f663ba750d6e0eeee60f828dda8203d4f2352471..bf2fefabd50637df075508cbc8087cd396ff7892 100644
--- a/var/spack/packages/libelf/package.py
+++ b/var/spack/packages/libelf/package.py
@@ -33,8 +33,8 @@ class Libelf(Package):
     homepage = "http://www.mr511.de/software/english.html"
     url      = "http://www.mr511.de/software/libelf-0.8.13.tar.gz"
 
-    versions = { '0.8.13' : '4136d7b4c04df68b686570afa26988ac',
-                 '0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7', }
+    version('0.8.13', '4136d7b4c04df68b686570afa26988ac')
+    version('0.8.12', 'e21f8273d9f5f6d43a59878dc274fec7')
 
     def install(self, spec, prefix):
         configure("--prefix=" + prefix,
diff --git a/var/spack/packages/libevent/package.py b/var/spack/packages/libevent/package.py
index 9b45b532d7f54d3ddeeff433a30f90586d67fbdf..11b1083d6720cefd0460996391c2f3eff31fc90d 100644
--- a/var/spack/packages/libevent/package.py
+++ b/var/spack/packages/libevent/package.py
@@ -11,18 +11,17 @@ class Libevent(Package):
     url      = "https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz"
     list_url = "http://libevent.org/old-releases.html"
 
-    versions =   {
-      '2.0.21' : 'b2405cc9ebf264aa47ff615d9de527a2',
-      '2.0.20' : '94270cdee32c0cd0aa9f4ee6ede27e8e',
-      '2.0.19' : '91111579769f46055b0a438f5cc59572',
-      '2.0.18' : 'aa1ce9bc0dee7b8084f6855765f2c86a',
-      '2.0.17' : 'dad64aaaaff16b5fbec25160c06fee9a',
-      '2.0.16' : '899efcffccdb3d5111419df76e7dc8df',
-      '2.0.15' : '2643abe7ba242df15c08b2cc14ec8759',
-      '2.0.14' : 'cac0f379da35d3b98f83ac16fcfe1df4',
-      '2.0.13' : 'af786b4b3f790c9d3279792edf7867fc',
-      '2.0.12' : '42986228baf95e325778ed328a93e070',
-    }
+    version('2.0.21', 'b2405cc9ebf264aa47ff615d9de527a2')
+    version('2.0.20', '94270cdee32c0cd0aa9f4ee6ede27e8e')
+    version('2.0.19', '91111579769f46055b0a438f5cc59572')
+    version('2.0.18', 'aa1ce9bc0dee7b8084f6855765f2c86a')
+    version('2.0.17', 'dad64aaaaff16b5fbec25160c06fee9a')
+    version('2.0.16', '899efcffccdb3d5111419df76e7dc8df')
+    version('2.0.15', '2643abe7ba242df15c08b2cc14ec8759')
+    version('2.0.14', 'cac0f379da35d3b98f83ac16fcfe1df4')
+    version('2.0.13', 'af786b4b3f790c9d3279792edf7867fc')
+    version('2.0.12', '42986228baf95e325778ed328a93e070')
+
 
     def install(self, spec, prefix):
         configure("--prefix=%s" % prefix)
diff --git a/var/spack/packages/libunwind/package.py b/var/spack/packages/libunwind/package.py
index c93b5b2c987083e42266bcde192f2bfd2fdeb8ca..aeadc85eb36d7241a3c875f39b29dae1462d6ff1 100644
--- a/var/spack/packages/libunwind/package.py
+++ b/var/spack/packages/libunwind/package.py
@@ -28,7 +28,7 @@ class Libunwind(Package):
     homepage = "http://www.nongnu.org/libunwind/"
     url      = "http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz"
 
-    versions = { '1.1' : 'fb4ea2f6fbbe45bf032cd36e586883ce' }
+    version('1.1', 'fb4ea2f6fbbe45bf032cd36e586883ce')
 
     def install(self, spec, prefix):
         configure("--prefix=" + prefix)
diff --git a/var/spack/packages/mpich/package.py b/var/spack/packages/mpich/package.py
index 703614a587815f13eecb8f047a4794080ada2de1..19a1efe9c36a41c098bd31cfbde021d345929817 100644
--- a/var/spack/packages/mpich/package.py
+++ b/var/spack/packages/mpich/package.py
@@ -32,7 +32,7 @@ class Mpich(Package):
     list_url   = "http://www.mpich.org/static/downloads/"
     list_depth = 2
 
-    versions = { '3.0.4' : '9c5d5d4fe1e17dd12153f40bc5b6dbc0' }
+    version('3.0.4', '9c5d5d4fe1e17dd12153f40bc5b6dbc0')
 
     provides('mpi@:3', when='@3:')
     provides('mpi@:1', when='@1:')
diff --git a/var/spack/packages/mrnet/package.py b/var/spack/packages/mrnet/package.py
index 89eeaf1e7145852bd6105ac7d6d0505ca7ef81e5..6e9766f275cdd1345b185751be45b1b94675df1c 100644
--- a/var/spack/packages/mrnet/package.py
+++ b/var/spack/packages/mrnet/package.py
@@ -5,8 +5,9 @@ class Mrnet(Package):
     homepage = "http://paradyn.org/mrnet"
     url      = "ftp://ftp.cs.wisc.edu/paradyn/mrnet/mrnet_4.0.0.tar.gz"
 
-    versions = { '4.0.0' : 'd00301c078cba57ef68613be32ceea2f', }
-    versions = { '4.1.0' : '5a248298b395b329e2371bf25366115c', }
+    version('4.0.0', 'd00301c078cba57ef68613be32ceea2f')
+    version('4.1.0', '5a248298b395b329e2371bf25366115c')
+
     parallel = False
 
     depends_on("boost")
diff --git a/var/spack/packages/mvapich2/package.py b/var/spack/packages/mvapich2/package.py
index f372679f49bd067274208e4ba09dfc96f838adc1..5b62835bf9a67080dd4685aaf90cbce66127538e 100644
--- a/var/spack/packages/mvapich2/package.py
+++ b/var/spack/packages/mvapich2/package.py
@@ -2,11 +2,12 @@
 
 class Mvapich2(Package):
     """mvapich2 is an MPI implmenetation for infiniband networks."""
-
     homepage = "http://mvapich.cse.ohio-state.edu/"
-    url      = "http://mvapich.cse.ohio-state.edu/download/mvapich2/mv2/mvapich2-1.9.tgz"
 
-    versions = { '1.9' : '5dc58ed08fd3142c260b70fe297e127c', }
+    version('1.9', '5dc58ed08fd3142c260b70fe297e127c',
+            url="http://mvapich.cse.ohio-state.edu/download/mvapich2/mv2/mvapich2-1.9.tgz")
+    version('2.0', '9fbb68a4111a8b6338e476dc657388b4',
+            url='http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.0.tar.gz')
 
     provides('mpi@:1', when='@1.9:')
 
diff --git a/var/spack/packages/ncurses/package.py b/var/spack/packages/ncurses/package.py
index 221860374b2638f08f73b0b61c52feb7f32c823c..4885caa628a149dc2e2c3e510b64c0df1df8523e 100644
--- a/var/spack/packages/ncurses/package.py
+++ b/var/spack/packages/ncurses/package.py
@@ -8,14 +8,12 @@ class Ncurses(Package):
     """
 
     homepage = "http://invisible-island.net/ncurses/ncurses.html"
-    url      = "http://invisible-island.net/datafiles/release/ncurses.tar.gz"
 
-    versions = { 'stable' : '8cb9c412e5f2d96bc6f459aa8c6282a1' }
+    version('5.9', '8cb9c412e5f2d96bc6f459aa8c6282a1',
+            url='http://invisible-island.net/datafiles/release/ncurses.tar.gz')
 
     def install(self, spec, prefix):
         configure("--prefix=%s" % prefix)
         make()
         make("install")
 
-    def url_for_version(self, version):
-        return "http://invisible-island.net/datafiles/release/ncurses.tar.gz"
diff --git a/var/spack/packages/openmpi/package.py b/var/spack/packages/openmpi/package.py
index 5ac231a33f2a5034638bd14206c479582ec355a2..0ce09bdd8db910818e7c69fa294699b1000d037c 100644
--- a/var/spack/packages/openmpi/package.py
+++ b/var/spack/packages/openmpi/package.py
@@ -12,7 +12,7 @@ class Openmpi(Package):
     homepage = "http://www.open-mpi.org"
     url      = "http://www.open-mpi.org/software/ompi/v1.6/downloads/openmpi-1.6.5.tar.bz2"
 
-    versions = { '1.6.5' : '03aed2a4aa4d0b27196962a2a65fc475', }
+    version('1.6.5', '03aed2a4aa4d0b27196962a2a65fc475')
 
     provides('mpi@:2')
 
diff --git a/var/spack/packages/parmetis/package.py b/var/spack/packages/parmetis/package.py
index 10a48503b2f47225cec8cfd481ef4ee536f5b845..d8cd33730477bfe4623710a4d1d8ad656ad72ce7 100644
--- a/var/spack/packages/parmetis/package.py
+++ b/var/spack/packages/parmetis/package.py
@@ -8,7 +8,7 @@ class Parmetis(Package):
     homepage = "http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview"
     url      = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/parmetis-4.0.3.tar.gz"
 
-    versions = { '4.0.3' : 'f69c479586bf6bb7aff6a9bc0c739628', }
+    version('4.0.3', 'f69c479586bf6bb7aff6a9bc0c739628')
 
     depends_on('mpi')
 
diff --git a/var/spack/packages/pmgr_collective/package.py b/var/spack/packages/pmgr_collective/package.py
index 0874e2d17b74c708e84aa89775690461a36eb90b..5d9b02acc3102e8180e11ad3044d662f39014aa6 100644
--- a/var/spack/packages/pmgr_collective/package.py
+++ b/var/spack/packages/pmgr_collective/package.py
@@ -30,7 +30,7 @@ class PmgrCollective(Package):
     homepage = "http://www.sourceforge.net/projects/pmgrcollective"
     url      = "http://downloads.sourceforge.net/project/pmgrcollective/pmgrcollective/PMGR_COLLECTIVE-1.0/pmgr_collective-1.0.tgz"
 
-    versions = { '1.0' : '0384d008774274cc3fc7b4d810dfd07e' }
+    version('1.0', '0384d008774274cc3fc7b4d810dfd07e')
 
     def install(self, spec, prefix):
         make('PREFIX="' + prefix + '"')
diff --git a/var/spack/packages/scr/package.py b/var/spack/packages/scr/package.py
index cb908e830e0db7b360221874c5fa721b8a0d7e27..d480dba62fdb761504299f4b7019bac753af4036 100644
--- a/var/spack/packages/scr/package.py
+++ b/var/spack/packages/scr/package.py
@@ -30,7 +30,7 @@ class Scr(Package):
 
     depends_on("mpi")
 
-    versions = { '1.1-7' : 'a5930e9ab27d1b7049447c2fd7734ebd' }
+    version('1.1-7', 'a5930e9ab27d1b7049447c2fd7734ebd')
 
     def install(self, spec, prefix):
         configure("--prefix=" + prefix,
diff --git a/var/spack/packages/spindle/package.py b/var/spack/packages/spindle/package.py
index 0d106221d85dd241afaffe0679eb7e15e9124d81..bb0b74ab6fe3c3ef70d92f4af59fbc28e3be5598 100644
--- a/var/spack/packages/spindle/package.py
+++ b/var/spack/packages/spindle/package.py
@@ -29,7 +29,7 @@ class Spindle(Package):
     url      = "https://github.com/hpc/Spindle/archive/v0.8.1.tar.gz"
     list_url = "https://github.com/hpc/Spindle/releases"
 
-    versions = {'0.8.1' : 'f11793a6b9d8df2cd231fccb2857d912' }
+    version('0.8.1', 'f11793a6b9d8df2cd231fccb2857d912')
 
     depends_on("launchmon")
 
diff --git a/var/spack/packages/stat/package.py b/var/spack/packages/stat/package.py
index 9f156d53e722f888460f4508d8e38f6b661b3630..583ae48e82eed0f66f9e6d0f03a669b345bdbb59 100644
--- a/var/spack/packages/stat/package.py
+++ b/var/spack/packages/stat/package.py
@@ -5,8 +5,8 @@ class Stat(Package):
     homepage = "http://paradyn.org/STAT/STAT.html"
     url      = "https://github.com/lee218llnl/stat/archive/v2.0.0.tar.gz"
 
-    versions = { '2.0.0' : 'c7494210b0ba26b577171b92838e1a9b', }
-    versions = { '2.1.0' : 'ece26beaf057aa9134d62adcdda1ba91', }
+    version('2.0.0', 'c7494210b0ba26b577171b92838e1a9b')
+    version('2.1.0', 'ece26beaf057aa9134d62adcdda1ba91')
 
     depends_on('libdwarf')
     depends_on('dyninst')
diff --git a/var/spack/packages/tau/package.py b/var/spack/packages/tau/package.py
index 62c467b572da4a6a325f81158808763ab37da14f..8d9dbe1759b4a7b5ec34cf8b77cf0ace82804ddc 100644
--- a/var/spack/packages/tau/package.py
+++ b/var/spack/packages/tau/package.py
@@ -10,7 +10,8 @@ class Tau(Package):
     homepage = "http://www.cs.uoregon.edu/research/tau"
     url      = "http://www.cs.uoregon.edu/research/paracomp/tau/tauprofile/dist/tau-2.23.1.tar.gz"
 
-    versions = { '2.23.1' : '6593b47ae1e7a838e632652f0426fe72', }
+    version('2.23.1', '6593b47ae1e7a838e632652f0426fe72')
+
 
     def install(self, spec, prefix):
         # TAU isn't happy with directories that have '@' in the path.  Sigh.
diff --git a/var/spack/packages/tmux/package.py b/var/spack/packages/tmux/package.py
index d4e3d9f8296e28be8bc2ec91c529d5e6edd0a456..23d36db427514f349e7c52083794ef4ac86a6a75 100644
--- a/var/spack/packages/tmux/package.py
+++ b/var/spack/packages/tmux/package.py
@@ -10,7 +10,7 @@ class Tmux(Package):
     homepage = "http://tmux.sourceforge.net"
     url      = "http://downloads.sourceforge.net/project/tmux/tmux/tmux-1.9/tmux-1.9a.tar.gz"
 
-    versions = { '1.9a' : 'b07601711f96f1d260b390513b509a2d', }
+    version('1.9a', 'b07601711f96f1d260b390513b509a2d')
 
     depends_on('libevent')
     depends_on('ncurses')
diff --git a/var/spack/packages/vim/package.py b/var/spack/packages/vim/package.py
index 9398134b50947f67caceff2a344530458a19a8b1..5c6d7cb56bc9840f542b9385ae91e9a7b8ddf642 100644
--- a/var/spack/packages/vim/package.py
+++ b/var/spack/packages/vim/package.py
@@ -13,19 +13,17 @@ class Vim(Package):
     url      = "ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2"
     list_url = "http://ftp.vim.org/pub/vim/unix/"
 
-    versions = {
-        '7.4' : '607e135c559be642f210094ad023dc65',
-        '7.3' : '5b9510a17074e2b37d8bb38ae09edbf2',
-        '7.2' : 'f0901284b338e448bfd79ccca0041254',
-        '7.1' : '44c6b4914f38d6f9aa959640b89da329',
-        '7.0' : '4ca69757678272f718b1041c810d82d8',
-        '6.4' : '774c14d93ce58674b3b2c880edd12d77',
-        '6.3' : '821fda8f14d674346b87e3ef9cb96389',
-        '6.2' : 'c49d360bbd069d00e2a57804f2a123d9',
-        '6.1.405' : 'd220ff58f2c72ed606e6d0297c2f2a7c',
-        '6.1' : '7fd0f915adc7c0dab89772884268b030',
-        '6.0' : '9d9ca84d489af6b3f54639dd97af3774',
-    }
+    version('7.4',     '607e135c559be642f210094ad023dc65')
+    version('7.3',     '5b9510a17074e2b37d8bb38ae09edbf2')
+    version('7.2',     'f0901284b338e448bfd79ccca0041254')
+    version('7.1',     '44c6b4914f38d6f9aa959640b89da329')
+    version('7.0',     '4ca69757678272f718b1041c810d82d8')
+    version('6.4',     '774c14d93ce58674b3b2c880edd12d77')
+    version('6.3',     '821fda8f14d674346b87e3ef9cb96389')
+    version('6.2',     'c49d360bbd069d00e2a57804f2a123d9')
+    version('6.1.405', 'd220ff58f2c72ed606e6d0297c2f2a7c')
+    version('6.1',     '7fd0f915adc7c0dab89772884268b030')
+    version('6.0',     '9d9ca84d489af6b3f54639dd97af3774')
 
     def install(self, spec, prefix):
         configure("--prefix=%s" % prefix)
diff --git a/var/spack/packages/zlib/package.py b/var/spack/packages/zlib/package.py
index 608b27ddd39682cee971f6e4a9ae08fef230755b..2770f781ac3c80046e2c41fce90daea15e184bb1 100644
--- a/var/spack/packages/zlib/package.py
+++ b/var/spack/packages/zlib/package.py
@@ -9,7 +9,7 @@ class Zlib(Package):
     homepage = "http://zlib.net"
     url      = "http://zlib.net/zlib-1.2.8.tar.gz"
 
-    versions = { '1.2.8' : '44d667c142d7cda120332623eab69f40', }
+    version('1.2.8', '44d667c142d7cda120332623eab69f40')
 
     def install(self, spec, prefix):
         configure("--prefix=%s" % prefix)