# Buggy code
def __init__(self, maximum_number_of_tasks=0):
    """Initializes a task manager object.

    Args:
      maximum_number_of_tasks (Optional[int]): maximum number of concurrent
          tasks, where 0 represents no limit.
    """
    super(TaskManager, self).__init__()
    # Dictionary mapping task identifiers to tasks which have been abandoned.
    self._abandoned_tasks = {}
    # Dictionary mapping task identifiers to tasks that are active.
    self._active_tasks = {}
    self._maximum_number_of_tasks = maximum_number_of_tasks
    self._tasks_pending_merge = _PendingMergeTaskHeap()
    # Use ordered dictionaries to preserve the order in which tasks were added.
    # This dictionary maps task identifiers to tasks.
    self._tasks_processing = collections.OrderedDict()


# Traceback (KeyError)
plaso - log2timeline version 1.5.0

Source path     : /data/images/2016-0945-00/2016-0945-00-HDD01.E01
Source type     : storage media image

Identifier      PID     Status          Sources         Events          File
Main            15282   running         124812 (0)      148935 (0)
Worker_00       15292   collecting      1903 (0)        3419 (0)        TSK:/Windows/System32/WindowsPowerShell/v1.0
Worker_01       15296   collecting      4843 (0)        10232 (0)       TSK:/Windows/System32/{
Worker_02       15300   collecting      6450 (0)        5009 (0)        TSK:/Windows/System32/SMI/Manifests
Worker_03       15304   collecting      2934 (0)        50431 (0)       TSK:/Windows/System32/wdi/{c4a3}
Worker_04       15308   collecting      2917 (0)        3460 (0)        TSK:/Windows/System32/{3D
Worker_05       15312   running         3820 (7)        9815 (4)        TSK:/Windows/System32/{3DA
Worker_06       15316   collecting      21192 (0)       3489 (0)      TSK:/Windows/System32/wdi/{8643c
Worker_07       15320   collecting      3495 (0)        7159 (0)        TSK:/Windows/System32/winevt/Logs
Worker_08       15324   collecting      21358 (0)       3350 (0)        TSK:/Windows/System32/wdi/perftrack
Worker_09       15328   collecting      2212 (0)        12994 (0)       TSK:/Windows/System32/winrm/0409
Worker_10       15332   collecting      2206 (0)        16475 (0)       TSK:/Windows/System32/winevt/TraceFormat
Worker_11       15336   collecting      20089 (0)       3615 (0)        TSK:/Windows/System32/WinBioPlugIns/en-US
Worker_12       15340   collecting      4551 (0)        3547 (0)        TSK:/Windows/System32/wdi/{6
Worker_13       15344   collecting      15735 (0)       12450 (0)       TSK:/Windows/System32/{3DA228B
Worker_14       15348   collecting      11200 (0)       3510 (0)        TSK:/Windows/System32/SMI/Store

Traceback (most recent call last):
File "/data/plaso/plasoenv/bin/log2timeline.py", line 4, in <module>
__import__('pkg_resources').run_script('plaso==1.5.0', 'log2timeline.py')
File "/data/plaso/plasoenv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 744, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 1499, in run_script
exec(code, namespace, namespace)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/EGG-INFO/scripts/log2timeline.py", line 767, in <module>
if not Main():
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/EGG-INFO/scripts/log2timeline.py", line 753, in Main
tool.ProcessSources()
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/EGG-INFO/scripts/log2timeline.py", line 664, in ProcessSources
timezone=self._timezone, yara_rules_string=self._yara_rules_string)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/frontend/extraction_frontend.py", line 483, in ProcessSources
yara_rules_string=yara_rules_string)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_engine.py", line 791, in ProcessSources
filter_find_specs=filter_find_specs)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_engine.py", line 288, in _ProcessSources
self._ScheduleTasks(storage_writer)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_engine.py", line 397, in _ScheduleTasks
while event_source or self._task_manager.HasActiveTasks():
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_manager.py", line 192, in HasActiveTasks
for task in iter(self._tasks_processing.values()):
File "/usr/lib64/python2.7/collections.py", line 106, in values
return [self[key] for key in self]
KeyError: '7779c7e5f1214e44a6a500dee1d9539d'

# Fixed code
def __init__(self, maximum_number_of_tasks=0):
    """Initializes a task manager object.

    Args:
      maximum_number_of_tasks (Optional[int]): maximum number of concurrent
          tasks, where 0 represents no limit.
    """
    super(TaskManager, self).__init__()
    # Dictionary mapping task identifiers to tasks which have been abandoned.
    self._abandoned_tasks = {}
    # Dictionary mapping task identifiers to tasks that are active.
    self._active_tasks = {}
    self._lock = threading.Lock()
    self._maximum_number_of_tasks = maximum_number_of_tasks
    self._tasks_pending_merge = _PendingMergeTaskHeap()
    # Use ordered dictionaries to preserve the order in which tasks were added.
    # This dictionary maps task identifiers to tasks.
    self._tasks_processing = collections.OrderedDict()