diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index bb03082..0589141 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -2,10 +2,11 @@ import os
 import sys
 from optparse import OptionParser, NO_DEFAULT
 import imp
+import pkgutil
 import warnings
 
 from django.core.management.base import BaseCommand, CommandError, handle_default_options
-from django.utils.importlib import import_module
+from django.utils.importlib import import_module, find_package_path
 
 # For backwards compatibility: get_version() used to be in this module.
 from django import get_version
@@ -21,11 +22,11 @@ def find_commands(management_dir):
 
     Returns an empty list if no commands are defined.
     """
-    command_dir = os.path.join(management_dir, 'commands')
     try:
-        return [f[:-3] for f in os.listdir(command_dir)
-                if not f.startswith('_') and f.endswith('.py')]
-    except OSError:
+        commands_dir = find_package_path('commands', [management_dir])[0]
+        return [name for loader,name,ispkg in pkgutil.iter_modules([commands_dir])
+                if not name.startswith('_') ]
+    except ImportError:
         return []
 
 def find_management_module(app_name):
@@ -37,26 +38,37 @@ def find_management_module(app_name):
     """
     parts = app_name.split('.')
     parts.append('management')
-    parts.reverse()
-    part = parts.pop()
-    path = None
-
-    # When using manage.py, the project module is added to the path,
-    # loaded, then removed from the path. This means that
-    # testproject.testapp.models can be loaded in future, even if
-    # testproject isn't in the path. When looking for the management
-    # module, we need look for the case where the project name is part
-    # of the app_name but the project directory itself isn't on the path.
-    try:
-        f, path, descr = imp.find_module(part,path)
-    except ImportError,e:
-        if os.path.basename(os.getcwd()) != part:
-            raise e
+
+    for i in range(len(parts), 0, -1):
+        try:
+            path = sys.modules['.'.join(parts[:i])].__path__
+        except KeyError:
+            continue
+
+        parts = parts[i:]
+        parts.reverse()
+        break
+    else:
+        parts.reverse()
+        part = parts.pop()
+        path = None
+
+        # When using manage.py, the project module is added to the path,
+        # loaded, then removed from the path. This means that
+        # testproject.testapp.models can be loaded in future, even if
+        # testproject isn't in the path. When looking for the management
+        # module, we need look for the case where the project name is part
+        # of the app_name but the project directory itself isn't on the path.
+        try:
+            path = find_package_path(part, path)
+        except ImportError,e:
+            if os.path.basename(os.getcwd()) != part:
+                raise e
 
     while parts:
         part = parts.pop()
-        f, path, descr = imp.find_module(part, path and [path] or None)
-    return path
+        path = find_package_path(part, path)
+    return path[0]
 
 def load_command_class(app_name, name):
     """
diff --git a/django/utils/importlib.py b/django/utils/importlib.py
index ef4d0e4..774e50d 100644
--- a/django/utils/importlib.py
+++ b/django/utils/importlib.py
@@ -1,5 +1,9 @@
 # Taken from Python 2.7 with permission from/by the original author.
+import os
 import sys
+import imp
+import pkgutil
+import warnings
 
 def _resolve_name(name, package, level):
     """Return the absolute name of the module to be imported."""
@@ -34,3 +38,86 @@ def import_module(name, package=None):
         name = _resolve_name(name[level:], package, level)
     __import__(name)
     return sys.modules[name]
+
+
+def find_package_path(name, path=None):
+    """Finds search path for package with given name.
+
+    The 'path' argument defaults to ``sys.path``.
+
+    Raises ImportError if no search path could be found.
+    """
+    if path is None:
+        path = sys.path
+
+    results = []
+
+    for path_item in path:
+        importer = get_importer(path_item)
+
+        if importer is None:
+            continue
+
+        try:
+            loader = importer.find_module(name)
+
+            if loader is not None:
+
+                if not hasattr(loader, 'is_package'):
+                    warnings.warn(
+                        "Django cannot find search path for package '%s' ",
+                        "under '%s', because the loader returned by '%s' does ",
+                        "not implement 'is_package' method."%(
+                            name,
+                            path_item,
+                            importer.__class__.__name__))
+                    continue
+
+                if not hasattr(loader, 'get_filename'):
+                    warnings.warn(
+                        "Django cannot find search path for package '%s' ",
+                        "under '%s', because the loader returned by '%s' does ",
+                        "not implement 'get_filename' method."%(
+                            name,
+                            path_item,
+                            importer.__class__.__name__))
+                    continue
+
+                if loader.is_package(name):
+                    results.append(os.path.dirname(loader.get_filename(name)))
+        except ImportError:
+            pass
+
+    if not results:
+        raise ImportError("No module named %s" % name)
+
+    return results
+
+
+get_importer = pkgutil.get_importer
+
+try:
+    import zipimport
+
+    if hasattr(zipimport.zipimporter, 'get_filename'):
+        class ZipImporter(zipimport.zipimporter):
+            def get_filename(self, fullname):
+                archivepath = os.path.join(self.archive, self.prefix)
+                if self.is_package(fullname):
+                    return os.path.join(archivepath, fullname, '__init__.py')
+
+                return os.path.join(archivepath, fullname + '.py')
+
+        def get_importer(path_item):
+            importer = pkgutil.get_importer(path_item)
+
+            if isinstance(importer, zipimport.zipimporter):
+                archivepath = os.path.join(importer.archive, importer.prefix)
+                importer = ZipImporter(os.path.dirname(archivepath))
+
+            return importer
+
+except ImportError:
+    pass
+
+
diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py b/tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py b/tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py b/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py
new file mode 100644
index 0000000..a393663
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+    help = 'Test managment commands in non-namespaced app'
+    requires_model_validation = False
+    args = ''
+
+    def handle(self, *labels, **options):
+        print 'EXECUTE:nons_app_command1'
diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/models.py b/tests/regressiontests/admin_scripts/lib1/nons_app/models.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py
new file mode 100644
index 0000000..32f26d8
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py
new file mode 100644
index 0000000..32f26d8
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py
new file mode 100644
index 0000000..2f479bb
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+    help = 'Test managment commands in namespaced apps'
+    requires_model_validation = False
+    args = ''
+
+    def handle(self, *labels, **options):
+        print 'EXECUTE:app1_command1'
diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py
new file mode 100644
index 0000000..32f26d8
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py
new file mode 100644
index 0000000..32f26d8
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py
new file mode 100644
index 0000000..b9e20a7
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+    help = 'Test managment commands in namespaced apps'
+    requires_model_validation = False
+    args = ''
+
+    def handle(self, *labels, **options):
+        print 'EXECUTE:app2_command1'
diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib3/_addsitedir.py b/tests/regressiontests/admin_scripts/lib3/_addsitedir.py
new file mode 100644
index 0000000..9e264d2
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib3/_addsitedir.py
@@ -0,0 +1 @@
+import os.path, site; site.addsitedir(os.path.dirname(__file__))
diff --git a/tests/regressiontests/admin_scripts/lib3/egg_module.pth b/tests/regressiontests/admin_scripts/lib3/egg_module.pth
new file mode 100644
index 0000000..9367ab5
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib3/egg_module.pth
@@ -0,0 +1 @@
+test_egg.egg
diff --git a/tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth b/tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth
new file mode 100644
index 0000000..1f31155
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth
@@ -0,0 +1 @@
+import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('exapps',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('exapps',new.module('exapps')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py
new file mode 100644
index 0000000..97f5d33
--- /dev/null
+++ b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+    help = 'Test managment commands in namespaced apps'
+    requires_model_validation = False
+    args = ''
+
+    def handle(self, *labels, **options):
+        print 'EXECUTE:app3_command1'
diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_scripts/lib3/test_egg.egg b/tests/regressiontests/admin_scripts/lib3/test_egg.egg
new file mode 100644
index 0000000000000000000000000000000000000000..d9e57de006a3d602515293f8e980bf3a16fb42c0
GIT binary patch
diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
index 17a2ccb..63d3719 100644
--- a/tests/regressiontests/admin_scripts/tests.py
+++ b/tests/regressiontests/admin_scripts/tests.py
@@ -90,6 +90,10 @@ class AdminScriptTestCase(unittest.TestCase):
     def run_test(self, script, args, settings_file=None, apps=None):
         project_dir = os.path.dirname(test_dir)
         base_dir = os.path.dirname(project_dir)
+        lib1_dir = os.path.join(os.path.dirname(__file__), 'lib1')
+        lib2_dir = os.path.join(os.path.dirname(__file__), 'lib2')
+        lib3_dir = os.path.join(os.path.dirname(__file__), 'lib3')
+        eggs_dir = os.path.join(os.path.dirname(__file__), 'eggs')
         ext_backend_base_dirs = self._ext_backend_paths()
 
         # Remember the old environment
@@ -107,7 +111,7 @@ class AdminScriptTestCase(unittest.TestCase):
             os.environ['DJANGO_SETTINGS_MODULE'] = settings_file
         elif 'DJANGO_SETTINGS_MODULE' in os.environ:
             del os.environ['DJANGO_SETTINGS_MODULE']
-        python_path = [project_dir, base_dir]
+        python_path = [project_dir, base_dir, lib1_dir, lib2_dir, lib3_dir]
         python_path.extend(ext_backend_base_dirs)
         os.environ[python_path_var_name] = os.pathsep.join(python_path)
 
@@ -1489,3 +1493,86 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
         self.assertNoOutput(err)
         self.assertTrue(os.path.isdir(testproject_dir))
         self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
+
+class NamespacePackagedApps(AdminScriptTestCase):
+    def setUp(self):
+        self.write_settings('settings.py', apps=['nons_app', 'nsapps.contrib.app1','nsapps.contrib.app2','exapps.app3', 'egg_module'])
+        test_dir = os.path.dirname(os.path.dirname(__file__))
+        settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
+        settings_file.write('import _addsitedir')
+        settings_file.close()
+        
+    def tearDown(self):
+        self.remove_settings('settings.py')
+
+    def test_help(self):
+        out, err = self.run_manage(['help'])
+        self.assertNoOutput(err)
+        self.assertOutput(out, "nons_app_command1")
+        self.assertOutput(out, "app1_command1")
+        self.assertOutput(out, "app2_command1")
+        self.assertOutput(out, "app3_command1")
+        self.assertOutput(out, "egg_command")
+
+    def test_nons_app(self):
+        args = ['nons_app_command1']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:nons_app_command1")
+
+    def test_nsapps(self):
+        args = ['app1_command1']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:app1_command1")
+
+        args = ['app2_command1']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:app2_command1")
+
+    def test_exapps(self):
+        args = ['app3_command1']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:app3_command1")
+
+    def test_exapps(self):
+        args = ['egg_command']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:egg_command")
+
+
+class PreloadedNamespacePackagedApps(AdminScriptTestCase):
+    def setUp(self):
+        self.write_settings('settings.py', apps=['nsapps.contrib.app1','nsapps.contrib.app2'])
+        test_dir = os.path.dirname(os.path.dirname(__file__))
+        settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
+        settings_file.write('import nsapps')
+        settings_file.close()
+        
+    def tearDown(self):
+        self.remove_settings('settings.py')
+
+    def test_help(self):
+        out, err = self.run_manage(['help'])
+        self.assertNoOutput(err)
+        self.assertOutput(out, "app1_command1")
+        self.assertOutput(out, "app2_command1")
+
+
+    def test_nsapps(self):
+        args = ['app1_command1']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:app1_command1")
+
+        args = ['app2_command1']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:app2_command1")
+
+
+
+
