class DatabaseFDFlowManager extends BaseService implements FDFlowManager {

    @Override
    public FDFlowEvent deleteFlowEvent(final String flowEventId) {
        if (StringUtils.isBlank(flowEventId)) {
            throw new IllegalArgumentException("Flow event id cannot be null or blank");
        }

        final Optional<FDFlowEventEntity> flowEventEntity = flowEventRepository.findById(flowEventId);
        if (!flowEventEntity.isPresent()) {
            throw new ResourceNotFoundException("No flow event exists for the given id");
        }

        if (flowEventEntity.get().getEventType() == FDFlowEventType.FLOW_PUBLISHED) {
            throw new IllegalArgumentException("Cannot delete event because deleting events of type "
                    + FDFlowEventType.FLOW_PUBLISHED + " is not allowed");
        }

        final FDFlowEntity flowEntity = flowEventEntity.get().getFlow();

        final Long numEventsForFlow = flowEventRepository.countByFlow(flowEntity);
        if (numEventsForFlow <= 1) {
            throw new IllegalStateException("Cannot delete event because there is only one event for the given flow");
        }

        flowEventRepository.delete(flowEventEntity.get());

        // we don't know if the event being deleted is the latest event, and if it is then the cached version of
        // the flow is no longer accurate because it was based on the deleted event
        if (flowsById.containsKey(flowEntity.getId())) {
            flowsById.remove(flowEntity.getId());
        }

        return modelMapper.map(flowEventEntity.get(), FDFlowEvent.class);
    }

}

class TestDatabaseFDFlowManager extends BaseService {

    @Autowired
    private FDFlowManager flowManager;

    @Test
    public void testDeleteFlowEvent() {

        // Verify that we start with 3 events for flow #2
        final String flowId = "2";
        final List<FDFlowEvent> flowEvents = flowManager.getFlowEvents(flowId);
        assertEquals(3, flowEvents.size());

        final FDFlowEvent flowEvent2 = flowManager.deleteFlowEvent("2");
        assertNotNull(flowEvent2);

        final FDFlowEvent flowEvent3 = flowManager.deleteFlowEvent("3");
        assertNotNull(flowEvent3);

        try {
            flowManager.deleteFlowEvent("4");
            Assert.fail("Should have thrown exception");
        } catch (Exception e) {

        }
    }

}