Read graph and update component definitions with related elements

def _extend_component_definitions(self, graph):
        """
        Read graph and update component definitions with related elements
        """
        for def_uri, comp_def in self._components.items():
            # Store created components indexed for later lookup
            component_index = {}
            identity = URIRef(def_uri)

            # Get components
            for comp in graph.triples((identity, SBOL.component, None)):
                comp_identity = comp[2]
                ci = self._get_rdf_identified(graph, comp_identity)
                ci['maps_to'] = self._get_triplet_value(graph, comp_identity, SBOL.mapTo)
                ci['access'] = self._get_triplet_value(graph, comp_identity, SBOL.access)

                component_comp_def = self._get_triplet_value(graph, comp_identity, SBOL.definition)
                ci['definition'] = self._components[component_comp_def]

                c = Component(**ci)
                component_index[ci['identity']] = c
            self._components[def_uri].components = list(component_index.values())

            # Get sequence annotations
            if (identity, SBOL.sequenceAnnotation, None) in graph:
                find_annotation_using = (identity, SBOL.sequenceAnnotation, None)
            else:
                find_annotation_using = (identity, SBOL.SequenceAnnotation, None)
            sequence_annotations = []
            for seq_annot in graph.triples(find_annotation_using):
                seq_identity = seq_annot[2]
                sa = self._get_rdf_identified(graph, seq_identity)
                component_to_use = self._get_triplet_value(graph, seq_identity, SBOL.component)
                sa['component'] = component_index[component_to_use]
                sa['roles'] = self._get_triplet_value_list(graph, seq_identity, SBOL.role)
                locations = []
                for loc in graph.triples((seq_identity, SBOL.location, None)):
                    loc_identity = loc[2]
                    location = self._get_rdf_identified(graph, loc_identity)
                    location['orientation'] = self._get_triplet_value(graph, loc_identity,
                                                                      SBOL.orientation)
                    location_type = URIRef(self._get_triplet_value(graph, loc_identity, RDF.type))
                    if location_type == SBOL.Range:
                        location['start'] = self._get_triplet_value(graph, loc_identity, SBOL.start)
                        location['end'] = self._get_triplet_value(graph, loc_identity, SBOL.end)
                        locations.append(Range(**location))
                    elif location_type == SBOL.Cut:
                        location['at'] = self._get_triplet_value(graph, loc_identity, SBOL.at)
                        locations.append(Cut(**location))
                    else:
                        locations.append(GenericLocation(**location))
                sa_obj = SequenceAnnotation(locations=locations, **sa)
                sequence_annotations.append(sa_obj)
            self._components[def_uri].sequence_annotations = sequence_annotations

            # Get sequence constraints
            if (identity, SBOL.sequenceConstraint, None) in graph:
                find_constraint_using = (identity, SBOL.sequenceConstraint, None)
            else:
                find_constraint_using = (identity, SBOL.SequenceConstraint, None)
            sequence_constraints = []
            for seq_constraint in graph.triples(find_constraint_using):
                seq_identity = seq_constraint[2]
                sc = self._get_rdf_identified(graph, seq_identity)
                sc['restriction'] = self._get_triplet_value(graph, seq_identity, SBOL.restriction)
                subject_id = self._get_triplet_value(graph, seq_identity, SBOL.subject)
                sc['subject'] = component_index[subject_id]
                object_id = self._get_triplet_value(graph, seq_identity, SBOL.object)
                # Object is a reserved word so call it obj to prevent clashes
                sc['obj'] = component_index[object_id]
                sc_obj = SequenceConstraint(**sc)
                sequence_constraints.append(sc_obj)
            self._components[def_uri].sequence_constraints = sequence_constraints