def METHOD_NAME(self, patient_id=None, document_id=None,
        limit=1000, bucket_size_seconds=None, min_count=0, meta_requirements=None, require_time=True):
    """Returns all concepts belonging to a document or patient
    given the concept type (if none all are retruned).
    """
    if patient_id is not None:
        q = 'MATCH (patient:Patient {patientId: "%s"})-[:HAS]->' % patient_id \
            + '(document:Document)-[has:HAS]->(concept:Concept) \n'
    elif document_id is not None:
        q = 'MATCH (patient:Patient)-[:HAS]->(document:Document {documentId: "%s"})' % document_id \
            + '-[has:HAS]->(concept:Concept) \n'
    else:
        raise Exception("patient_id or document_id are required")
    q += 'RETURN patient, document, concept, has LIMIT %s \n' % limit
    data = self.execute(q).data() # Do not like this too much 
    out = None
    if len(data) > 0:
        out = {'patient': dict(data[0]['patient']),
               'entities': []}
        cnt = defaultdict(int)
        for row in data:
            if meta_requirements is None or \
               all([row['has'][meta] == value for meta,value in meta_requirements.items()]):
                if not require_time or 'timestamp' in row['has']:
                    ent = dict(row['concept']) # Take everything from concept
                    ent['documentId'] = row['document']['documentId']
                    ent.update(row['has']) # add all the stuff from the meta ann
                    out['entities'].append(ent)
                    cnt[ent['conceptId']] += 1
        # Cleanup based on min_count
        new_ents = []
        for ent in out['entities']:
            if cnt[ent['conceptId']] >= min_count:
                ent['count'] = cnt[ent['conceptId']]
                new_ents.append(ent)
        out['entities'] = new_ents
        if bucket_size_seconds is not None:
            self.bucket_concepts(data=out, bucket_size_seconds=bucket_size_seconds)
    return out, q