@Override
  public Collection<IGameMap> provide(final File file) throws FileNotFoundException, IOException {
    if (!file.exists())
      throw new FileNotFoundException(file.getAbsolutePath() + " does not exist.");

    Collection<File> filesToRead = new ArrayList<File>(1);

    if (!file.isDirectory()) {
      if (!file.getAbsolutePath().endsWith(TPBJGConfig.LEVEL_FILE_EXTENSION)) {
        throw new RuntimeException(file.getAbsolutePath() + " is not a XML file.");
      }
      filesToRead.add(file);
    } else
      filesToRead = FileUtils.listFiles(file, new String[] { TPBJGConfig.LEVEL_FILE_EXTENSION }, true);

    Collection<XMLGameMapDTO> dtos = new ArrayList<XMLGameMapDTO>();
    filesToRead.forEach(f -> {
      BufferedInputStream in = null;
      try {
        in = new BufferedInputStream(new FileInputStream(f), 8192);
        try {
          JAXBContext context = JAXBContext.newInstance(XMLGameMapDTO.class);
          Unmarshaller unmarshaller = context.createUnmarshaller();
          dtos.add((XMLGameMapDTO) unmarshaller.unmarshal(in));
        } catch (JAXBException e) {
          throw new IOException(e.getMessage() + ": Error reading map from " + TPBJGConfig.LEVEL_FILE_EXTENSION + " map file: "
              + f.getAbsolutePath(), e);
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        try {
          in.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });

    return dtos
        .stream()
        .map(
            dto -> {
              IGameMap m = new GameMap(dto.getId(), dto.getWidth(), dto.getHeight(), dto.getItems().stream()
                  .map(dtoi -> new Item(dtoi.getX(), dtoi.getY(), dtoi.getItemType())).collect(Collectors.<Item> toList()), dto
                  .getPlayerSpawns().stream().map(dtoi -> new int[] { dtoi.getX(), dtoi.getY() }).collect(Collectors.<int[]> toList()), dto
                  .getPlayerSpawns().stream().map(dtoi -> new int[] { dtoi.getGlassX(), dtoi.getGlassY() })
                  .collect(Collectors.<int[]> toList()));
              dto.getFields().forEach(f -> m.setField(f.getX(), f.getY(), f.getFieldType()));
              return m;
            }).collect(Collectors.toList());
  }