docs: def data(self, name, subject_ids=None, visit_ids=None, session_ids=None,
               **kwargs):
          """
          Returns the Fileset(s) or Field(s) associated with the provided spec
          name(s), generating derived filesets as required. Multiple names in a
          list can be provided, to allow their workflows to be combined into a
          single workflow.
  
          Parameters
          ----------
          name : str | List[str]
              The name of the FilesetSpec|FieldSpec to retried the
              filesets for
          subject_id : str | None
              The subject ID of the data to return. If provided (including None
              values) the data will be return as a single item instead of a
              collection
          visit_id : str | None
              The visit ID of the data to return. If provided (including None
              values) the data will be return as a single item instead of a
              c ollection
          subject_ids : list[str]
              The subject IDs to include in the returned collection
          visit_ids : list[str]
              The visit IDs to include in the returned collection
          session_ids : list[str]
              The session IDs (i.e. 2-tuples of the form
              (<subject-id>, <visit-id>) to include in the returned collection
  
          Returns
          -------
          data : BaseItem | BaseCollection | list[BaseItem | BaseCollection]
              If 'subject_id' or 'visit_id' is provided then the data returned is
              a single Fileset or Field. Otherwise a collection of Filesets or
              Fields are returned. If muliple spec names are provided then a
              list of items or collections corresponding to each spec name.
          """
          if isinstance(name, basestring):
              single_name = True
              names = [name]
          else:
              names = name
              single_name = False
          single_item = 'subject_id' in kwargs or 'visit_id' in kwargs
          filter_items = (subject_ids, visit_ids, session_ids) != (None, None,
                                                                     None)
          specs = [self.spec(n) for n in names]
          if single_item:
              if filter_items:
                  raise ArcanaUsageError(
                      "Cannot provide 'subject_id' and/or 'visit_id' in "
                      "combination with 'subject_ids', 'visit_ids' or "
                      "'session_ids'")
              subject_id = kwargs.pop('subject_id', None)
              visit_id = kwargs.pop('visit_id', None)
              iterators = set(chain(self.FREQUENCIES[s.frequency]
                                    for s in specs))
              if subject_id is not None and visit_id is not None:
                  session_ids = [(subject_id, visit_id)]
              elif subject_id is not None:
                  if self.VISIT_ID in iterators:
                      raise ArcanaUsageError(
                          "Non-None values for visit IDs need to be "
                          "provided to select a single item for each of '{}'"
                          .format("', '".join(names)))
                  subject_ids = [subject_id]
              elif visit_id is not None:
                  if self.SUBJECT_ID in iterators:
                      raise ArcanaUsageError(
                          "Non-None values for subject IDs need to be "
                          "provided to select a single item for each of '{}'"
                          .format("', '".join(names)))
                  visit_ids = [visit_id]
              elif iterators:
                  raise ArcanaUsageError(
                      "Non-None values for subject and/or visit IDs need to be "
                      "provided to select a single item for each of '{}'"
                      .format("', '".join(names)))
          # Work out which pipelines need to be run
          pipeline_getters = defaultdict(set)
          for spec in specs:
              if spec.derived or spec.derivable:  # Filter out Study inputs
                  # Add name of spec to set of required outputs
                  pipeline_getters[spec.pipeline_getter].add(spec.name)
          # Run required pipelines
          if pipeline_getters:
              kwargs = copy(kwargs)
              kwargs.update({'subject_ids': subject_ids,
                             'visit_ids': visit_ids,
                             'session_ids': session_ids})
              pipelines, required_outputs = zip(*(
                  (self.pipeline(k), v) for k, v in pipeline_getters.items()))
              kwargs['required_outputs'] = required_outputs
              self.processor.run(*pipelines, **kwargs)
          # Find and return Item/Collection corresponding to requested spec
          # names
          all_data = []
          for name in names:
              spec = self.bound_spec(name)
              data = spec.collection
              if single_item:
                  data = data.item(subject_id=subject_id, visit_id=visit_id)
              elif filter_items and spec.frequency != 'per_study':
                  if subject_ids is None:
                      subject_ids = []
                  if visit_ids is None:
                      visit_ids = []
                  if session_ids is None:
                      session_ids = []
                  if spec.frequency == 'per_session':
                      data = [d for d in data
                              if (d.subject_id in subject_ids or
                                  d.visit_id in visit_ids or
                                  d.session_id in session_ids)]
                  elif spec.frequency == 'per_subject':
                      data = [d for d in data
                              if (d.subject_id in subject_ids or
                                  d.subject_id in [s[0] for s in session_ids])]
                  elif spec.frequency == 'per_visit':
                      data = [d for d in data
                              if (d.visit_id in visit_ids or
                                  d.visit_id in [s[1] for s in session_ids])]
                  if not data:
                      raise ArcanaUsageError(
                          "No matching data found (subject_ids={}, visit_ids={} "
                          ", session_ids={})"
                          .format(subject_ids, visit_ids, session_ids))
                  data = spec.CollectionClass(spec.name, data)
              if single_name:
                  return data
              else:
                  all_data.append(data)
          return all_data