# Path: schwa/dr/decoration.py
# class Decorator(object):
#   """
#   An abstract document decorator, which wraps its decorate method to ensure it is only executed once per document.
#   """
# 
#   def __init__(self, key):
#     # NOTE: wrapping __call__ like this didn't seem to work
#     self.decorate = decorator(key)(self.decorate)
#     self._key = key
# 
#   @classmethod
#   def _build_key(cls, *args):
#     return '{0}-{1}'.format(cls.__name__, '-'.join(repr(arg) for arg in args))
# 
#   def _set_affected_fields(self, *args):
#     """
#     Stores a list of fields affected (i.e. set) for this decorator, aiding in reflexion and undo operations.
# 
#     Elements of args should be (store, field) pairs, or just an attr string for attributes of the document set by the decorator.
# 
#     Where store, field or attr are not strings or None for any of the args, affected fields will not be stored.
#     """
#     field_map = collections.defaultdict(set)
#     for field in args:
#       if isinstance(field, (six.binary_type, six.text_type)):
#         field_map[None].add(field)
#       elif field is None:
#         pass
#       else:
#         try:
#           store, field = field
#         except TypeError:
#           return
#         if isinstance(store, (six.binary_type, six.text_type)) and isinstance(field, (six.binary_type, six.text_type)):
#           field_map[store].add(field)
#         elif store is not None and field is not None:
#           # Not strings or None.
#           return
#     self._affected_fields = dict(field_map)
# 
#   def __call__(self, doc):
#     self.decorate(doc)
# 
#   def reapply(self, doc):
#     """Apply the decorator without checking if it has been previously applied to this document."""
#     return self.decorate.reapply(doc)
# 
#   @staticmethod
#   def _clear_fields(obj, fields):
#     for field in fields:
#       try:
#         delattr(obj, field)
#       except AttributeError:
#         pass
# 
#   def undo(self, doc, unmark=True):
#     """Where possible, unset the fields set by this decorator (and any other values in those fields), and allow it to be decorated again."""
#     try:
#       field_map = self._affected_fields
#     except AttributeError:
#       raise NotImplementedError('The affected fields are unknown for decorator %r' % self)
# 
#     for store, fields in six.iteritems(field_map):
#       if store is None:
#         self._clear_fields(doc, fields)
#       else:
#         for obj in getattr(doc, store, ()):
#           self._clear_fields(obj, fields)
# 
#     if unmark:
#       try:
#         del doc._dr_decorated_by[self._key]
#       except KeyError:
#         pass
# 
#   def decorate(self, doc):
#     raise NotImplementedError()
# 
#   def __str__(self):
#     return self._key


import collections
import functools
import operator
import itertools
import six
from .decoration import Decorator
    self.set_pointer = setter(pointer_attr)
    self.set_offset = setter(offset_attr)
    self.set_roffset = setter(roffset_attr)
    self.set_all = setter(all_attr)
    self.mark_outside = mark_outside
    self._set_affected_fields((target_store, pointer_attr), (target_store, offset_attr), (target_store, roffset_attr), (target_store, all_attr))

  def decorate(self, doc):
    target_items = self.get_target_store(doc)

    if self.mark_outside:
      for target in target_items:
        self.set_pointer.default(target, None)
        self.set_offset.default(target, None)
        self.set_roffset.default(target, None)
        self.set_all.default(target, (None, None, None))

    for source in self.get_source_store(doc):
      span = getattr(source, self.slice_attr)
      if span is None:
        continue
      n = span.stop - span.start
      for i, target in enumerate(target_items[span]):
        self.set_pointer(target, source)
        self.set_offset(target, i)
        roffset = n - i - 1
        self.set_roffset(target, roffset)
        self.set_all(target, (source, i, roffset))



# Path: schwa/dr/decoration.py
# class Decorator(object):
#   """
#   An abstract document decorator, which wraps its decorate method to ensure it is only executed once per document.
#   """
# 
#   def __init__(self, key):
#     # NOTE: wrapping __call__ like this didn't seem to work
#     self.decorate = decorator(key)(self.decorate)
#     self._key = key
# 
#   @classmethod
#   def _build_key(cls, *args):
#     return '{0}-{1}'.format(cls.__name__, '-'.join(repr(arg) for arg in args))
# 
#   def _set_affected_fields(self, *args):
#     """
#     Stores a list of fields affected (i.e. set) for this decorator, aiding in reflexion and undo operations.
# 
#     Elements of args should be (store, field) pairs, or just an attr string for attributes of the document set by the decorator.
# 
#     Where store, field or attr are not strings or None for any of the args, affected fields will not be stored.
#     """
#     field_map = collections.defaultdict(set)
#     for field in args:
#       if isinstance(field, (six.binary_type, six.text_type)):
#         field_map[None].add(field)
#       elif field is None:
#         pass
#       else:
#         try:
#           store, field = field
#         except TypeError:
#           return
#         if isinstance(store, (six.binary_type, six.text_type)) and isinstance(field, (six.binary_type, six.text_type)):
#           field_map[store].add(field)
#         elif store is not None and field is not None:
#           # Not strings or None.
#           return
#     self._affected_fields = dict(field_map)
# 
#   def __call__(self, doc):
#     self.decorate(doc)
# 
#   def reapply(self, doc):
#     """Apply the decorator without checking if it has been previously applied to this document."""
#     return self.decorate.reapply(doc)
# 
#   @staticmethod
#   def _clear_fields(obj, fields):
#     for field in fields:
#       try:
#         delattr(obj, field)
#       except AttributeError:
#         pass
# 
#   def undo(self, doc, unmark=True):
#     """Where possible, unset the fields set by this decorator (and any other values in those fields), and allow it to be decorated again."""
#     try:
#       field_map = self._affected_fields
#     except AttributeError:
#       raise NotImplementedError('The affected fields are unknown for decorator %r' % self)
# 
#     for store, fields in six.iteritems(field_map):
#       if store is None:
#         self._clear_fields(doc, fields)
#       else:
#         for obj in getattr(doc, store, ()):
#           self._clear_fields(obj, fields)
# 
#     if unmark:
#       try:
#         del doc._dr_decorated_by[self._key]
#       except KeyError:
#         pass
# 
#   def decorate(self, doc):
#     raise NotImplementedError()
# 
#   def __str__(self):
#     return self._key


# Path: schwa/dr/decorators.py
import collections
import functools
import operator
import itertools
import six
from .decoration import Decorator

    self.set_pointer = setter(pointer_attr)
    self.set_offset = setter(offset_attr)
    self.set_roffset = setter(roffset_attr)
    self.set_all = setter(all_attr)
    self.mark_outside = mark_outside
    self._set_affected_fields((target_store, pointer_attr), (target_store, offset_attr), (target_store, roffset_attr), (target_store, all_attr))

  def decorate(self, doc):
    target_items = self.get_target_store(doc)

    if self.mark_outside:
      for target in target_items:
        self.set_pointer.default(target, None)
        self.set_offset.default(target, None)
        self.set_roffset.default(target, None)
        self.set_all.default(target, (None, None, None))

    for source in self.get_source_store(doc):
      span = getattr(source, self.slice_attr)
      if span is None:
        continue
      n = span.stop - span.start
      for i, target in enumerate(target_items[span]):
        self.set_pointer(target, source)
        self.set_offset(target, i)
        roffset = n - i - 1
        self.set_roffset(target, roffset)
        self.set_all(target, (source, i, roffset))



class find_contained_slices(Decorator):