diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 1214a82..88d3945 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -3,11 +3,12 @@ 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.core.management.color import color_style
-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
@@ -23,11 +24,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):
@@ -54,7 +55,7 @@ def find_management_module(app_name):
     else:
         parts.reverse()
         part = parts.pop()
-        path = sys.path
+        path = None
 
         # When using manage.py, the project module is added to the path,
         # loaded, then removed from the path. This means that
@@ -63,31 +64,14 @@ def find_management_module(app_name):
         # 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:
-            next_path = []
-            for p in path:
-                try:
-                    next_path.append(imp.find_module(part, [p])[1])
-                except ImportError:
-                    pass
-            if not next_path:
-                raise ImportError("No module named %s" % part)
-            path = next_path
+            path = find_package_path(part, path)
         except ImportError,e:
             if os.path.basename(os.getcwd()) != part:
                 raise e
 
     while parts:
         part = parts.pop()
-        next_path = []
-        for p in path:
-            try:
-                next_path.append(imp.find_module(part, [p])[1])
-            except ImportError:
-                pass
-        if not next_path:
-            raise ImportError("No module named %s" % part)
-        path = next_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..f53abd9 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 package 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/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/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 45852ba..1240ca4 100644
--- a/tests/regressiontests/admin_scripts/tests.py
+++ b/tests/regressiontests/admin_scripts/tests.py
@@ -93,6 +93,7 @@ class AdminScriptTestCase(unittest.TestCase):
         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
@@ -1558,8 +1559,7 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
 
 class NamespacePackagedApps(AdminScriptTestCase):
     def setUp(self):
-        self.write_settings('settings.py', apps=['nons_app', 'nsapps.contrib.app1','nsapps.contrib.app2','exapps.app3'])
-        test_dir = os.path.dirname(os.path.dirname(__file__))
+        self.write_settings('settings.py', apps=['nons_app', 'nsapps.contrib.app1','nsapps.contrib.app2','exapps.app3', 'egg_module'])
         settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
         settings_file.write('import _addsitedir')
         settings_file.close()
@@ -1574,6 +1574,7 @@ class NamespacePackagedApps(AdminScriptTestCase):
         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']
@@ -1598,10 +1599,16 @@ class NamespacePackagedApps(AdminScriptTestCase):
         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()
