def expandOptions(self, bindings, statements, constraints):
        def replace(key, resource, tupl):
            s,p,o,func = tupl
            if key == s:
                s = resource
            if key == p:
                p = resource
            if key == o:
                o = resource
            return (s,p,o,func)

        if len(self.children) == 0:

            # this is a leaf in the original expansion
            if self.bound == True and self.clash == False:

                # see if the optional bindings can be reduced because they are already
                # bound by this node
                toldBNodeLookup = {}
                for key in self.bindings:
                    normalizedStatements = []

                    for t in statements:
                        val = self.bindings[key]

                        if isinstance(val,BNode) and val not in toldBNodeLookup:
                            toldBNodeLookup[val] = val

                        normalizedStatements.append(replace(key,self.bindings[key],t))

                    statements = normalizedStatements

                    if key in bindings :
                        del bindings[key]

                bindings.update(toldBNodeLookup)

                optTree = _SPARQLNode(None, bindings, statements,
                                      self.tripleStore, expr=self.expr)

                self.optionalTrees.append(optTree)
                optTree.expand(constraints)

        else:
            for c in self.children:
                c.expandOptions(bindings, statements, constraints)
Returns the proxy class. 
dataset/ETHPy150Open RDFLib/rdfextras/rdfextras/sparql/query.py/_SPARQLNode.expandOptions--crossover with--dataset/ETHPy150Open espeed/bulbs/bulbs/model.py/Relationship.get_proxy_class