Reconstitutes requested domain entity from domain events found in event store.

def get_and_project_events(self, entity_id, gt=None, gte=None, lt=None, lte=None, limit=None, initial_state=None,
                               query_descending=False):
        """
        Reconstitutes requested domain entity from domain events found in event store.
        """
        # Decide if query is in ascending order.
        #  - A "speed up" for when events are stored in descending order (e.g.
        #  in Cassandra) and it is faster to get them in that order.
        #  - This isn't useful when 'until' or 'after' or 'limit' are set,
        #    because the inclusiveness or exclusiveness of until and after
        #    and the end of the stream that is truncated by limit both depend on
        #    the direction of the query. Also paging backwards isn't useful, because
        #    all the events are needed eventually, so it would probably slow things
        #    down. Paging is intended to support replaying longer event streams, and
        #    only makes sense to work in ascending order.
        if gt is None and gte is None and lt is None and lte is None and self.__page_size__ is None:
            is_ascending = False
        else:
            is_ascending = not query_descending

        # Get entity's domain events from the event store.
        domain_events = self.event_store.get_domain_events(
            originator_id=entity_id,
            gt=gt,
            gte=gte,
            lt=lt,
            lte=lte,
            limit=limit,
            is_ascending=is_ascending,
            page_size=self.__page_size__
        )

        # The events will be replayed in ascending order.
        if not is_ascending:
            domain_events = list(reversed(list(domain_events)))

        # Project the domain events onto the initial state.
        return self.project_events(initial_state, domain_events)