def process_plan(self, plan, sources, target):
        '''
        Called after the planning phase has completed. Provides an opportunity
        for the processors to modify the plan thus changing the actions that
        will be displayed and potentially applied.

        - `plan` may be None if no changes were detected, if so a `Plan` may
          still be created and returned.
        - May modify `plan.changes` directly or create a new `Plan`.
        - Does not have to modify `plan.desired` and/or `plan.existing` to line
          up with any modifications made to `plan.changes`.
        - Should copy over `plan.exists`, `plan.update_pcent_threshold`, and
          `plan.delete_pcent_threshold` when creating a new `Plan`.
        - Must return a `Plan` which may be `plan` or can be a newly created
          one `plan.desired` and `plan.existing` copied over as-is or modified.
        '''
        # plan may be None if no changes were detected up until now, the
        # process may still create a plan.
        # sources may be empty, as will be the case for aliased zones
        return plan

        Called after the planning phase has completed. Provides an opportunity
        for the processors to modify the plan thus changing the actions that
        will be displayed and potentially applied.

        - `plan` may be None if no changes were detected, if so a `Plan` may
          still be created and returned.
        - May modify `plan.changes` directly or create a new `Plan`.
        - Does not have to modify `plan.desired` and/or `plan.existing` to line
          up with any modifications made to `plan.changes`.
        - Should copy over `plan.exists`, `plan.update_pcent_threshold`, and
          `plan.delete_pcent_threshold` when creating a new `Plan`.
        - Must return a `Plan` which may be `plan` or can be a newly created
          one `plan.desired` and `plan.existing` copied over as-is or modified.
        
octodns/processor/base.py