# Buggy code
def _ProcessSources(self, source_path_specs, storage_writer, filter_find_specs=None):
    """Processes the sources.

    Args:
      source_path_specs (list[dfvfs.PathSpec]): path specifications of
          the sources to process.
      storage_writer (StorageWriter): storage writer for a session storage.
      filter_find_specs (Optional[list[dfvfs.FindSpec]]): find specifications
          used in path specification extraction. If set, path specs that match
          the find specification will be processed.
    """
    if self._processing_profiler:
        self._processing_profiler.StartTiming("process_sources")

    self._status = definitions.PROCESSING_STATUS_COLLECTING
    self._number_of_consumed_errors = 0
    self._number_of_consumed_events = 0
    self._number_of_consumed_reports = 0
    self._number_of_consumed_sources = 0
    self._number_of_produced_errors = 0
    self._number_of_produced_events = 0
    self._number_of_produced_reports = 0
    self._number_of_produced_sources = 0

    path_spec_extractor = extractors.PathSpecExtractor(self._resolver_context)

    for path_spec in path_spec_extractor.ExtractPathSpecs(
        source_path_specs, find_specs=filter_find_specs, recurse_file_system=False
    ):
        if self._abort:
            break

        # TODO: determine if event sources should be DataStream or FileEntry
        # or both.
        event_source = event_sources.FileEntryEventSource(path_spec=path_spec)
        storage_writer.AddEventSource(event_source)

        self._number_of_produced_sources = storage_writer.number_of_event_sources

    self._ScheduleTasks(storage_writer)

    if self._abort:
        self._status = definitions.PROCESSING_STATUS_ABORTED
    else:
        self._status = definitions.PROCESSING_STATUS_COMPLETED

    self._number_of_produced_errors = storage_writer.number_of_errors
    self._number_of_produced_events = storage_writer.number_of_events
    self._number_of_produced_sources = storage_writer.number_of_event_sources

    if self._processing_profiler:
        self._processing_profiler.StopTiming("process_sources")


# Traceback (KeyError)
[ERROR] (nsrlsvr   ) PID:XXXXX <analysis_process> <dfvfs.path.os_path_spec.OSPathSpec object at 0xXXXXXXXXXXXX>
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/plaso/multi_processing/analysis_process.py", line 138, in _Main
self._analysis_mediator.ProduceAnalysisReport(self._analysis_plugin)
File "/usr/lib/python2.7/dist-packages/plaso/analysis/mediator.py", line 95, in ProduceAnalysisReport
analysis_report = plugin.CompileReport(self)
File "/usr/lib/python2.7/dist-packages/plaso/analysis/interface.py", line 280, in CompileReport
hash_analysis)
File "/usr/lib/python2.7/dist-packages/plaso/analysis/interface.py", line 187, in _HandleHashAnalysis
event_uuids = self._event_uuids_by_pathspec.pop(pathspec)
KeyError: <dfvfs.path.os_path_spec.OSPathSpec object at 0xXXXXXXXXXXXX>

# Fixed code
def _ProcessSources(self, source_path_specs, storage_writer, filter_find_specs=None):
    """Processes the sources.

    Args:
      source_path_specs (list[dfvfs.PathSpec]): path specifications of
          the sources to process.
      storage_writer (StorageWriter): storage writer for a session storage.
      filter_find_specs (Optional[list[dfvfs.FindSpec]]): find specifications
          used in path specification extraction. If set, path specs that match
          the find specification will be processed.
    """
    if self._processing_profiler:
        self._processing_profiler.StartTiming("process_sources")

    self._status = definitions.PROCESSING_STATUS_COLLECTING
    self._number_of_consumed_errors = 0
    self._number_of_consumed_event_tags = 0
    self._number_of_consumed_events = 0
    self._number_of_consumed_reports = 0
    self._number_of_consumed_sources = 0
    self._number_of_produced_errors = 0
    self._number_of_produced_event_tags = 0
    self._number_of_produced_events = 0
    self._number_of_produced_reports = 0
    self._number_of_produced_sources = 0

    path_spec_extractor = extractors.PathSpecExtractor(self._resolver_context)

    for path_spec in path_spec_extractor.ExtractPathSpecs(
        source_path_specs, find_specs=filter_find_specs, recurse_file_system=False
    ):
        if self._abort:
            break

        # TODO: determine if event sources should be DataStream or FileEntry
        # or both.
        event_source = event_sources.FileEntryEventSource(path_spec=path_spec)
        storage_writer.AddEventSource(event_source)

        self._number_of_produced_sources = storage_writer.number_of_event_sources

    self._ScheduleTasks(storage_writer)

    if self._abort:
        self._status = definitions.PROCESSING_STATUS_ABORTED
    else:
        self._status = definitions.PROCESSING_STATUS_COMPLETED

    self._number_of_produced_errors = storage_writer.number_of_errors
    self._number_of_produced_events = storage_writer.number_of_events
    self._number_of_produced_sources = storage_writer.number_of_event_sources

    if self._processing_profiler:
        self._processing_profiler.StopTiming("process_sources")