def parse_compartments(self):
compartments = OrderedDict()<EOL>boundaries = set()<EOL>if '<STR_LIT>' in self._model:<EOL><INDENT>boundary_map = {}<EOL>for compartment_def in self._model['<STR_LIT>']:<EOL><INDENT>compartment_id = compartment_def.get('<STR_LIT:id>')<EOL>_check_id(compartment_id, '<STR_LIT>')<EOL>if compartment_id in compartments:<EOL><INDENT>raise ParseError('<STR_LIT>'.format(<EOL>compartment_id))<EOL><DEDENT>props = dict(compartment_def)<EOL>adjacent_to = props.pop('<STR_LIT>', None)<EOL>if adjacent_to is not None:<EOL><INDENT>if not isinstance(adjacent_to, list):<EOL><INDENT>adjacent_to = [adjacent_to]<EOL><DEDENT>for other in adjacent_to:<EOL><INDENT>boundary_map.setdefault(other, set()).add(<EOL>compartment_id)<EOL><DEDENT><DEDENT>mark = FileMark(self._context, None, None)<EOL>compartment = CompartmentEntry(props, mark)<EOL>compartments[compartment_id] = compartment<EOL><DEDENT>for source, dest_set in iteritems(boundary_map):<EOL><INDENT>if source not in compartments:<EOL><INDENT>raise ParseError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(<EOL>source, '<STR_LIT:U+002CU+0020>'.join(dest_set)))<EOL><DEDENT>for dest in dest_set:<EOL><INDENT>boundaries.add(tuple(sorted((source, dest))))<EOL><DEDENT><DEDENT><DEDENT>return itervalues(compartments), frozenset(boundaries)<EOL>
Parse compartment information from model.

        Return tuple of: 1) iterator of
        :class:`psamm.datasource.entry.CompartmentEntry`; 2) Set of pairs
        defining the compartment boundaries of the model.