class ProgramInstanceSupplier extends AbstractSupplier<Map<String, ProgramInstance>> {

    public Map<String, ProgramInstance> get( ImportOptions importOptions,
        Map<String, Pair<TrackedEntityInstance, Boolean>> teiMap, List<Event> events )
    {
        if ( events == null )
        {
            return new HashMap<>();
        }

        // Collect all the program instance UIDs to pass as SQL query argument
        Set<String> programInstanceUids = events.stream()
            .filter( e -> StringUtils.isNotEmpty( e.getEnrollment() ) )
            .map( Event::getEnrollment ).collect( Collectors.toSet() );

        Map<String, ProgramInstance> programInstances = new HashMap<>();

        if ( !programInstanceUids.isEmpty() )
        {
            // Create a bi-directional map enrollment uid -> event uid
            Multimap<String, String> programInstanceToEvent = HashMultimap.create();
            for ( Event event : events )
            {
                programInstanceToEvent.put( event.getEnrollment(), event.getUid() );
            }

            // Collect all the Program Stage Instances specified in the Events (enrollment
            // property)
            programInstances = getProgramInstancesByUid( importOptions, events, programInstanceToEvent,
                programInstanceUids );
        }

        mapExistingEventsToProgramInstances( importOptions, events, programInstances );

        mapEventsToProgramInstanceByTei( importOptions, events, programInstances, teiMap );

        return programInstances;
    }

    public  ProgramInstanceSupplier( NamedParameterJdbcTemplate jdbcTemplate, ProgramSupplier programSupplier );

}