class TrackedEntityInstanceSupplier extends AbstractSupplier<Map<String, Pair<TrackedEntityInstance, Boolean>>> {

    @Override
    public Map<String, Pair<TrackedEntityInstance, Boolean>> get( ImportOptions importOptions, List<Event> events )
    {

        if ( events == null )
        {
            return new HashMap<>();
        }
        // @formatter:off
        // Collect all the org unit uids to pass as SQL query argument
        Set<String> teiUids = events.stream()
                .filter( e -> e.getTrackedEntityInstance() != null )
                .map( Event::getTrackedEntityInstance ).collect( Collectors.toSet() );
        // @formatter:on

        if ( isEmpty( teiUids ) )
        {
            return new HashMap<>();
        }

        // Create a map: tei uid -> List [event uid]
        Multimap<String, String> teiToEvent = HashMultimap.create();
        for ( Event event : events )
        {
            teiToEvent.put( event.getTrackedEntityInstance(), event.getUid() );
        }

        //
        // Get all TEI associated to the events
        //
        Map<String, TrackedEntityInstance> teiMap = getTrackedEntityInstances( teiUids, teiToEvent );

        Map<String, Pair<TrackedEntityInstance, Boolean>> result = new HashMap<>();

        //
        // Return a map containing a Pair where key is the Tei and value is the boolean, can the TEI be updated
        // by current user
        //
        for ( String event : teiMap.keySet() )
        {
            TrackedEntityInstance tei = teiMap.get( event );
            result.put( event,
                Pair.of( tei, !importOptions.isSkipLastUpdated() ? aclService.canUpdate( importOptions.getUser(), tei )
                    : null ) );

        }

        return result;
    }

    public  TrackedEntityInstanceSupplier( NamedParameterJdbcTemplate jdbcTemplate,
        AclService aclService );

}