'Allocate segment fully specified by raw_segment.
If segment exists, then try to allocate it and return db object
If segment does not exists, then try to create it and return db object
If allocation/creation failed, then return None'

def allocate_fully_specified_segment(self, context, **raw_segment):

    network_type = self.get_type()
    (session, ctx_manager) = self._get_session(context)
    try:
        with ctx_manager:
            alloc = session.query(self.model).filter_by(**raw_segment).first()
            if alloc:
                if alloc.allocated:
                    return
                else:
                    LOG.debug('%(type)s    segment    %(segment)s    allocate    started    ', {'type': network_type, 'segment': raw_segment})
                    count = session.query(self.model).filter_by(allocated=False, **raw_segment).update({'allocated': True})
                    if count:
                        LOG.debug('%(type)s    segment    %(segment)s    allocate    done    ', {'type': network_type, 'segment': raw_segment})
                        return alloc
                    LOG.debug('%(type)s    segment    %(segment)s    allocate    failed:    segment    has    been    allocated    or    deleted', {'type': network_type, 'segment': raw_segment})
            LOG.debug('%(type)s    segment    %(segment)s    create    started', {'type': network_type, 'segment': raw_segment})
            alloc = self.model(allocated=True, **raw_segment)
            alloc.save(session)
            LOG.debug('%(type)s    segment    %(segment)s    create    done', {'type': network_type, 'segment': raw_segment})
    except db_exc.DBDuplicateEntry:
        alloc = None
        LOG.debug('%(type)s    segment    %(segment)s    create    failed', {'type': network_type, 'segment': raw_segment})
    return alloc
