diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index 74ee7b0adde923ed03cf5f19455f13f612baf5fa..51b26773e24be75a3b869d46c501a35e9ebeb597 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -45,11 +45,8 @@ class OpenMpi(Package):
   * ``resource``
 
 """
-__all__ = ['depends_on', 'extends', 'provides', 'patch', 'version',
-           'variant', 'resource']
 
 import re
-import inspect
 import os.path
 import functools
 
@@ -67,6 +64,9 @@ class OpenMpi(Package):
 from spack.resource import Resource
 from spack.fetch_strategy import from_kwargs
 
+__all__ = ['depends_on', 'extends', 'provides', 'patch', 'version', 'variant',
+           'resource']
+
 #
 # This is a list of all directives, built up as they are defined in
 # this file.
@@ -122,15 +122,14 @@ class Foo(Package):
 
     def __init__(self, dicts=None):
         if isinstance(dicts, basestring):
-            dicts = (dicts,)
+            dicts = (dicts, )
         elif type(dicts) not in (list, tuple):
             raise TypeError(
-                "dicts arg must be list, tuple, or string. Found %s"
-                % type(dicts))
+                "dicts arg must be list, tuple, or string. Found %s" %
+                type(dicts))
 
         self.dicts = dicts
 
-
     def ensure_dicts(self, pkg):
         """Ensure that a package has the dicts required by this directive."""
         for d in self.dicts:
@@ -142,7 +141,6 @@ def ensure_dicts(self, pkg):
                 raise spack.error.SpackError(
                     "Package %s has non-dict %s attribute!" % (pkg, d))
 
-
     def __call__(self, directive_function):
         directives[directive_function.__name__] = self
 
@@ -259,11 +257,12 @@ def variant(pkg, name, default=False, description=""):
     """Define a variant for the package. Packager can specify a default
     value (on or off) as well as a text description."""
 
-    default     = bool(default)
+    default = bool(default)
     description = str(description).strip()
 
     if not re.match(spack.spec.identifier_re, name):
-        raise DirectiveError("Invalid variant name in %s: '%s'" % (pkg.name, name))
+        raise DirectiveError("Invalid variant name in %s: '%s'" %
+                             (pkg.name, name))
 
     pkg.variants[name] = Variant(default, description)
 
@@ -271,31 +270,37 @@ def variant(pkg, name, default=False, description=""):
 @directive('resources')
 def resource(pkg, **kwargs):
     """
-    Define an external resource to be fetched and staged when building the package. Based on the keywords present in the
-    dictionary the appropriate FetchStrategy will be used for the resource. Resources are fetched and staged in their
-    own folder inside spack stage area, and then linked into the stage area of the package that needs them.
+    Define an external resource to be fetched and staged when building the
+    package. Based on the keywords present in the dictionary the appropriate
+    FetchStrategy will be used for the resource. Resources are fetched and
+    staged in their own folder inside spack stage area, and then linked into
+    the stage area of the package that needs them.
 
     List of recognized keywords:
 
-    * 'when' : (optional) represents the condition upon which the resource is needed
-    * 'destination' : (optional) path where to link the resource. This path must be relative to the main package stage
-    area.
-    * 'placement' : (optional) gives the possibility to fine tune how the resource is linked into the main package stage
-    area.
+    * 'when' : (optional) represents the condition upon which the resource is
+    needed
+    * 'destination' : (optional) path where to link the resource. This path
+    must be relative to the main package stage area.
+    * 'placement' : (optional) gives the possibility to fine tune how the
+    resource is linked into the main package stage area.
     """
     when = kwargs.get('when', pkg.name)
     destination = kwargs.get('destination', "")
     placement = kwargs.get('placement', None)
     # Check if the path is relative
     if os.path.isabs(destination):
-        message = "The destination keyword of a resource directive can't be an absolute path.\n"
+        message = "The destination keyword of a resource directive can't be"
+        " an absolute path.\n"
         message += "\tdestination : '{dest}\n'".format(dest=destination)
         raise RuntimeError(message)
     # Check if the path falls within the main package stage area
-    test_path = 'stage_folder_root/'
-    normalized_destination = os.path.normpath(join_path(test_path, destination))  # Normalized absolute path
+    test_path = 'stage_folder_root'
+    normalized_destination = os.path.normpath(join_path(test_path, destination)
+                                              )  # Normalized absolute path
     if test_path not in normalized_destination:
-        message = "The destination folder of a resource must fall within the main package stage directory.\n"
+        message = "The destination folder of a resource must fall within the"
+        " main package stage directory.\n"
         message += "\tdestination : '{dest}'\n".format(dest=destination)
         raise RuntimeError(message)
     when_spec = parse_anonymous_spec(when, pkg.name)
@@ -307,6 +312,7 @@ def resource(pkg, **kwargs):
 
 class DirectiveError(spack.error.SpackError):
     """This is raised when something is wrong with a package directive."""
+
     def __init__(self, directive, message):
         super(DirectiveError, self).__init__(message)
         self.directive = directive
@@ -314,6 +320,7 @@ def __init__(self, directive, message):
 
 class CircularReferenceError(DirectiveError):
     """This is raised when something depends on itself."""
+
     def __init__(self, directive, package):
         super(CircularReferenceError, self).__init__(
             directive,
diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 11998ad8d24f6f76e30ca520a68baec6483a51d3..af642dcc9bd4ba0cd2747743d67da5cbfc0ec954 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -39,7 +39,8 @@ class NameValueModifier(object):
     def __init__(self, name, value, **kwargs):
         self.name = name
         self.value = value
-        self.args = {'name': name, 'value': value}
+        self.separator = kwargs.get('separator', ':')
+        self.args = {'name': name, 'value': value, 'delim': self.separator}
         self.args.update(kwargs)
 
 
@@ -56,34 +57,36 @@ def execute(self):
 
 class SetPath(NameValueModifier):
     def execute(self):
-        string_path = concatenate_paths(self.value)
+        string_path = concatenate_paths(self.value, separator=self.separator)
         os.environ[self.name] = string_path
 
 
 class AppendPath(NameValueModifier):
     def execute(self):
         environment_value = os.environ.get(self.name, '')
-        directories = environment_value.split(':') if environment_value else []
+        directories = environment_value.split(
+            self.separator) if environment_value else []
         directories.append(os.path.normpath(self.value))
-        os.environ[self.name] = ':'.join(directories)
+        os.environ[self.name] = self.separator.join(directories)
 
 
 class PrependPath(NameValueModifier):
     def execute(self):
         environment_value = os.environ.get(self.name, '')
-        directories = environment_value.split(':') if environment_value else []
+        directories = environment_value.split(
+            self.separator) if environment_value else []
         directories = [os.path.normpath(self.value)] + directories
-        os.environ[self.name] = ':'.join(directories)
+        os.environ[self.name] = self.separator.join(directories)
 
 
 class RemovePath(NameValueModifier):
     def execute(self):
         environment_value = os.environ.get(self.name, '')
-        directories = environment_value.split(':') if environment_value else []
-        directories = [os.path.normpath(x)
-                       for x in directories
+        directories = environment_value.split(
+            self.separator) if environment_value else []
+        directories = [os.path.normpath(x) for x in directories
                        if x != os.path.normpath(self.value)]
-        os.environ[self.name] = ':'.join(directories)
+        os.environ[self.name] = self.separator.join(directories)
 
 
 class EnvironmentModifications(object):
@@ -238,17 +241,19 @@ def apply_modifications(self):
                 x.execute()
 
 
-def concatenate_paths(paths):
+def concatenate_paths(paths, separator=':'):
     """
-    Concatenates an iterable of paths into a  string of column separated paths
+    Concatenates an iterable of paths into a string of paths separated by
+    separator, defaulting to colon
 
     Args:
         paths: iterable of paths
+        separator: the separator to use, default ':'
 
     Returns:
         string
     """
-    return ':'.join(str(item) for item in paths)
+    return separator.join(str(item) for item in paths)
 
 
 def set_or_unset_not_first(variable, changes, errstream):
@@ -256,16 +261,13 @@ def set_or_unset_not_first(variable, changes, errstream):
     Check if we are going to set or unset something after other modifications
     have already been requested
     """
-    indexes = [ii
-               for ii, item in enumerate(changes)
+    indexes = [ii for ii, item in enumerate(changes)
                if ii != 0 and type(item) in [SetEnv, UnsetEnv]]
     if indexes:
         good = '\t    \t{context} at {filename}:{lineno}'
         nogood = '\t--->\t{context} at {filename}:{lineno}'
         message = 'Suspicious requests to set or unset the variable \'{var}\' found'  # NOQA: ignore=E501
-        errstream(
-            message.format(
-                var=variable))
+        errstream(message.format(var=variable))
         for ii, item in enumerate(changes):
             print_format = nogood if ii in indexes else good
             errstream(print_format.format(**item.args))
diff --git a/lib/spack/spack/modules.py b/lib/spack/spack/modules.py
index a35e21c3dbc7f075f1c8db5c4a9ac1a7f4f3db54..d2b819e80ac0d7ce704588c0805c64076e2613c6 100644
--- a/lib/spack/spack/modules.py
+++ b/lib/spack/spack/modules.py
@@ -485,9 +485,9 @@ class TclModule(EnvModule):
     path = join_path(spack.share_path, "modules")
 
     environment_modifications_formats = {
-        PrependPath: 'prepend-path {name} \"{value}\"\n',
-        AppendPath: 'append-path {name} \"{value}\"\n',
-        RemovePath: 'remove-path {name} \"{value}\"\n',
+        PrependPath: 'prepend-path --delim "{delim}" {name} \"{value}\"\n',
+        AppendPath: 'append-path   --delim "{delim}" {name} \"{value}\"\n',
+        RemovePath: 'remove-path   --delim "{delim}" {name} \"{value}\"\n',
         SetEnv: 'setenv {name} \"{value}\"\n',
         UnsetEnv: 'unsetenv {name}\n'
     }
diff --git a/var/spack/repos/builtin/packages/lua-luaposix/package.py b/var/spack/repos/builtin/packages/lua-luaposix/package.py
new file mode 100644
index 0000000000000000000000000000000000000000..9e96548f0800ac09f339154076d491b413892b89
--- /dev/null
+++ b/var/spack/repos/builtin/packages/lua-luaposix/package.py
@@ -0,0 +1,16 @@
+from spack import *
+import glob
+
+
+class LuaLuaposix(Package):
+    """Lua posix bindings, including ncurses"""
+    homepage = "https://github.com/luaposix/luaposix/"
+    url      = "https://github.com/luaposix/luaposix/archive/release-v33.4.0.tar.gz"
+
+    version('33.4.0', 'b36ff049095f28752caeb0b46144516c')
+
+    extends("lua")
+
+    def install(self, spec, prefix):
+        rockspec = glob.glob('luaposix-*.rockspec')
+        luarocks('--tree=' + prefix, 'install', rockspec[0])
diff --git a/var/spack/repos/builtin/packages/lua/package.py b/var/spack/repos/builtin/packages/lua/package.py
index 9a73a2264540074868c2a4faf3efa216012c9d38..e6219675862049bcb102b237786b9417a1598ae7 100644
--- a/var/spack/repos/builtin/packages/lua/package.py
+++ b/var/spack/repos/builtin/packages/lua/package.py
@@ -25,10 +25,11 @@
 from spack import *
 import os
 
+
 class Lua(Package):
     """ The Lua programming language interpreter and library """
     homepage = "http://www.lua.org"
-    url      = "http://www.lua.org/ftp/lua-5.1.5.tar.gz"
+    url = "http://www.lua.org/ftp/lua-5.1.5.tar.gz"
 
     version('5.3.2', '33278c2ab5ee3c1a875be8d55c1ca2a1')
     version('5.3.1', '797adacada8d85761c079390ff1d9961')
@@ -42,17 +43,115 @@ class Lua(Package):
     version('5.1.4', 'd0870f2de55d59c1c8419f36e8fac150')
     version('5.1.3', 'a70a8dfaa150e047866dc01a46272599')
 
+    extendable = True
+
     depends_on('ncurses')
     depends_on('readline')
 
+    resource(
+        name="luarocks",
+        url="https://keplerproject.github.io/luarocks/releases/"
+        "luarocks-2.3.0.tar.gz",
+        md5="a38126684cf42b7d0e7a3c7cf485defb",
+        destination="luarocks",
+        placement='luarocks')
+
     def install(self, spec, prefix):
         if spec.satisfies("=darwin-i686") or spec.satisfies("=darwin-x86_64"):
             target = 'macosx'
         else:
             target = 'linux'
         make('INSTALL_TOP=%s' % prefix,
-             'MYLDFLAGS=-L%s -lncurses' % spec['ncurses'].prefix.lib,
+             'MYLDFLAGS=-L%s -L%s ' % (
+                 spec['readline'].prefix.lib,
+                 spec['ncurses'].prefix.lib),
+             'MYLIBS=-lncurses',
              target)
         make('INSTALL_TOP=%s' % prefix,
-             'MYLDFLAGS=-L%s -lncurses' % spec['ncurses'].prefix.lib,
+             'MYLDFLAGS=-L%s -L%s ' % (
+                 spec['readline'].prefix.lib,
+                 spec['ncurses'].prefix.lib),
+             'MYLIBS=-lncurses',
              'install')
+
+        with working_dir(os.path.join('luarocks', 'luarocks')):
+            configure('--prefix=' + prefix, '--with-lua=' + prefix)
+            make('build')
+            make('install')
+
+    def append_paths(self, paths, cpaths, path):
+        paths.append(os.path.join(path, '?.lua'))
+        paths.append(os.path.join(path, '?', 'init.lua'))
+        cpaths.append(os.path.join(path, '?.so'))
+
+    def setup_dependent_environment(self, spack_env, run_env, extension_spec):
+        lua_paths = []
+        for d in extension_spec.traverse():
+            if d.package.extends(self.spec):
+                lua_paths.append(os.path.join(d.prefix, self.lua_lib_dir))
+                lua_paths.append(os.path.join(d.prefix, self.lua_share_dir))
+
+        lua_patterns = []
+        lua_cpatterns = []
+        for p in lua_paths:
+            if os.path.isdir(p):
+                self.append_paths(lua_patterns, lua_cpatterns, p)
+
+        # Always add this package's paths
+        for p in (os.path.join(self.spec.prefix, self.lua_lib_dir),
+                  os.path.join(self.spec.prefix, self.lua_share_dir)):
+            self.append_paths(lua_patterns, lua_cpatterns, p)
+
+        spack_env.set('LUA_PATH', ';'.join(lua_patterns), separator=';')
+        spack_env.set('LUA_CPATH', ';'.join(lua_cpatterns), separator=';')
+
+        # For run time environment set only the path for extension_spec and
+        # prepend it to LUAPATH
+        if extension_spec.package.extends(self.spec):
+            run_env.prepend_path('LUA_PATH', ';'.join(lua_patterns),
+                                 separator=';')
+            run_env.prepend_path('LUA_CPATH', ';'.join(lua_cpatterns),
+                                 separator=';')
+
+    def setup_environment(self, spack_env, run_env):
+        run_env.prepend_path(
+            'LUA_PATH',
+            os.path.join(self.spec.prefix, self.lua_share_dir, '?.lua'),
+            separator=';')
+        run_env.prepend_path(
+            'LUA_PATH', os.path.join(self.spec.prefix, self.lua_share_dir, '?',
+                                     'init.lua'),
+            separator=';')
+        run_env.prepend_path(
+            'LUA_PATH',
+            os.path.join(self.spec.prefix, self.lua_lib_dir, '?.lua'),
+            separator=';')
+        run_env.prepend_path(
+            'LUA_PATH',
+            os.path.join(self.spec.prefix, self.lua_lib_dir, '?', 'init.lua'),
+            separator=';')
+        run_env.prepend_path(
+            'LUA_CPATH',
+            os.path.join(self.spec.prefix, self.lua_lib_dir, '?.so'),
+            separator=';')
+
+    @property
+    def lua_lib_dir(self):
+        return os.path.join('lib', 'lua', '%d.%d' % self.version[:2])
+
+    @property
+    def lua_share_dir(self):
+        return os.path.join('share', 'lua', '%d.%d' % self.version[:2])
+
+    def setup_dependent_package(self, module, ext_spec):
+        """
+        Called before lua modules's install() methods.
+
+        In most cases, extensions will only need to have two lines::
+
+        luarocks('--tree=' + prefix, 'install', rock_spec_path)
+        """
+        # Lua extension builds can have lua and luarocks executable functions
+        module.lua = Executable(join_path(self.spec.prefix.bin, 'lua'))
+        module.luarocks = Executable(join_path(self.spec.prefix.bin,
+                                               'luarocks'))