--- pylint-orig/lint.py	2013-09-18 22:21:50.934983264 -0300
+++ pylint/lint.py	2013-09-18 22:23:45.194986894 -0300
@@ -30,6 +30,7 @@
 # import this first to avoid builtin namespace pollution
 from pylint.checkers import utils
 
+import multiprocessing
 import sys
 import os
 import re
@@ -60,6 +61,7 @@
 from pylint.__pkginfo__ import version
 
 
+NUMBER_OF_PROCESSES = 4
 OPTION_RGX = re.compile(r'\s*#*\s*pylint:(.*)')
 REPORTER_OPT_MAP = {'text': TextReporter,
                     'parseable': ParseableTextReporter,
@@ -513,6 +515,43 @@
         self.reporter.symbols = self.config.symbols
         if not isinstance(files_or_modules, (list, tuple)):
             files_or_modules = (files_or_modules,)
+
+        task_queue = multiprocessing.Queue()
+        result_queue = multiprocessing.Queue()
+
+        for i in range(NUMBER_OF_PROCESSES):
+            multiprocessing.Process(target=self._worker_main,
+                                    args=(task_queue, result_queue)).start()
+
+        tasks = []
+
+        for descr in self.expand_files(files_or_modules):
+            tasks.append(descr)
+
+        for task in tasks:
+            task_queue.put(task)
+
+        stats = []
+        for i in range(len(tasks)):
+            stats.append(result_queue.get())
+
+        self.stats = self._merge_stats(stats)
+
+        # Tell child processes to stop
+        for i in range(NUMBER_OF_PROCESSES):
+            task_queue.put('STOP')
+
+    def _worker_main(self, tasks, results):
+        for descr in iter(tasks.get, 'STOP'):
+            result = self._worker_check_one(descr)
+            results.put(result)
+
+    def _worker_check_one(self, descr):
+        # build ast and check modules or packages
+        modname, filepath = descr['name'], descr['path']
+        if self.config.files_output:
+            reportfile = 'pylint_%s.%s' % (modname, self.reporter.extension)
+            self.reporter.set_output(open(reportfile, 'w'))
         walker = PyLintASTWalker(self)
         checkers = self.prepare_checkers()
         rawcheckers = [c for c in checkers if implements(c, IRawChecker)
@@ -522,31 +561,77 @@
             checker.open()
             if implements(checker, IASTNGChecker):
                 walker.add_checker(checker)
-        # build ast and check modules or packages
-        for descr in self.expand_files(files_or_modules):
-            modname, filepath = descr['name'], descr['path']
-            if self.config.files_output:
-                reportfile = 'pylint_%s.%s' % (modname, self.reporter.extension)
-                self.reporter.set_output(open(reportfile, 'w'))
-            self.set_current_module(modname, filepath)
-            # get the module representation
-            astng = self.get_astng(filepath, modname)
-            if astng is None:
-                continue
-            self.base_name = descr['basename']
-            self.base_file = descr['basepath']
-            self._ignore_file = False
-            # fix the current file (if the source file was not available or
-            # if it's actually a c extension)
-            self.current_file = astng.file
-            self.check_astng_module(astng, walker, rawcheckers)
+        self.set_current_module(modname, filepath)
+        # get the module representation
+        astng = self.get_astng(filepath, modname)
+        if astng is None:
+            return
+        self.base_name = descr['basename']
+        self.base_file = descr['basepath']
+        self._ignore_file = False
+        # fix the current file (if the source file was not available or
+        # if it's actually a c extension)
+        self.current_file = astng.file
+        self.check_astng_module(astng, walker, rawcheckers)
+        self.stats['statement'] = walker.nbstatements
+
         # notify global end
         self.set_current_module('')
-        self.stats['statement'] = walker.nbstatements
         checkers.reverse()
         for checker in checkers:
             checker.close()
 
+        return self.stats
+
+    def _merge_stats(self, stats):
+        ARG_SPEC = {'badname_argument': int,
+                    'badname_attr': int,
+                    'badname_class': int,
+                    'badname_const': int,
+                    'badname_function': int,
+                    'badname_inlinevar': int,
+                    'badname_method': int,
+                    'badname_module': int,
+                    'badname_variable': int,
+                    'by_module': dict,
+                    'by_msg': dict,
+                    'class': int,
+                    'convention': int,
+                    'cycles': list,
+                    'dependencies': dict,
+                    'error': int,
+                    'fatal': int,
+                    'function': int,
+                    'info': int,
+                    'method': int,
+                    'module': int,
+                    'refactor': int,
+                    'statement': int,
+                    'undocumented_class': int,
+                    'undocumented_function': int,
+                    'undocumented_method': int,
+                    'undocumented_module': int,
+                    'warning': int}
+        merged = {}
+        for key, arg_type in ARG_SPEC.items():
+            merged[key] = arg_type()
+
+        for stat in stats:
+            for key, item in stat.items():
+                spec = ARG_SPEC[key]
+                value = merged[key]
+                if spec == int:
+                    value += item
+                elif spec == list:
+                    value.extend(item)
+                elif spec == dict:
+                    value.update(item)
+                else:
+                    raise AssertionError((key, spec))
+                merged[key] = value
+
+        return merged
+
     def expand_files(self, modules):
         """get modules and errors from a list of modules and handle errors
         """
