docs: @Override
  	public List<Tuple> getTuples(EntityKey[] keys, TupleContext tupleContext) {
  		Objects.requireNonNull( keys );
  		if ( keys.length == 0 ) {
  			return Collections.emptyList();
  		}
  		else if ( keys.length == 1 ) {
  			return Collections.singletonList( getTuple( keys[0], tupleContext ) );
  		}
  		else {
  			final String cacheName = cacheName( keys[0] );
  			final ProtoStreamMappingAdapter mapper = provider.getDataMapperForCache( cacheName );
  			final Map<EntityKey,ProtostreamId> keyConversionMatch = new HashMap<>();
  			final Set<ProtostreamId> convertedKeys = new HashSet<>();
  			for ( EntityKey ek : keys ) {
  				if ( ek == null ) {
  					continue;
  				}
  				assert cacheName( ek ).equals( cacheName ) : "The javadoc comment promised batches would be loaded from the same table";
  				ProtostreamId idBuffer = mapper.createIdPayload( ek.getColumnNames(), ek.getColumnValues() );
  				keyConversionMatch.put( ek, idBuffer );
  				convertedKeys.add( idBuffer );
  			}
  			final Map<ProtostreamId, ProtostreamPayload> loadedBulk = mapper.withinCacheEncodingContext( c -> {
  				//TODO getAll doesn't support versioned entries ?!
  				return c.getAll( convertedKeys );
  			} );
  
  			final List<Tuple> results = new ArrayList<>( keys.length );
  			for ( int i = 0; i < keys.length; i++ ) {
  				EntityKey originalKey = keys[i];
  				if ( originalKey == null ) {
  					results.add( null );
  					continue;
  				}
  				ProtostreamId protostreamId = keyConversionMatch.get( originalKey );
  				ProtostreamPayload payload = loadedBulk.get( protostreamId );
  				if ( payload == null ) {
  					results.add( null );
  					continue;
  				}
  				results.add( payload.toTuple( SnapshotType.UNKNOWN ) );
  			}
  			return results;
  		}
  	}