  @Nonnull
  @Override
  public Route.Handler apply(@Nonnull Route.Handler next) {
    return ctx -> {
      if (ctx.getRoute().isTransactional(enabledByDefault)) {
        SessionFactory sessionFactory = ctx.require(sessionFactoryKey);
        SessionProvider sessionProvider = ctx.require(sessionProviderKey);

        try (Session session = sessionProvider.newSession(sessionFactory.withOptions())) {
          ManagedSessionContext.bind(session);

          Object result;

          Transaction trx = null;
          try {
            trx = session.getTransaction();
            trx.begin();

            result = next.apply(ctx);

            if (trx.isActive()) {
              trx.commit();
            }
          } catch (Throwable ex) {
            if (trx != null && trx.isActive()) {
              trx.rollback();
            }
            throw SneakyThrows.propagate(ex);
          }

          ensureCompletion(session.getTransaction());

          return result;
        } finally {
          ManagedSessionContext.unbind(sessionFactory);
        }
      } else {
        return next.apply(ctx);
      }
    };
  }

  @Nonnull @Override public Route.Handler apply(@Nonnull Route.Handler next) {
    return sessionRequest.apply(ctx -> {
      if (ctx.getRoute().isTransactional(enabledByDefault)) {
        SessionFactory sessionFactory = ctx.require(sessionRequest.getSessionFactoryKey());
        Transaction trx = null;
        try {
          Session session = sessionFactory.getCurrentSession();
          trx = session.getTransaction();
          trx.begin();

          Object result = next.apply(ctx);

          if (trx.isActive()) {
            trx.commit();
          }

          return result;
        } catch (Throwable ex) {
          if (trx != null && trx.isActive()) {
            trx.rollback();
          }
          throw SneakyThrows.propagate(ex);
        }
      } else {
        return next.apply(ctx);
      }
    });
  }

Try With Resources try(Session session=sessionProvider.newSession(sessionFactory.withOptions())) in method public apply(next Route.Handler) : Route.Handler from class io.jooby.hibernate.TransactionalRequest


  @Nonnull @Override public Route.Handler apply(@Nonnull Route.Handler next) {
    return ctx -> {
      String origin = ctx.header("Origin").valueOrNull();
      if (origin != null) {
        if (!options.allowOrigin(origin)) {
          log.debug("denied origin: {}", origin);
          return ctx.send(StatusCode.FORBIDDEN);
        }
        log.debug("allowed origin: {}", origin);
        if (isPreflight(ctx)) {
          log.debug("handling preflight for: {}", origin);
          if (preflight(ctx, options, origin)) {
            return ctx;
          } else {
            log.debug("preflight for {} {} with origin: {} failed", ctx.header(AC_REQUEST_METHOD),
                ctx.getRequestURL(), origin);
            return ctx.send(StatusCode.FORBIDDEN);
          }
        } else {
          // OPTIONS?
          if (ctx.getMethod().equalsIgnoreCase(Router.OPTIONS)) {
            // handle normal OPTIONS
            String allow = Router.METHODS.stream()
                .flatMap(method -> allowMethod(ctx, method))
                .collect(Collectors.joining(","));
            ctx.setResponseHeader("Allow", allow);
            return ctx.send(StatusCode.OK);
          } else {
            log.debug("handling simple cors for: {}", origin);
            ctx.setResetHeadersOnError(false);
            simple(ctx, options, origin);
          }
        }
      }
      return next.apply(ctx);
    };
  }

  private static Context methodContext(Context ctx, String method) {
    return new ForwardingContext(ctx) {
      @Nonnull @Override public String getMethod() {
        return method;
      }
    };
  }

Replace Anonymous With Lambda io.jooby.CorsHandler.methodContext.new ForwardingContext with ctx -> {String origin=ctx.header("Origin").valueOrNull(); in method public apply(next Route.Handler) : Route.Handler from class io.jooby.CorsHandler


  public byte[] byteCode(String classname) {
    try (InputStream stream = loader.getResourceAsStream(classname.replace(".", "/") + ".class")) {
      if (stream == null) {
        throw new ClassNotFoundException(classname);
      }
      return IOUtils.toByteArray(stream);
    } catch (Exception x) {
      throw SneakyThrows.propagate(x);
    }
  }

  public byte[] byteCode(String classname) {
    try {
      Path classpath = classpath(classname);
      return Files.readAllBytes(classpath);
    } catch (IOException x) {
      throw SneakyThrows.propagate(x);
    }
  }

Try With Resources try(InputStream stream=loader.getResourceAsStream(classname.replace(".","/") + ".class")) in method public byteCode(classname String) : byte[] from class io.jooby.internal.openapi.ClassSource


  @Override public byte[] bytes() {
    try (InputStream in = stream()) {
      return in.readAllBytes();
    } catch (IOException x) {
      throw Throwing.sneakyThrow(x);
    }
  }

  @Override public byte[] bytes() {
    try {
      return Files.readAllBytes(upload.getPath());
    } catch (IOException x) {
      throw Throwing.sneakyThrow(x);
    }
  }

Try With Resources try(InputStream in=stream()) in method public bytes() : byte[] from class io.jooby.internal.utow.UtowFileUpload


  @Nonnull @Override public Context sendFile(@Nonnull FileChannel file) {
    try (FileChannel channel = file) {
      response.setLongContentLength(channel.size());
      return sendStream(Channels.newInputStream(file));
    } catch (IOException x) {
      throw Throwing.sneakyThrow(x);
    }
  }

  @Nonnull @Override public Context sendFile(@Nonnull FileChannel file) {
    try {
      response.setLongContentLength(file.size());
      if (!request.isAsyncStarted()) {
        request.startAsync();
      }
      response.getHttpOutput().sendContent(file, this);
      return this;
    } catch (IOException x) {
      throw Throwing.sneakyThrow(x);
    }
  }

Try With Resources try(FileChannel channel=file) in method public sendFile(file FileChannel) : Context from class io.jooby.internal.jetty.JettyContext


  @Nonnull @Override public Context outputStream(Throwing.Consumer<OutputStream> consumer)
      throws Exception {
    requireBlocking();
    if (!exchange.isBlocking()) {
      exchange.startBlocking();
    }
    try (OutputStream output = exchange.getOutputStream()) {
      consumer.accept(output);
    }
    return this;
  }

  @Nonnull @Override public Context outputStream(Throwing.Consumer<OutputStream> consumer) throws Exception {
    requireBlocking();
    if (!exchange.isBlocking()) {
      exchange.startBlocking();
    }
    OutputStream output = exchange.getOutputStream();
    try {
      consumer.accept(output);
    } finally {
      if (output != null) {
        output.close();
      }
    }
    return this;
  }

Try With Resources try(OutputStream output=exchange.getOutputStream()) in method public outputStream(consumer Throwing.Consumer<OutputStream>) : Context from class io.jooby.internal.utow.UtowContext


  /**
   * Gets type literal for the parameterized type represented by applying {@code typeArguments} to
   * {@code rawType}.
   */
  public static Reified<?> getParameterized(Type rawType, Type... typeArguments) {
    return new Reified<>($Types.newParameterizedTypeWithOwner(null, rawType, typeArguments));
  }

  /**
   * Gets type literal for the parameterized type represented by applying {@code typeArguments} to
   * {@code rawType}.
   */
  public static Reified<?> getParameterized(Type rawType, Type... typeArguments) {
    return new Reified<Object>($Types.newParameterizedTypeWithOwner(null, rawType, typeArguments));
  }

Replace Generic With Diamond Reified<Object> with Reified<> in method public getParameterized(rawType Type, typeArguments Type...) : Reified<?> from class io.jooby.Reified


  /**
   * Gets type literal for the array type whose elements are all instances of {@code componentType}.
   */
  public static Reified<?> getArray(Type componentType) {
    return new Reified<>($Types.arrayOf(componentType));
  }

  /**
   * Gets type literal for the array type whose elements are all instances of {@code componentType}.
   */
  public static Reified<?> getArray(Type componentType) {
    return new Reified<Object>($Types.arrayOf(componentType));
  }

Replace Generic With Diamond Reified<Object> with Reified<> in method public getArray(componentType Type) : Reified<?> from class io.jooby.Reified


  public Watcher(final BiConsumer<Kind<?>, Path> listener, final Path... dirs)
          throws IOException {
    this.watcher = FileSystems.getDefault().newWatchService();
    this.keys = new HashMap<>();
    this.listener = listener;
    for (Path dir : dirs) {
      registerAll(dir);
    }

    this.scanner = new Thread(() -> {
      boolean process = true;
      while (!stopped && process) {
        process = processEvents();
      }
    }, "HotswapScanner");

    scanner.setDaemon(true);
  }

  public Watcher(final BiConsumer<Kind<?>, Path> listener, final Path... dirs)
          throws IOException {
    this.watcher = FileSystems.getDefault().newWatchService();
    this.keys = new HashMap<WatchKey, Path>();
    this.listener = listener;
    for (Path dir : dirs) {
      registerAll(dir);
    }

    this.scanner = new Thread(() -> {
      boolean process = true;
      while (!stopped && process) {
        process = processEvents();
      }
    }, "HotswapScanner");

    scanner.setDaemon(true);
  }

Replace Generic With Diamond HashMap<WatchKey,Path> with HashMap<> in method public Watcher(listener BiConsumer<Kind<?>,Path>, dirs Path...) from class org.jooby.run.Watcher


  @SuppressWarnings("rawtypes")
  private static Optional<ObservableAdapter> toAdapter(final Function<Observable, Observable> fn) {
    return Optional.of(fn::apply);
  }

  @SuppressWarnings("rawtypes")
  private static Optional<ObservableAdapter> toAdapter(final Function<Observable, Observable> fn) {
    return Optional.of(new ObservableAdapter() {

      @SuppressWarnings("unchecked")
      @Override
      public <T> Observable<T> adapt(final Observable<T> observable) {
        return fn.apply(observable);
      }
    });
  }

Replace Anonymous With Lambda org.jooby.mongodb.MongoRx.toAdapter.of.new ObservableAdapter with fn::apply in method private toAdapter(fn Function<Observable,Observable>) : Optional<ObservableAdapter> from class org.jooby.mongodb.MongoRx


  private static ExecutorService executor(final String name) {
    AtomicInteger next = new AtomicInteger(0);
    return new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(),
        r -> {
          Thread thread = Executors.defaultThreadFactory().newThread(r);
          thread.setName(name + "-" + next.incrementAndGet());
          return thread;
        });
  }

  private static ExecutorService executor(final String name) {
    AtomicInteger next = new AtomicInteger(0);
    return new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
        r -> {
          Thread thread = Executors.defaultThreadFactory().newThread(r);
          thread.setName(name + "-" + next.incrementAndGet());
          return thread;
        });
  }

Replace Generic With Diamond ThreadPoolExecutor with ThreadPoolExecutor in method private executor(name String) : ExecutorService from class org.jooby.crash.CrashBootstrap


  private static List<MediaType> parseInternal(final String value) {
    String[] types = value.split(",");
    @SuppressWarnings("serial")
    List<MediaType> result = new ArrayList<>(types.length);
    for (String type : types) {
      String[] parts = type.trim().split(";");
      if (parts[0].equals("*")) {
        // odd and ugly media type
        result.add(all);
      } else {
        String[] typeAndSubtype = parts[0].split("/");
        if (typeAndSubtype.length != 2) {
          throw new Err.BadMediaType(value);
        }
        String stype = typeAndSubtype[0].trim();
        String subtype = typeAndSubtype[1].trim();
        if ("*".equals(stype) && !"*".equals(subtype)) {
          throw new Err.BadMediaType(value);
        }
        Map<String, String> parameters = DEFAULT_PARAMS;
        if (parts.length > 1) {
          parameters = new LinkedHashMap<>(DEFAULT_PARAMS);
          for (int i = 1; i < parts.length; i++) {
            String[] parameter = parts[i].split("=");
            if (parameter.length > 1) {
              parameters.put(parameter[0].trim(), parameter[1].trim().toLowerCase());
            }
          }
        }
        result.add(new MediaType(stype, subtype, parameters));
      }
    }
    if (result.size() > 1) {
      Collections.sort(result);
    }
    return result;
  }

  private static List<MediaType> parseInternal(final String value) {
    String[] types = value.split(",");
    @SuppressWarnings("serial")
    List<MediaType> result = new ArrayList<MediaType>(types.length) {
      int hc = 1;

      @Override
      public boolean add(final MediaType e) {
        hc = 31 * hc + e.hashCode();
        return super.add(e);
      }

      @Override
      public int hashCode() {
        return hc;
      }
    };
    for (String type : types) {
      String[] parts = type.trim().split(";");
      if (parts[0].equals("*")) {
        // odd and ugly media type
        result.add(all);
      } else {
        String[] typeAndSubtype = parts[0].split("/");
        if (typeAndSubtype.length != 2) {
          throw new Err.BadMediaType(value);
        }
        String stype = typeAndSubtype[0].trim();
        String subtype = typeAndSubtype[1].trim();
        if ("*".equals(stype) && !"*".equals(subtype)) {
          throw new Err.BadMediaType(value);
        }
        Map<String, String> parameters = DEFAULT_PARAMS;
        if (parts.length > 1) {
          parameters = new LinkedHashMap<>(DEFAULT_PARAMS);
          for (int i = 1; i < parts.length; i++) {
            String[] parameter = parts[i].split("=");
            if (parameter.length > 1) {
              parameters.put(parameter[0].trim(), parameter[1].trim().toLowerCase());
            }
          }
        }
        result.add(new MediaType(stype, subtype, parameters));
      }
    }
    if (result.size() > 1) {
      Collections.sort(result);
    }
    return result;
  }

Replace Generic With Diamond ArrayList<MediaType> with ArrayList<> in method private parseInternal(value String) : List<MediaType> from class org.jooby.MediaType


  private static Set<String> pkgs(final File file) throws IOException {
    if (file.exists()) {
      return pkgs(new FileReader(file));
    }
    return new LinkedHashSet<>();
  }

  private static Set<String> pkgs(final File file) throws IOException {
    if (file.exists()) {
      return pkgs(new FileReader(file));
    }
    return new LinkedHashSet<String>();
  }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method private pkgs(file File) : Set<String> from class org.jooby.run.AppModuleLoader


  private static Set<String> pkgs(final Reader reader) throws IOException {
    try (BufferedReader in = new BufferedReader(reader)) {
      Set<String> pkgs = new LinkedHashSet<>();
      String line = in.readLine();
      while (line != null) {
        pkgs.add(line.trim());
        line = in.readLine();
      }
      return pkgs;
    }
  }

  private static Set<String> pkgs(final Reader reader) throws IOException {
    try (BufferedReader in = new BufferedReader(reader)) {
      Set<String> pkgs = new LinkedHashSet<String>();
      String line = in.readLine();
      while (line != null) {
        pkgs.add(line.trim());
        line = in.readLine();
      }
      return pkgs;
    }
  }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method private pkgs(reader Reader) : Set<String> from class org.jooby.run.AppModuleLoader


  private Model definitions(final Type type, final BiConsumer<String, Model> definitions) {
    ModelConverters converter = ModelConverters.getInstance();
    final Property property = converter.readAsProperty(type);

    final Map<PropertyBuilder.PropertyId, Object> args = new EnumMap<>(
        PropertyBuilder.PropertyId.class);
    for (Map.Entry<String, Model> entry : converter.readAll(type).entrySet()) {
      definitions.accept(entry.getKey(), entry.getValue());
    }
    return PropertyBuilder.toModel(PropertyBuilder.merge(property, args));
  }

  private Model definitions(final Type type, final BiConsumer<String, Model> definitions) {
    ModelConverters converter = ModelConverters.getInstance();
    final Property property = converter.readAsProperty(type);

    final Map<PropertyBuilder.PropertyId, Object> args = new EnumMap<PropertyBuilder.PropertyId, Object>(
        PropertyBuilder.PropertyId.class);
    for (Map.Entry<String, Model> entry : converter.readAll(type).entrySet()) {
      definitions.accept(entry.getKey(), entry.getValue());
    }
    return PropertyBuilder.toModel(PropertyBuilder.merge(property, args));
  }

Replace Generic With Diamond EnumMap<PropertyBuilder.PropertyId,Object> with EnumMap<> in method private definitions(type Type, definitions BiConsumer<String,Model>) : Model from class org.jooby.internal.swagger.SwaggerBuilder


  private static PathMatcher pathMatcher(final String expressions) {
    List<PathMatcher> matchers = new ArrayList<>();
    for (String expression : expressions.split(File.pathSeparator)) {
      matchers.add(FileSystems.getDefault().getPathMatcher("glob:" + expression.trim()));
    }
    return new PathMatcher() {

      @Override
      public boolean matches(final Path path) {
        for (PathMatcher matcher : matchers) {
          if (matcher.matches(path)) {
            return true;
          }
        }
        return false;
      }

      @Override
      public String toString() {
        return "[" + expressions + "]";
      }
    };
  }

  private static PathMatcher pathMatcher(final String expressions) {
    List<PathMatcher> matchers = new ArrayList<PathMatcher>();
    for (String expression : expressions.split(File.pathSeparator)) {
      matchers.add(FileSystems.getDefault().getPathMatcher("glob:" + expression.trim()));
    }
    return new PathMatcher() {

      @Override
      public boolean matches(final Path path) {
        for (PathMatcher matcher : matchers) {
          if (matcher.matches(path)) {
            return true;
          }
        }
        return false;
      }

      @Override
      public String toString() {
        return "[" + expressions + "]";
      }
    };
  }

Replace Generic With Diamond ArrayList<PathMatcher> with ArrayList<> in method private pathMatcher(expressions String) : PathMatcher from class org.jooby.run.Main


  @SuppressWarnings("unchecked")
  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {

    Set<File> appcp = new LinkedHashSet<>();

    // public / config, etc..
    appcp.addAll(resources(mavenProject.getResources()));

    // target/classes
    appcp.add(new File(buildOutputDirectory));

    // references project
    Set<Artifact> references = references(mavenProject);
    Set<File> refbasedir = refbasedir(mavenProject, references);
    Set<File> refcp = refcp(refbasedir);
    appcp.addAll(refcp);

    // *.jar
    Set<Artifact> artifacts = new LinkedHashSet<Artifact>(mavenProject.getArtifacts());

    artifacts.forEach(artifact -> {
      if (!"pom".equals(artifact.getType())) {
        // ignore self reference
        appcp.add(new File(artifact.getFile().getAbsolutePath()));
      }
    });

    Set<File> classpath = new LinkedHashSet<>();

    File hotreload = extra(pluginArtifacts, "jooby-run").get();
    File jbossModules = extra(pluginArtifacts, "jboss-modules").get();
    classpath.add(hotreload);
    classpath.add(jbossModules);

    // prepare commands
    List<Command> cmds = new ArrayList<>();
    if (commands != null && commands.size() > 0) {
      cmds.addAll(this.commands);
    }

    // watch dir
    List<File> watchDirs = new ArrayList<>();
    watchDirs.add(mavenProject.getBasedir());
    watchDirs.addAll(refbasedir);
    if (this.watchDirs != null) {
      this.watchDirs.forEach(f -> watchDirs.add(new File(f)));
    }

    // includes/excludes pattern
    String includes = null;
    if (this.includes != null && this.includes.size() > 0) {
      includes = this.includes.stream().collect(Collectors.joining(File.pathSeparator));
    }
    String excludes = null;
    if (this.excludes != null && this.excludes.size() > 0) {
      excludes = this.excludes.stream().collect(Collectors.joining(File.pathSeparator));
    }
    String watchDirStr = watchDirs.stream().filter(File::exists)
        .map(File::getAbsolutePath)
        .collect(Collectors.joining(File.pathSeparator));
    // moduleId
    String mId = mavenProject.getGroupId() + "." + mavenProject.getArtifactId();

    // logback and application.version
    setLogback();
    System.setProperty("application.version", mavenProject.getVersion());

    // fork?
    Command runapp = fork
        ? new RunForkedApp(mavenProject.getBasedir(), debug, vmArgs, classpath, mId, mainClass,
            appcp, includes, excludes, watchDirStr)
        : new RunApp(mId, mainClass, appcp, includes, excludes, watchDirs);

    // run app at the end
    cmds.add(runapp);

    for (Command cmd : cmds) {
      cmd.setWorkdir(mavenProject.getBasedir());
      getLog().debug("cmd: " + cmd.debug());
    }

    Watcher watcher = setupCompiler(mavenProject, compiler, goal -> {
      maven.execute(DefaultMavenExecutionRequest.copy(session.getRequest())
          .setGoals(Arrays.asList(goal)));
    });

    ShutdownHook shutdownHook = new ShutdownHook(getLog(), cmds);
    shutdownHook.watcher = watcher;
    /**
     * Shutdown hook
     */
    Runtime.getRuntime().addShutdownHook(shutdownHook);

    if (watcher != null) {
      watcher.start();
    }

    /**
     * Start process
     */
    for (Command cmd : cmds) {
      try {
        getLog().debug("Starting process: " + cmd.debug());
        cmd.execute();
      } catch (Exception ex) {
        throw new MojoFailureException("Execution of " + cmd + " resulted in error", ex);
      }
    }

  }

  @SuppressWarnings("unchecked")
  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {

    Set<File> appcp = new LinkedHashSet<File>();

    // public / config, etc..
    appcp.addAll(resources(mavenProject.getResources()));

    // target/classes
    appcp.add(new File(buildOutputDirectory));

    // references project
    Set<Artifact> references = references(mavenProject);
    Set<File> refbasedir = refbasedir(mavenProject, references);
    Set<File> refcp = refcp(refbasedir);
    appcp.addAll(refcp);

    // *.jar
    Set<Artifact> artifacts = new LinkedHashSet<Artifact>(mavenProject.getArtifacts());

    artifacts.forEach(artifact -> {
      if (!"pom".equals(artifact.getType())) {
        // ignore self reference
        appcp.add(new File(artifact.getFile().getAbsolutePath()));
      }
    });

    Set<File> classpath = new LinkedHashSet<>();

    File hotreload = extra(pluginArtifacts, "jooby-run").get();
    File jbossModules = extra(pluginArtifacts, "jboss-modules").get();
    classpath.add(hotreload);
    classpath.add(jbossModules);

    // prepare commands
    List<Command> cmds = new ArrayList<>();
    if (commands != null && commands.size() > 0) {
      cmds.addAll(this.commands);
    }

    // watch dir
    List<File> watchDirs = new ArrayList<>();
    watchDirs.add(mavenProject.getBasedir());
    watchDirs.addAll(refbasedir);
    if (this.watchDirs != null) {
      this.watchDirs.forEach(f -> watchDirs.add(new File(f)));
    }

    // includes/excludes pattern
    String includes = null;
    if (this.includes != null && this.includes.size() > 0) {
      includes = this.includes.stream().collect(Collectors.joining(File.pathSeparator));
    }
    String excludes = null;
    if (this.excludes != null && this.excludes.size() > 0) {
      excludes = this.excludes.stream().collect(Collectors.joining(File.pathSeparator));
    }
    String watchDirStr = watchDirs.stream().filter(File::exists)
        .map(File::getAbsolutePath)
        .collect(Collectors.joining(File.pathSeparator));
    // moduleId
    String mId = mavenProject.getGroupId() + "." + mavenProject.getArtifactId();

    // logback and application.version
    setLogback();
    System.setProperty("application.version", mavenProject.getVersion());

    // fork?
    Command runapp = fork
        ? new RunForkedApp(mavenProject.getBasedir(), debug, vmArgs, classpath, mId, mainClass,
            appcp, includes, excludes, watchDirStr)
        : new RunApp(mId, mainClass, appcp, includes, excludes, watchDirs);

    // run app at the end
    cmds.add(runapp);

    for (Command cmd : cmds) {
      cmd.setWorkdir(mavenProject.getBasedir());
      getLog().debug("cmd: " + cmd.debug());
    }

    Watcher watcher = setupCompiler(mavenProject, compiler, goal -> {
      maven.execute(DefaultMavenExecutionRequest.copy(session.getRequest())
          .setGoals(Arrays.asList(goal)));
    });

    ShutdownHook shutdownHook = new ShutdownHook(getLog(), cmds);
    shutdownHook.watcher = watcher;
    /**
     * Shutdown hook
     */
    Runtime.getRuntime().addShutdownHook(shutdownHook);

    if (watcher != null) {
      watcher.start();
    }

    /**
     * Start process
     */
    for (Command cmd : cmds) {
      try {
        getLog().debug("Starting process: " + cmd.debug());
        cmd.execute();
      } catch (Exception ex) {
        throw new MojoFailureException("Execution of " + cmd + " resulted in error", ex);
      }
    }

  }

Replace Generic With Diamond LinkedHashSet<File> with LinkedHashSet<> in method public execute() : void from class org.jooby.JoobyMojo


  @SuppressWarnings("unchecked")
  @Test
  public void defaults() throws Exception {
    new MockUnit(Provider.class)
        .run(unit -> {
          new AuthSessionStore<>(unit.get(Provider.class));
        });
  }

  @SuppressWarnings("unchecked")
  @Test
  public void defaults() throws Exception {
    new MockUnit(Provider.class)
        .run(unit -> {
          new AuthSessionStore<UserProfile>(unit.get(Provider.class));
        });
  }

Replace Generic With Diamond AuthSessionStore<UserProfile> with AuthSessionStore<> in method public defaults() : void from class org.jooby.pac4j.AuthSessionStoreTest


  private static TypeConverter stringConstructorTypeConverter() {
    return (value, type) -> {
      Class<?> rawType = type.getRawType();
      try {
        if (rawType == Locale.class) {
          return new LocaleParamConverter().convert(type, new Object[] {value}, null);
        }
        return new StringConstructorParamConverter().convert(type, new Object[] {value}, null);
      } catch (Exception ex) {
        throw new IllegalStateException("Can't convert: " + value + " to " + type, ex);
      }
    };
  }

  private static TypeConverter stringConstructorTypeConverter() {
    return new TypeConverter() {

      @Override
      public Object convert(final String value, final TypeLiteral<?> type) {
        Class<?> rawType = type.getRawType();
        try {
          return rawType.getDeclaredConstructor(String.class).newInstance(value);
        } catch (NoSuchMethodException | SecurityException | InstantiationException
            | InvocationTargetException | IllegalAccessException ex) {
          throw new IllegalStateException("Invocation of " + rawType.getName() + "(String) failed",
              ex);
        }
      }
    };
  }

Replace Anonymous With Lambda org.jooby.internal.TypeConverters.stringConstructorTypeConverter.new TypeConverter with (value, type) -> {Class<?> rawType=type.getRawType(); in method private stringConstructorTypeConverter() : TypeConverter from class org.jooby.internal.TypeConverters


  public static Server build(final Config config, final RouteHandler routeHandler)
      throws Exception {
    // jetty URL charset
    System.setProperty("org.eclipse.jetty.util.UrlEncoded.charset",
        config.getString("application.charset"));
    System.setProperty("org.mortbay.log.class", Slf4jLog.class.getName());

    Server server = new Server();
    // stop is done from Jooby
    server.setStopAtShutdown(false);

    Config $ = config.getConfig("jetty");

    HttpConfiguration httpConfig = configure(new HttpConfiguration(), $);

    httpConfig.setSecurePort(config.getInt("application.securePort"));
    httpConfig.setSecureScheme("https");

    // HTTP connector
    ServerConnector http = configure(new ServerConnector(server, new HttpConnectionFactory(
        httpConfig)), $.getConfig("http"));
    http.setPort(config.getInt("application.port"));

    server.addConnector(http);

    String keystorePath = config.getString("ssl.keystore.path");
    Resource keystore = Resource.newClassPathResource(keystorePath);
    if (keystore == null || !keystore.exists()) {
      keystore = Resource.newResource(keystorePath);
    }

    if (keystore.exists()) {
      SslContextFactory sslContextFactory = new SslContextFactory();
      sslContextFactory.setKeyStoreResource(keystore);
      sslContextFactory.setKeyStorePassword(config.getString("ssl.keystore.password"));
      sslContextFactory.setKeyManagerPassword(config.getString("ssl.keymanager.password"));

      // get config from https if present and/or fallback to http
      HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
      httpsConfig.addCustomizer(new SecureRequestCustomizer());

      ServerConnector https = configure(new ServerConnector(server,
          new SslConnectionFactory(sslContextFactory, "HTTP/1.1"),
          new HttpConnectionFactory(httpsConfig)),
          $.getConfig("https"));
      https.setPort(config.getInt("application.securePort"));

      server.addConnector(https);
    }

    // contextPath
    String contextPath = config.getString("application.path");

    ContextHandler context = new ContextHandler(contextPath);
    JettyHandler handler = new JettyHandler(routeHandler, config);
    Injector injector = routeHandler.injector();
    Session.Definition sessionDef = injector.getInstance(Session.Definition.class);

    /**
     * Session configuration
     */
    Session.Store store = sessionDef.store();
    Session.Store forwardingStore = fwdStore(store);
    String secret = config.hasPath("application.secret")
        ? config.getString("application.secret") : null;
    JoobySessionManager sessionManager = new JoobySessionManager(forwardingStore, secret);
    Config $session = config.getConfig("application.session");

    // session cookie config
    SessionCookieConfig sessionCookieConfig = sessionManager.getSessionCookieConfig();
    org.jooby.Cookie.Definition cookieDef = sessionDef.cookie();
    sessionCookieConfig.setComment(cookieDef.comment()
        .orElse($session.hasPath("cookie.comment") ? $session.getString("cookie.path") : null)
        );
    sessionCookieConfig.setDomain(cookieDef.domain()
        .orElse($session.hasPath("cookie.domain") ? $session.getString("cookie.domain") : null)
        );
    sessionCookieConfig.setHttpOnly(cookieDef.httpOnly()
        .orElse($session.getBoolean("cookie.httpOnly"))
        );
    sessionCookieConfig.setMaxAge(cookieDef.maxAge()
        .orElse((int) duration($session, "cookie.maxAge", TimeUnit.SECONDS))
        );
    sessionCookieConfig.setName(cookieDef.name()
        .orElse($session.getString("cookie.name"))
        );
    sessionCookieConfig.setPath(cookieDef.path()
        .orElse($session.getString("cookie.path"))
        );
    sessionCookieConfig.setSecure(cookieDef.secure()
        .orElse($session.getBoolean("cookie.secure"))
        );

    // session timeout
    sessionManager.setMaxInactiveInterval(sessionDef.timeout().orElse(
        (int) duration($session, "timeout", TimeUnit.SECONDS))
        );

    sessionManager.setSaveInterval(sessionDef.saveInterval().orElse(
        (int) duration($session, "saveInterval", TimeUnit.SECONDS))
        );

    sessionManager.setPreserveOnStop(sessionDef.preserveOnStop().orElse(
        $session.getBoolean("preserveOnStop"))
        );

    handler.setSessionManager(sessionManager);

    /**
     * Web sockets
     */
    @SuppressWarnings("unchecked")
    Set<WebSocket.Definition> sockets = (Set<Definition>) injector.getInstance(Key.get(Types
        .setOf(WebSocket.Definition.class)));

    if (sockets.size() > 0) {
      WebSocketPolicy policy = configure(new WebSocketPolicy(WebSocketBehavior.SERVER),
          config.getConfig("jetty.ws.policy"));
      WebSocketServerFactory socketServerFactory = new WebSocketServerFactory(policy);
      socketServerFactory.setCreator((req, resp) -> {
     String path = req.getRequestPath();
     for (WebSocket.Definition socketDef : sockets) {
      Optional<WebSocket> matches = socketDef.matches(path);
      if (matches.isPresent()) {
        WebSocketImpl socket = (WebSocketImpl) matches.get();
        return new JettyWebSocketHandler(injector, config, socket);
      }
     }
     return null;
    });

      handler.addBean(socketServerFactory);
    }

    context.setHandler(handler);

    server.setHandler(context);

    server.addLifeCycleListener(new AbstractLifeCycleListener() {
      @Override
      public void lifeCycleStarted(final LifeCycle event) {
        StringBuilder buffer = new StringBuilder(routeHandler.toString());
        if (sockets.size() > 0) {
          buffer.append("\nweb sockets:\n");

          int verbMax = "WS".length(), routeMax = 0, consumesMax = 0, producesMax = 0;
          for (WebSocket.Definition socketDef : sockets) {
            routeMax = Math.max(routeMax, socketDef.pattern().length());

            consumesMax = Math.max(consumesMax, socketDef.consumes().toString().length());

            producesMax = Math.max(producesMax, socketDef.produces().toString().length());
          }

          String format = "  %-" + verbMax + "s %-" + routeMax + "s    %" + consumesMax + "s     %"
              + producesMax + "s\n";

          for (WebSocket.Definition socketDef : sockets) {
            buffer.append(String.format(format, "WS", socketDef.pattern(),
                socketDef.consumes(), socketDef.produces()));
          }
        }
        buffer.append("\nlistening on:\n");
        buffer.append("  http://localhost:").append(config.getInt("application.port"))
            .append(contextPath).append("\n");
        buffer.append("  https://localhost:").append(config.getInt("application.securePort"))
            .append(contextPath).append("\n");

        log.info("\nroutes:\n{}", buffer);
      }
    });

    return server;
  }

  public static Server build(final Config config, final RouteHandler routeHandler)
      throws Exception {
    // jetty URL charset
    System.setProperty("org.eclipse.jetty.util.UrlEncoded.charset",
        config.getString("application.charset"));
    System.setProperty("org.mortbay.log.class", Slf4jLog.class.getName());

    Server server = new Server();
    // stop is done from Jooby
    server.setStopAtShutdown(false);

    Config $ = config.getConfig("jetty");

    HttpConfiguration httpConfig = configure(new HttpConfiguration(), $);

    httpConfig.setSecurePort(config.getInt("application.securePort"));
    httpConfig.setSecureScheme("https");

    // HTTP connector
    ServerConnector http = configure(new ServerConnector(server, new HttpConnectionFactory(
        httpConfig)), $.getConfig("http"));
    http.setPort(config.getInt("application.port"));

    server.addConnector(http);

    String keystorePath = config.getString("ssl.keystore.path");
    Resource keystore = Resource.newClassPathResource(keystorePath);
    if (keystore == null || !keystore.exists()) {
      keystore = Resource.newResource(keystorePath);
    }

    if (keystore.exists()) {
      SslContextFactory sslContextFactory = new SslContextFactory();
      sslContextFactory.setKeyStoreResource(keystore);
      sslContextFactory.setKeyStorePassword(config.getString("ssl.keystore.password"));
      sslContextFactory.setKeyManagerPassword(config.getString("ssl.keymanager.password"));

      // get config from https if present and/or fallback to http
      HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
      httpsConfig.addCustomizer(new SecureRequestCustomizer());

      ServerConnector https = configure(new ServerConnector(server,
          new SslConnectionFactory(sslContextFactory, "HTTP/1.1"),
          new HttpConnectionFactory(httpsConfig)),
          $.getConfig("https"));
      https.setPort(config.getInt("application.securePort"));

      server.addConnector(https);
    }

    // contextPath
    String contextPath = config.getString("application.path");

    ContextHandler context = new ContextHandler(contextPath);
    JettyHandler handler = new JettyHandler(routeHandler, config);
    Injector injector = routeHandler.injector();
    Session.Definition sessionDef = injector.getInstance(Session.Definition.class);

    /**
     * Session configuration
     */
    Session.Store store = sessionDef.store();
    Session.Store forwardingStore = fwdStore(store);
    String secret = config.getString("application.secret");
    JoobySessionManager sessionManager = new JoobySessionManager(forwardingStore, secret);
    Config $session = config.getConfig("application.session");

    // session cookie config
    SessionCookieConfig sessionCookieConfig = sessionManager.getSessionCookieConfig();
    org.jooby.Cookie.Definition cookieDef = sessionDef.cookie();
    sessionCookieConfig.setComment(cookieDef.comment()
        .orElse($session.hasPath("cookie.comment") ? $session.getString("cookie.path") : null)
        );
    sessionCookieConfig.setDomain(cookieDef.domain()
        .orElse($session.hasPath("cookie.domain") ? $session.getString("cookie.domain") : null)
        );
    sessionCookieConfig.setHttpOnly(cookieDef.httpOnly()
        .orElse($session.getBoolean("cookie.httpOnly"))
        );
    sessionCookieConfig.setMaxAge(cookieDef.maxAge()
        .orElse((int) duration($session, "cookie.maxAge", TimeUnit.SECONDS))
        );
    sessionCookieConfig.setName(cookieDef.name()
        .orElse($session.getString("cookie.name"))
        );
    sessionCookieConfig.setPath(cookieDef.path()
        .orElse($session.getString("cookie.path"))
        );
    sessionCookieConfig.setSecure(cookieDef.secure()
        .orElse($session.getBoolean("cookie.secure"))
        );

    // session timeout
    sessionManager.setMaxInactiveInterval(sessionDef.timeout().orElse(
        (int) duration($session, "timeout", TimeUnit.SECONDS))
        );

    sessionManager.setSaveInterval(sessionDef.saveInterval().orElse(
        (int) duration($session, "saveInterval", TimeUnit.SECONDS))
        );

    sessionManager.setPreserveOnStop(sessionDef.preserveOnStop().orElse(
        $session.getBoolean("preserveOnStop"))
        );

    handler.setSessionManager(sessionManager);

    /**
     * Web sockets
     */
    @SuppressWarnings("unchecked")
    Set<WebSocket.Definition> sockets = (Set<Definition>) injector.getInstance(Key.get(Types
        .setOf(WebSocket.Definition.class)));

    if (sockets.size() > 0) {
      WebSocketPolicy policy = configure(new WebSocketPolicy(WebSocketBehavior.SERVER),
          config.getConfig("jetty.ws.policy"));
      WebSocketServerFactory socketServerFactory = new WebSocketServerFactory(policy);
      socketServerFactory.setCreator(new WebSocketCreator() {
        @Override
        public Object createWebSocket(final ServletUpgradeRequest req,
            final ServletUpgradeResponse resp) {
          String path = req.getRequestPath();
          for (WebSocket.Definition socketDef : sockets) {
            Optional<WebSocket> matches = socketDef.matches(path);
            if (matches.isPresent()) {
              WebSocketImpl socket = (WebSocketImpl) matches.get();
              return new JettyWebSocketHandler(injector, config, socket);
            }
          }
          return null;
        }
      });

      handler.addBean(socketServerFactory);
    }

    context.setHandler(handler);

    server.setHandler(context);

    server.addLifeCycleListener(new AbstractLifeCycleListener() {
      @Override
      public void lifeCycleStarted(final LifeCycle event) {
        StringBuilder buffer = new StringBuilder(routeHandler.toString());
        if (sockets.size() > 0) {
          buffer.append("\nweb sockets:\n");

          int verbMax = "WS".length(), routeMax = 0, consumesMax = 0, producesMax = 0;
          for (WebSocket.Definition socketDef : sockets) {
            routeMax = Math.max(routeMax, socketDef.pattern().length());

            consumesMax = Math.max(consumesMax, socketDef.consumes().toString().length());

            producesMax = Math.max(producesMax, socketDef.produces().toString().length());
          }

          String format = "  %-" + verbMax + "s %-" + routeMax + "s    %" + consumesMax + "s     %"
              + producesMax + "s\n";

          for (WebSocket.Definition socketDef : sockets) {
            buffer.append(String.format(format, "WS", socketDef.pattern(),
                socketDef.consumes(), socketDef.produces()));
          }
        }
        buffer.append("\nlistening on:\n");
        buffer.append("  http://localhost:").append(config.getInt("application.port"))
            .append(contextPath).append("\n");
        buffer.append("  https://localhost:").append(config.getInt("application.securePort"))
            .append(contextPath).append("\n");

        log.info("\nroutes:\n{}", buffer);
      }
    });

    return server;
  }

Replace Anonymous With Lambda org.jooby.internal.jetty.JettyServerBuilder.build.setCreator.new WebSocketCreator with (req, resp) -> {String path=req.getRequestPath(); in method public build(config Config, routeHandler RouteHandler) : Server from class org.jooby.internal.jetty.JettyServerBuilder


/**
   *
Bootstrap

   *

   * The bootstrap process is defined as follows:
   *

   *
1. Configuration files (first-listed are higher priority)

   *

   *
System properties

   *
Application properties: {@code application.conf} or custom, see {@link #use(Config)}

   *
{@link Jooby.Module Modules} properties

   *

   *
   *
2. Dependency Injection and {@link Jooby.Module modules}

   *

   *
An {@link Injector Guice Injector} is created.

   *
It calls to {@link Jooby.Module#configure(Env, Config, Binder)} for each module.

   *
At this point Guice is ready and all the services has been binded.

   *
It calls to {@link Jooby.Module#start() start method} for each module.

   *
A web server is started

   *

   *
   * @param args Application arguments.
   * @throws Exception If something fails to start.
   */
  public void start(final String[] args) throws Exception {
    Config config = buildConfig(
        Optional.ofNullable(this.source)
            .orElseGet(
                () -> ConfigFactory.parseResources("application.conf")
            )
        );
    Env env = this.env.build(config);

    // shutdown hook
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      stop();
    }));

    final Charset charset = Charset.forName(config.getString("application.charset"));

    String[] lang = config.getString("application.lang").split("_");
    final Locale locale = lang.length == 1 ? new Locale(lang[0]) : new Locale(lang[0], lang[1]);

    ZoneId zoneId = ZoneId.of(config.getString("application.tz"));
    DateTimeFormatter dateTimeFormat = DateTimeFormatter
        .ofPattern(config.getString("application.dateFormat"), locale)
        .withZone(zoneId);

    DecimalFormat numberFormat = new DecimalFormat(config.getString("application.numberFormat"));

    // Guice Stage
    Stage stage = env.when("dev", Stage.DEVELOPMENT).value().orElse(Stage.PRODUCTION);

    // dependency injection
    injector = Guice.createInjector(stage, (com.google.inject.Module) binder -> {

      TypeConverters.configure(binder);

      // bind config
      bindConfig(binder, config);

      // bind env
      binder.bind(Env.class).toInstance(env);

      // bind charset
      binder.bind(Charset.class).toInstance(charset);

      // bind locale
      binder.bind(Locale.class).toInstance(locale);

      // bind time zone
      binder.bind(ZoneId.class).toInstance(zoneId);
      binder.bind(TimeZone.class).toInstance(TimeZone.getTimeZone(zoneId));

      // bind date format
      binder.bind(DateTimeFormatter.class).toInstance(dateTimeFormat);

      // bind number format
      binder.bind(NumberFormat.class).toInstance(numberFormat);
      binder.bind(DecimalFormat.class).toInstance(numberFormat);

      // bind formatter & parser
      Multibinder parserBinder = Multibinder
          .newSetBinder(binder, Body.Parser.class);
      Multibinder formatterBinder = Multibinder
          .newSetBinder(binder, Body.Formatter.class);

      // session definition
      binder.bind(Session.Definition.class).toInstance(session);

      // Routes
      Multibinder<Route.Definition> definitions = Multibinder
          .newSetBinder(binder, Route.Definition.class);

      // Web Sockets
      Multibinder<WebSocket.Definition> sockets = Multibinder
          .newSetBinder(binder, WebSocket.Definition.class);

      // Request Modules
      Multibinder<Request.Module> requestModule = Multibinder
          .newSetBinder(binder, Request.Module.class);

      // bind prototype routes in request module
      if (protoRoutes.size() > 0) {
        requestModule.addBinding().toInstance(
            b -> protoRoutes.forEach(routeClass1 -> b.bind(routeClass1)));
      }

      // tmp dir
      File tmpdir = new File(config.getString("application.tmpdir"));
      tmpdir.mkdirs();
      binder.bind(File.class).annotatedWith(Names.named("application.tmpdir")).toInstance(tmpdir);

      // converters
      parsers.forEach(it1 -> parserBinder.addBinding().toInstance(it1));
      formatters.forEach(it2 -> formatterBinder.addBinding().toInstance(it2));

      RouteMetadata classInfo = new RouteMetadata(env);
      binder.bind(RouteMetadata.class).toInstance(classInfo);

      // modules, routes and websockets
      bag.forEach(candidate -> {
        if (candidate instanceof Jooby.Module) {
          install((Jooby.Module) candidate, env, config, binder);
        } else if (candidate instanceof Request.Module) {
          requestModule.addBinding().toInstance((Request.Module) candidate);
        } else if (candidate instanceof Route.Definition) {
          definitions.addBinding().toInstance((Route.Definition) candidate);
        } else if (candidate instanceof WebSocket.Definition) {
          sockets.addBinding().toInstance((WebSocket.Definition) candidate);
        } else {
          Routes.routes(env, classInfo, (Class<?>) candidate)
              .forEach(route -> definitions.addBinding().toInstance(route));
        }
      });

      // Singleton routes
      singletonRoutes.forEach(routeClass3 -> binder.bind(routeClass3).in(Scopes.SINGLETON));

      formatterBinder.addBinding().toInstance(BuiltinBodyConverter.formatReader);
      formatterBinder.addBinding().toInstance(BuiltinBodyConverter.formatStream);
      formatterBinder.addBinding().toInstance(BuiltinBodyConverter.formatAny);

      parserBinder.addBinding().toInstance(BuiltinBodyConverter.parseString);

      // err
      if (err == null) {
        binder.bind(Err.Handler.class).toInstance(new Err.Default());
      } else {
        binder.bind(Err.Handler.class).toInstance(err);
      }
    });

    // start modules
    for (Jooby.Module module : modules) {
      module.start();
    }

    // Start server
    Server server = injector.getInstance(Server.class);

    server.start();
  }

/**
   *
Bootstrap

   *

   * The bootstrap process is defined as follows:
   *

   *
1. Configuration files (first-listed are higher priority)

   *

   *
System properties

   *
Application properties: {@code application.conf} or custom, see {@link #use(Config)}

   *
{@link Jooby.Module Modules} properties

   *

   *
   *
2. Dependency Injection and {@link Jooby.Module modules}

   *

   *
An {@link Injector Guice Injector} is created.

   *
It calls to {@link Jooby.Module#configure(Env, Config, Binder)} for each module.

   *
At this point Guice is ready and all the services has been binded.

   *
It calls to {@link Jooby.Module#start() start method} for each module.

   *
A web server is started

   *

   *
   * @param args Application arguments.
   * @throws Exception If something fails to start.
   */
  public void start(final String[] args) throws Exception {
    Config config = buildConfig(
        Optional.ofNullable(this.source)
            .orElseGet(
                () -> ConfigFactory.parseResources("application.conf")
            )
        );
    Env env = this.env.build(config);

    // shutdown hook
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      stop();
    }));

    final Charset charset = Charset.forName(config.getString("application.charset"));

    String[] lang = config.getString("application.lang").split("_");
    final Locale locale = lang.length == 1 ? new Locale(lang[0]) : new Locale(lang[0], lang[1]);

    ZoneId zoneId = ZoneId.of(config.getString("application.tz"));
    DateTimeFormatter dateTimeFormat = DateTimeFormatter
        .ofPattern(config.getString("application.dateFormat"), locale)
        .withZone(zoneId);

    DecimalFormat numberFormat = new DecimalFormat(config.getString("application.numberFormat"));

    // Guice Stage
    Stage stage = env.when("dev", Stage.DEVELOPMENT).value().orElse(Stage.PRODUCTION);

    // dependency injection
    injector = Guice.createInjector(stage, new com.google.inject.Module() {
      @Override
      public void configure(final Binder binder) {

        TypeConverters.configure(binder);

        // bind config
        bindConfig(binder, config);

        // bind env
        binder.bind(Env.class).toInstance(env);

        // bind charset
        binder.bind(Charset.class).toInstance(charset);

        // bind locale
        binder.bind(Locale.class).toInstance(locale);

        // bind time zone
        binder.bind(ZoneId.class).toInstance(zoneId);
        binder.bind(TimeZone.class).toInstance(TimeZone.getTimeZone(zoneId));

        // bind date format
        binder.bind(DateTimeFormatter.class).toInstance(dateTimeFormat);

        // bind number format
        binder.bind(NumberFormat.class).toInstance(numberFormat);
        binder.bind(DecimalFormat.class).toInstance(numberFormat);

        // bind formatter & parser
        Multibinder parserBinder = Multibinder
            .newSetBinder(binder, Body.Parser.class);
        Multibinder formatterBinder = Multibinder
            .newSetBinder(binder, Body.Formatter.class);

        // session definition
        binder.bind(Session.Definition.class).toInstance(session);

        // Routes
        Multibinder<Route.Definition> definitions = Multibinder
            .newSetBinder(binder, Route.Definition.class);

        // Web Sockets
        Multibinder<WebSocket.Definition> sockets = Multibinder
            .newSetBinder(binder, WebSocket.Definition.class);

        // Request Modules
        Multibinder<Request.Module> requestModule = Multibinder
            .newSetBinder(binder, Request.Module.class);

        // bind prototype routes in request module
        if (protoRoutes.size() > 0) {
          requestModule.addBinding().toInstance(
              b -> protoRoutes.forEach(routeClass -> b.bind(routeClass)));
        }

        // tmp dir
        File tmpdir = new File(config.getString("application.tmpdir"));
        tmpdir.mkdirs();
        binder.bind(File.class).annotatedWith(Names.named("application.tmpdir")).toInstance(tmpdir);

        // converters
        parsers.forEach(it -> parserBinder.addBinding().toInstance(it));
        formatters.forEach(it -> formatterBinder.addBinding().toInstance(it));

        // modules, routes and websockets
        bag.forEach(candidate -> {
          if (candidate instanceof Jooby.Module) {
            install((Jooby.Module) candidate, env, config, binder);
          } else if (candidate instanceof Request.Module) {
            requestModule.addBinding().toInstance((Request.Module) candidate);
          } else if (candidate instanceof Route.Definition) {
            definitions.addBinding().toInstance((Route.Definition) candidate);
          } else if (candidate instanceof WebSocket.Definition) {
            sockets.addBinding().toInstance((WebSocket.Definition) candidate);
          } else {
            Class<?> routeClass = (Class<?>) candidate;
            Routes.routes(env, routeClass)
                .forEach(route -> definitions.addBinding().toInstance(route));
          }
        });

        // Singleton routes
        singletonRoutes.forEach(routeClass -> binder.bind(routeClass).in(Scopes.SINGLETON));

        formatterBinder.addBinding().toInstance(BuiltinBodyConverter.formatReader);
        formatterBinder.addBinding().toInstance(BuiltinBodyConverter.formatStream);
        formatterBinder.addBinding().toInstance(BuiltinBodyConverter.formatAny);

        parserBinder.addBinding().toInstance(BuiltinBodyConverter.parseString);

        // err
        if (err == null) {
          binder.bind(Err.Handler.class).toInstance(new Err.Default());
        } else {
          binder.bind(Err.Handler.class).toInstance(err);
        }
      }

    });

    // start modules
    for (Jooby.Module module : modules) {
      module.start();
    }

    // Start server
    Server server = injector.getInstance(Server.class);

    server.start();
  }

Replace Anonymous With Lambda org.jooby.Jooby.start.createInjector.new com.google.inject.Module with binder -> {TypeConverters.configure(binder); in method public start(args String[]) : void from class org.jooby.Jooby


  private List<Route> findRoutes(final Verb verb, final String path, final MediaType type,
      final List<MediaType> accept, final Verb overrideVerb) {

    List<Route> routes = new ArrayList<>();
    for (Route.Definition routeDef : routeDefs) {
      Optional<Route> route = routeDef.matches(verb, path, type, accept);
      if (route.isPresent()) {
        routes.add(verb.equals(overrideVerb) ? route.get()
            : overrideVerb(route.get(), overrideVerb));
      }
    }
    return routes;
  }

  private List<Route> findRoutes(final Verb verb, final String path, final MediaType type,
      final List<MediaType> accept, final Verb overrideVerb) {

    LinkedList<Route> routes = new LinkedList<Route>();
    for (Route.Definition routeDef : routeDefs) {
      Optional<Route> route = routeDef.matches(verb, path, type, accept);
      if (route.isPresent()) {
        routes.add(verb.equals(overrideVerb) ? route.get()
            : overrideVerb(route.get(), overrideVerb));
      }
    }
    return routes;
  }

Replace Generic With Diamond LinkedList<Route> with ArrayList<> in method private findRoutes(verb Verb, path String, type MediaType, accept List<MediaType>, overrideVerb Verb) : List<Route> from class org.jooby.internal.RouteHandler


  @Override
  protected Object createTest() throws Exception {
    Object test = super.createTest();
    Guice.createInjector(binder -> {
        binder.bind(Integer.class).annotatedWith(Names.named("jooby.http.port")).toInstance(port);
        binder.bind(Integer.class).annotatedWith(Names.named("port")).toInstance(port);
    }).injectMembers(test);

    return test;
  }

  @Override
  protected Object createTest() throws Exception {
    Object test = super.createTest();
    Guice.createInjector(new Module() {
      @Override
      public void configure(final Binder binder) {
        binder.bind(Integer.class).annotatedWith(Names.named("jooby.http.port")).toInstance(port);
        binder.bind(Integer.class).annotatedWith(Names.named("port")).toInstance(port);
      }
    }).injectMembers(test);
    ;
    return test;
  }

Replace Anonymous With Lambda jooby.JoobyRunner.createTest.injectMembers.createInjector.new Module with binder -> {binder.bind(Integer.class).annotatedWith(Names.named("jooby.http.port")).toInstance(port); in method protected createTest() : Object from class jooby.JoobyRunner


    public ArrayList<int[]> getListeVoisins()
    {
        int x = this.getX();
        int y = this.getY();
        ArrayList<int[]> listeVoisins = new ArrayList<>();
        listeVoisins.add(new int[]{x-1, y});
        listeVoisins.add(new int[]{x+1, y});
        listeVoisins.add(new int[]{x, y-1});
        listeVoisins.add(new int[]{x, y+1});
        for (int i=listeVoisins.size()-1; i>=0; i--)
            if ( !deplacementValide( listeVoisins.get(i)[0], listeVoisins.get(i)[1] ) )
                listeVoisins.remove(i);
        return listeVoisins;
    }

    public ArrayList<int[]> getListeVoisins()
    {
        int x = this.getX();
        int y = this.getY();
        ArrayList<int[]> listeVoisins = new ArrayList<int[]>();
        listeVoisins.add(new int[]{x-1, y});
        listeVoisins.add(new int[]{x+1, y});
        listeVoisins.add(new int[]{x, y-1});
        listeVoisins.add(new int[]{x, y+1});
        for (int i=listeVoisins.size()-1; i>=0; i--)
            if ( !deplacementValide( listeVoisins.get(i)[0], listeVoisins.get(i)[1] ) )
                listeVoisins.remove(i);
        return listeVoisins;
    }

Replace Generic With Diamond ArrayList<int[]> with ArrayList<> in method public getListeVoisins() : ArrayList<int[]> from class v2.Ant


	public static int getLastRowWithData(String filePath, String sheetName, String columnName) {
		try (FileInputStream file = new FileInputStream(new File(filePath));
			 Workbook workbook = WorkbookFactory.create(file)) {

			// Lấy sheet theo tên
			Sheet sheet = workbook.getSheet(sheetName);

			if (sheet == null) {
				throw new IllegalArgumentException("Sheet " + sheetName + " không tồn tại trong file Excel.");
			}

			// Tìm số dòng có dữ liệu cuối cùng
			return getLastRowWithData(sheet, columnName);

		} catch (IOException e) {
			System.err.println("Đã xảy ra lỗi khi xử lý file: " + e.getMessage());
			return -1;
		}
	}

	public static int getLastRowWithData(String filePath, String sheetName) {
		try {
			// Mở file Excel
			FileInputStream file = new FileInputStream(new File(filePath));

			// Tạo Workbook từ file Excel
			Workbook workbook = WorkbookFactory.create(file);

			// Lấy sheet theo tên
			Sheet sheet = workbook.getSheet(sheetName);

			if (sheet == null) {
				throw new IllegalArgumentException("Sheet " + sheetName + " không tồn tại trong file Excel.");
			}

			// Tìm số dòng có dữ liệu cuối cùng
			int lastRowWithData = getLastRowWithData(sheet);

			// Đóng workbook và file
			workbook.close();
			file.close();

			return lastRowWithData;

		} catch (IOException e) {
			System.err.println("Đã xảy ra lỗi khi xử lý file: " + e.getMessage());
			return -1;
		}
	}

Try With Resources try(FileInputStream file=new FileInputStream(new File(filePath)); Workbook workbook=WorkbookFactory.create(file)) in method public getLastRowWithData(filePath String, sheetName String, columnName String) : int from class helpers.ExcelHelper


    public void mergeItems(List<SegmentIterator> items, Segment output) {

        //reversed guarantees that the most recent data is kept when duplicate keys are found
        Collections.reverse(items);

        try (Records records = pool.empty()) {
            while (!items.isEmpty()) {
                List<SegmentIterator> segmentIterators = new ArrayList<>();
                Iterator<SegmentIterator> itit = items.iterator();
                while (itit.hasNext()) {
                    SegmentIterator seg = itit.next();
                    if (!seg.hasNext()) {
                        itit.remove();
                        continue;
                    }
                    segmentIterators.add(seg);
                }

                //single segment, drain it
                if (segmentIterators.size() == 1) {
                    SegmentIterator it = segmentIterators.get(0);
                    while (it.hasNext()) {
                        writeOut(records, output, it.next());
                    }
                } else {
                    Record nextEntry = getNextEntry(segmentIterators);
                    writeOut(records, output, nextEntry);
                }
            }
            doWrite(records, output);
        }
    }

    public void mergeItems(List<SegmentIterator> items, Segment output) {

        //reversed guarantees that the most recent data is kept when duplicate keys are found
        Collections.reverse(items);

        try {
            while (!items.isEmpty()) {
                List<SegmentIterator> segmentIterators = new ArrayList<>();
                Iterator<SegmentIterator> itit = items.iterator();
                while (itit.hasNext()) {
                    SegmentIterator seg = itit.next();
                    if (!seg.hasNext()) {
                        itit.remove();
                        continue;
                    }
                    segmentIterators.add(seg);
                }

                //single segment, drain it
                if (segmentIterators.size() == 1) {
                    SegmentIterator it = segmentIterators.get(0);
                    while (it.hasNext()) {
                        writeOut(output, it.next());
                    }
                } else {
                    Record nextEntry = getNextEntry(segmentIterators);
                    writeOut(output, nextEntry);
                }
            }
            doWrite(output);
        } finally {
            records.close();
        }
    }

Try With Resources try(Records records=pool.empty()) in method public mergeItems(items List<SegmentIterator>, output Segment) : void from class io.joshworks.ilog.compaction.combiner.UniqueMergeCombiner


    Lsm(File root,
        RowKey rowKey,
        int memTableMaxSizeInBytes,
        int memTableMaxEntries,
        boolean directBuffers,
        int blockSize,
        long maxAge,
        int compactionThreads,
        int compactionThreshold,
        Codec codec) throws IOException {

        FileUtils.createDir(root);
        this.maxAge = maxAge;
        this.rowKey = rowKey;

        this.blockPool = new ObjectPool<>(100, p -> new HeapBlock(p, blockSize, rowKey, directBuffers, codec));

//        int maxRecordSize = Record2.HEADER_BYTES + comparator.keySize() + blockSize;
        int maxRecordSize = 36 + rowKey.keySize() + blockSize;

        this.recordPool = BufferPool.localCachePool(256, maxRecordSize, directBuffers);
        BufferPool logRecordPool = BufferPool.localCachePool(256, maxRecordSize, directBuffers);

//        int sstableIndexSize = memTableMaxEntries * (keySize + Long.BYTES); //key + pos
        int sstableIndexSize = memTableMaxSizeInBytes; // FIXME this needs to be properly calculated
        int tlogIndexSize = sstableIndexSize * 4;

        this.memTable = new MemTable(memTableMaxEntries);

        this.tlog = new Log<>(
                new File(root, LOG_DIR),
                tlogIndexSize,
                2,
                1,
                FlushMode.ON_ROLL,
                RowKey.LONG,
                IndexedSegment::new);

        this.ssTables = new Log<>(new File(root, SSTABLES_DIR),
                sstableIndexSize,
                compactionThreshold,
                compactionThreads,
                FlushMode.ON_ROLL,
                rowKey,
                IndexedSegment::new);
    }

    Lsm(File root,
        RowKey rowKey,
        int memTableMaxSizeInBytes,
        int memTableMaxEntries,
        boolean directBuffers,
        int blockSize,
        long maxAge,
        int compactionThreads,
        int compactionThreshold,
        Codec codec) throws IOException {

        FileUtils.createDir(root);
        this.maxAge = maxAge;
        this.rowKey = rowKey;

        this.blockPool = new ObjectPool<>(100, p -> new HeapBlock(p, blockSize, rowKey, directBuffers, codec));

//        int maxRecordSize = Record2.HEADER_BYTES + comparator.keySize() + blockSize;
        int maxRecordSize = 36 + rowKey.keySize() + blockSize;

        this.recordPool = BufferPool.localCachePool(256, maxRecordSize, directBuffers);
        BufferPool logRecordPool = BufferPool.localCachePool(256, maxRecordSize, directBuffers);

//        int sstableIndexSize = memTableMaxEntries * (keySize + Long.BYTES); //key + pos
        int sstableIndexSize = memTableMaxSizeInBytes; // FIXME this needs to be properly calculated
        int tlogIndexSize = sstableIndexSize * 4;

        this.memTable = new MemTable(memTableMaxEntries);

        this.tlog = new Log<IndexedSegment>(
                new File(root, LOG_DIR),
                tlogIndexSize,
                2,
                1,
                FlushMode.ON_ROLL,
                RowKey.LONG,
                IndexedSegment::new);

        this.ssTables = new Log<>(new File(root, SSTABLES_DIR),
                sstableIndexSize,
                compactionThreshold,
                compactionThreads,
                FlushMode.ON_ROLL,
                rowKey,
                SSTable::new);
    }

Replace Generic With Diamond Log<IndexedSegment> with Log<> in method package Lsm(root File, rowKey RowKey, memTableMaxSizeInBytes int, memTableMaxEntries int, directBuffers boolean, blockSize int, maxAge long, compactionThreads int, compactionThreshold int, codec Codec) from class io.joshworks.ilog.lsm.Lsm


    public int get(ByteBuffer key, ByteBuffer dst) {
        return ssTables.apply(Direction.BACKWARD, sst -> {

            int fromMem = memTable.apply(key, dst, IndexFunctions.EQUALS);
            if (fromMem > 0) {
                return fromMem;
            }

            var record = recordPool.allocate();
            try (HeapBlock block = blockPool.allocate()) {
                for (SSTable ssTable : sst) {
                    record.clear();
                    if (!ssTable.readOnly()) {
                        block.clear();
                        continue;
                    }
                    int read = ssTable.find(key, record, IndexFunctions.FLOOR);
                    if (read > 0) {
                        record.flip();
                        int entrySize = readFromBlock(key, block, record, dst, IndexFunctions.EQUALS);
                        if (entrySize <= 0) {// not found in the block, continue
                            block.clear();
                            continue;
                        }
                        return entrySize;
                    }
                }
                return 0;
            } finally {
                recordPool.free(record);
            }
        });
    }

    public int get(ByteBuffer key, ByteBuffer dst) {
        return ssTables.apply(Direction.BACKWARD, sst -> {
            int fromMem = memTable.apply(key, dst, IndexFunctions.EQUALS);
            if (fromMem > 0) {
                return fromMem;
            }

            var record = recordPool.allocate();
            try {
                for (SSTable ssTable : sst) {
                    record.clear();
                    if (!ssTable.readOnly()) {
                        continue;
                    }
                    int read = ssTable.find(key, record, IndexFunctions.FLOOR);
                    if (read > 0) {
                        record.flip();
                        int entrySize = readFromBlock(key, heapBlock, record, dst, IndexFunctions.EQUALS);
                        if (entrySize <= 0) {// not found in the block, continue
                            continue;
                        }
                        return entrySize;
                    }
                }
                return 0;
            } finally {
                recordPool.free(record);
            }
        });
    }

Try With Resources try(HeapBlock block=blockPool.allocate()) in method public get(key ByteBuffer, dst ByteBuffer) : int from class io.joshworks.ilog.lsm.Lsm


    @Override
    public void handleEvent(ConduitStreamSourceChannel channel) {
        try (appBuffer) {
            ByteBuffer buffer = appBuffer.allocate();
            int read;
            while ((read = channel.read(buffer)) > 0) {
                buffer.flip();
                handle(tcpConnection, buffer);
                buffer.clear();
            }
            if (read == -1) {
                IoUtils.safeClose(channel);
            }

        } catch (Exception e) {
            logger.warn("Error while reading message", e);
            IoUtils.safeClose(channel);
        }
    }

    @Override
    public void handleEvent(ConduitStreamSourceChannel channel) {
        try {
            if (!channel.isOpen()) {
                tcpConnection.close();
                return;
            }
            SimpleBufferPool.BufferRef ref = appBuffer.allocateRef();
            int read = channel.read(ref.buffer);
            if (read == 0) {
                return;
            }
            if (read == -1) {
                tcpConnection.close();
                return;
            }
            ref.buffer.flip();
            handle(tcpConnection, ref);
            channel.resumeReads();
        } catch (Exception e) {
            logger.warn("Error while reading message", e);
            IoUtils.safeClose(channel);
        }
    }

Try With Resources try(appBuffer) in method public handleEvent(channel ConduitStreamSourceChannel) : void from class io.joshworks.eventry.network.tcp.ReadHandler


    @Override
    public <T> RecordEntry<T> read(Storage storage, final long position, Serializer<T> serializer) {
        try (bufferPool) {
            ByteBuffer buffer = bufferPool.allocate(pageReadSize);
            int limit = buffer.limit();
            if (position - limit < Log.START) {
                int available = (int) (position - Log.START);
                if (available == 0) {
                    return RecordEntry.empty();
                }
                buffer.limit(available);
                limit = available;
            }

            storage.read(position - limit, buffer);
            buffer.flip();
            if (buffer.remaining() == 0) {
                return RecordEntry.empty();
            }

            int recordDataEnd = buffer.limit() - RecordHeader.SECONDARY_HEADER;
            int length = buffer.getInt(recordDataEnd);
            if (length == 0) {
                return RecordEntry.empty();
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;

            if (recordSize > buffer.limit()) {
                bufferPool.free();
                buffer = bufferPool.allocate(recordSize);

                buffer.limit(recordSize - RecordHeader.SECONDARY_HEADER); //limit to the entry size, excluding the secondary header
                long readStart = position - recordSize;
                storage.read(readStart, buffer);
                buffer.flip();

                int foundLength = buffer.getInt();
                return readRecord(position, serializer, buffer, foundLength);
            }

            buffer.limit(recordDataEnd);
            buffer.position(recordDataEnd - length - RecordHeader.CHECKSUM_SIZE);
            return readRecord(position, serializer, buffer, length);

        } finally {
            bufferPool.free();
        }

    }

    @Override
    public <T> RecordEntry<T> read(Storage storage, final long position, Serializer<T> serializer) {
        ByteBuffer buffer = bufferPool.allocate(pageReadSize);
        try {
            int limit = buffer.limit();
            if (position - limit < Log.START) {
                int available = (int) (position - Log.START);
                if (available == 0) {
                    return RecordEntry.empty();
                }
                buffer.limit(available);
                limit = available;
            }

            storage.read(position - limit, buffer);
            buffer.flip();
            if (buffer.remaining() == 0) {
                return RecordEntry.empty();
            }

            int recordDataEnd = buffer.limit() - RecordHeader.SECONDARY_HEADER;
            int length = buffer.getInt(recordDataEnd);
            if (length == 0) {
                return RecordEntry.empty();
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;

            if (recordSize > buffer.limit()) {
                bufferPool.free(buffer);
                buffer = bufferPool.allocate(recordSize);

                buffer.limit(recordSize - RecordHeader.SECONDARY_HEADER); //limit to the entry size, excluding the secondary header
                long readStart = position - recordSize;
                storage.read(readStart, buffer);
                buffer.flip();

                int foundLength = buffer.getInt();
                return readRecord(position, serializer, buffer, foundLength);
            }

            buffer.limit(recordDataEnd);
            buffer.position(recordDataEnd - length - RecordHeader.CHECKSUM_SIZE);
            return readRecord(position, serializer, buffer, length);

        } finally {
            bufferPool.free(buffer);
        }

    }

Try With Resources try(bufferPool) in method public read(storage Storage, position long, serializer Serializer<T>) : RecordEntry<T> from class io.joshworks.fstore.log.record.BackwardRecordReader


    @Override
    public <T> List<RecordEntry<T>> read(Storage storage, final long position, Serializer<T> serializer) {

        List<RecordEntry<T>> entries = new ArrayList<>();

        try (bufferPool) {
            ByteBuffer buffer = bufferPool.allocate(pageReadSize);
            int limit = buffer.limit();
            if (position - limit < Log.START) {
                int available = (int) (position - Log.START);
                if (available == 0) {
                    return entries;
                }
                buffer.limit(available);
                limit = available;
            }

            storage.read(position - limit, buffer);
            buffer.flip();
            if (buffer.remaining() == 0) {
                return entries;
            }

            int recordDataEnd = buffer.limit() - RecordHeader.SECONDARY_HEADER;
            int length = buffer.getInt(recordDataEnd);
            if (length == 0) {
                return entries;
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;

            if (recordSize > buffer.limit()) {
                bufferPool.free();
                buffer = bufferPool.allocate(recordSize);

                buffer.limit(recordSize); //limit to the entry size, excluding the secondary header
                long readStart = position - recordSize;
                if (readStart < 0) {
                    throw new IllegalStateException("Read start < 0: " + readStart + " position: " + position + " recordSize: " + recordSize);
                }
                storage.read(readStart, buffer);
                buffer.flip();
            }

            int originalLimit = buffer.limit();
            while (true) {
                buffer.limit(originalLimit);
                buffer.position(originalLimit);

                int len = buffer.getInt(originalLimit - RecordHeader.SECONDARY_HEADER);
                int recordStart = originalLimit - len - RecordHeader.HEADER_OVERHEAD;
                if (recordStart < 0) {
                    return entries;
                }
                buffer.position(originalLimit - len - RecordHeader.HEADER_OVERHEAD);

                int pos = buffer.position();
                if (len == 0 || buffer.remaining() < len + RecordHeader.CHECKSUM_SIZE) {
                    return entries;
                }

                buffer.getInt();//skip length
                int checksum = buffer.getInt();
                buffer.limit(buffer.position() + len);
                checksum(checksum, buffer, position + pos);
                T entry = serializer.fromBytes(buffer);
                entries.add(new RecordEntry<>(len, entry, position));

                originalLimit = pos;

                if (originalLimit - RecordHeader.SECONDARY_HEADER <= 0) {
                    return entries;
                }
            }
        }
    }

    @Override
    public <T> List<RecordEntry<T>> read(Storage storage, final long position, Serializer<T> serializer) {
        ByteBuffer buffer = bufferPool.allocate(pageReadSize);

        List<RecordEntry<T>> entries = new ArrayList<>();

        try {
            int limit = buffer.limit();
            if (position - limit < Log.START) {
                int available = (int) (position - Log.START);
                if (available == 0) {
                    return entries;
                }
                buffer.limit(available);
                limit = available;
            }

            storage.read(position - limit, buffer);
            buffer.flip();
            if (buffer.remaining() == 0) {
                return entries;
            }

            int recordDataEnd = buffer.limit() - RecordHeader.SECONDARY_HEADER;
            int length = buffer.getInt(recordDataEnd);
            if (length == 0) {
                return entries;
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;

            if (recordSize > buffer.limit()) {
                bufferPool.free(buffer);
                buffer = bufferPool.allocate(recordSize);

                buffer.limit(recordSize); //limit to the entry size, excluding the secondary header
                long readStart = position - recordSize;
                if (readStart < 0) {
                    throw new IllegalStateException("Read start < 0: " + readStart + " position: " + position + " recordSize: " + recordSize);
                }
                storage.read(readStart, buffer);
                buffer.flip();
            }

            int originalLimit = buffer.limit();
            while (true) {
                buffer.limit(originalLimit);
                buffer.position(originalLimit);

                int len = buffer.getInt(originalLimit - RecordHeader.SECONDARY_HEADER);
                int recordStart = originalLimit - len - RecordHeader.HEADER_OVERHEAD;
                if (recordStart < 0) {
                    return entries;
                }
                buffer.position(originalLimit - len - RecordHeader.HEADER_OVERHEAD);

                int pos = buffer.position();
                if (len == 0 || buffer.remaining() < len + RecordHeader.CHECKSUM_SIZE) {
                    return entries;
                }

                buffer.getInt();//skip length
                int checksum = buffer.getInt();
                buffer.limit(buffer.position() + len);
                checksum(checksum, buffer, position + pos);
                T entry = serializer.fromBytes(buffer);
                entries.add(new RecordEntry<>(len, entry, position));

                originalLimit = pos;

                if (originalLimit - RecordHeader.SECONDARY_HEADER <= 0) {
                    return entries;
                }
            }
        } finally {
            bufferPool.free(buffer);
        }

    }

Try With Resources try(bufferPool) in method public read(storage Storage, position long, serializer Serializer<T>) : List<RecordEntry<T>> from class io.joshworks.fstore.log.record.BulkBackwardRecordReader


    @Override
    public <T> List<RecordEntry<T>> read(Storage storage, final long position, Serializer<T> serializer) {
        final List<RecordEntry<T>> entries = new ArrayList<>();
        try (bufferPool) {
            ByteBuffer buffer = bufferPool.allocate(pageReadSize);
            storage.read(position, buffer);
            buffer.flip();

            if (buffer.remaining() < RecordHeader.MAIN_HEADER) {
                return entries;
            }

            int length = buffer.getInt();
            if (length == 0) {
                return entries;
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;
            if (recordSize > buffer.limit()) {
                bufferPool.free();
                buffer = bufferPool.allocate(recordSize);
                storage.read(position, buffer);
                buffer.flip();
                buffer.getInt(); //skip length
            }

            buffer.position(buffer.position() - Integer.BYTES);
            int originalLimit = buffer.limit();
            while (buffer.hasRemaining() && buffer.remaining() > RecordHeader.MAIN_HEADER) {
                int pos = buffer.position();
                int len = buffer.getInt();
                if (len == 0 || buffer.remaining() < len + RecordHeader.CHECKSUM_SIZE) {
                    return entries;
                }

                int checksum = buffer.getInt();
                buffer.limit(buffer.position() + len);
                checksum(checksum, buffer, position + pos);

                T entry = serializer.fromBytes(buffer);
                entries.add(new RecordEntry<>(len, entry, position + pos));

                int newPos = pos + len + RecordHeader.HEADER_OVERHEAD;
                newPos = Math.min(originalLimit, newPos);
                buffer.limit(originalLimit);
                if (newPos > buffer.limit()) {
                    return entries;
                }
                buffer.position(newPos);
            }
            return entries;
        }
    }

    @Override
    public <T> List<RecordEntry<T>> read(Storage storage, final long position, Serializer<T> serializer) {
        ByteBuffer buffer = bufferPool.allocate(pageReadSize);

        final List<RecordEntry<T>> entries = new ArrayList<>();

        try {
            storage.read(position, buffer);
            buffer.flip();

            if (buffer.remaining() < RecordHeader.MAIN_HEADER) {
                return entries;
            }

            int length = buffer.getInt();
            if (length == 0) {
                return entries;
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;
            if (recordSize > buffer.limit()) {
                bufferPool.free(buffer);
                buffer = bufferPool.allocate(recordSize);
                storage.read(position, buffer);
                buffer.flip();
                buffer.getInt(); //skip length
            }

            buffer.position(buffer.position() - Integer.BYTES);
            int originalLimit = buffer.limit();
            while (buffer.hasRemaining() && buffer.remaining() > RecordHeader.MAIN_HEADER) {
                int pos = buffer.position();
                int len = buffer.getInt();
                if (len == 0 || buffer.remaining() < len + RecordHeader.CHECKSUM_SIZE) {
                    return entries;
                }

                int checksum = buffer.getInt();
                buffer.limit(buffer.position() + len);
                checksum(checksum, buffer, position + pos);

                T entry = serializer.fromBytes(buffer);
                entries.add(new RecordEntry<>(len, entry, position + pos));

                int newPos = pos + len + RecordHeader.HEADER_OVERHEAD;
                newPos = Math.min(originalLimit, newPos);
                buffer.limit(originalLimit);
                if (newPos > buffer.limit()) {
                    return entries;
                }
                buffer.position(newPos);
            }
            return entries;
        } finally {
            bufferPool.free(buffer);
        }
    }

Try With Resources try(bufferPool) in method public read(storage Storage, position long, serializer Serializer<T>) : List<RecordEntry<T>> from class io.joshworks.fstore.log.record.BulkForwardRecordReader


    public <T> long write(long position, T entry, Serializer<T> serializer) {
        try (bufferPool) {
            ByteBuffer dst = bufferPool.allocate();
            serialize(entry, serializer, dst);
            long recordLen = dst.remaining();
            long written = storage.write(position, dst);
            checkWrittenBytes(recordLen, written);
            return position;
        }
    }

    public <T> long write(long position, T entry, Serializer<T> serializer, long maxEntrySize) {
        ByteBuffer writeBuffer = null;
        try {
            writeBuffer = writeToBuffer(entry, serializer, maxEntrySize);
            if (writeBuffer == null || writeBuffer.remaining() > maxEntrySize) {
                return Storage.EOF;
            }
            long recordLen = writeBuffer.remaining();
            long written = storage.write(position, writeBuffer);
            checkWrittenBytes(recordLen, written);

            return position;
        } finally {
            if (writeBuffer != null) {
                bufferPool.free(writeBuffer);
            }
        }
    }

Try With Resources try(bufferPool) in method public write(position long, entry T, serializer Serializer<T>) : long from class io.joshworks.fstore.log.record.DataStream


    public <T> long write(T entry, Serializer<T> serializer) {
        try (bufferPool) {
            ByteBuffer dst = bufferPool.allocate();
            serialize(entry, serializer, dst);
            long recordLen = dst.remaining();
            long storagePos = storage.position();
            long written = storage.write(dst);
            checkWrittenBytes(recordLen, written);
            return storagePos;
        }
    }

    public <T> long write(T entry, Serializer<T> serializer, long maxEntrySize) {
        ByteBuffer writeBuffer = null;
        try {
            writeBuffer = writeToBuffer(entry, serializer, maxEntrySize);
            if (writeBuffer == null || writeBuffer.remaining() > maxEntrySize) {
                return Storage.EOF;
            }
            long recordLen = writeBuffer.remaining();
            long storagePos = storage.position();
            long written = storage.write(writeBuffer);
            checkWrittenBytes(recordLen, written);

            return storagePos;
        } finally {
            if (writeBuffer != null) {
                bufferPool.free(writeBuffer);
            }
        }
    }

Try With Resources try(bufferPool) in method public write(entry T, serializer Serializer<T>) : long from class io.joshworks.fstore.log.record.DataStream


    @Override
    public <T> RecordEntry<T> read(Storage storage, final long position, Serializer<T> serializer) {
        try (bufferPool) {
            ByteBuffer buffer = bufferPool.allocate(pageReadSize);
            int read = storage.read(position, buffer);
            if (read == Storage.EOF) {
                return RecordEntry.empty();
            }
            buffer.flip();

            if (buffer.remaining() < RecordHeader.MAIN_HEADER) {
                return RecordEntry.empty();
            }

            int length = buffer.getInt();
            if (length == 0) {
                return RecordEntry.empty();
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;
            if (recordSize > buffer.limit()) {
                bufferPool.free();
                buffer = bufferPool.allocate(recordSize);
                storage.read(position, buffer);
                buffer.flip();
                buffer.getInt(); //skip length
            }

            int checksum = buffer.getInt();
            buffer.limit(buffer.position() + length);
            checksum(checksum, buffer, position);
            T data = serializer.fromBytes(buffer);
            return new RecordEntry<>(length, data, position);
        }
    }

    @Override
    public <T> RecordEntry<T> read(Storage storage, final long position, Serializer<T> serializer) {
        ByteBuffer buffer = bufferPool.allocate(pageReadSize);
        try {
            int read = storage.read(position, buffer);
            if (read == Storage.EOF) {
                return RecordEntry.empty();
            }
            buffer.flip();

            if (buffer.remaining() < RecordHeader.MAIN_HEADER) {
                return RecordEntry.empty();
            }

            int length = buffer.getInt();
            if (length == 0) {
                return RecordEntry.empty();
            }

            int recordSize = length + RecordHeader.HEADER_OVERHEAD;
            if (recordSize > buffer.limit()) {
                bufferPool.free(buffer);
                buffer = bufferPool.allocate(recordSize);
                storage.read(position, buffer);
                buffer.flip();
                buffer.getInt(); //skip length
            }

            int checksum = buffer.getInt();
            buffer.limit(buffer.position() + length);
            checksum(checksum, buffer, position);
            T data = serializer.fromBytes(buffer);
            return new RecordEntry<>(length, data, position);
        } finally {
            bufferPool.free(buffer);
        }
    }

Try With Resources try(bufferPool) in method public read(storage Storage, position long, serializer Serializer<T>) : RecordEntry<T> from class io.joshworks.fstore.log.record.ForwardRecordReader


    public <R> R acquireSegments(Direction direction, Function<LogIterator<Log<T>>, R> function) {
        int retries = 0;
        do {
            try (LogIterator<Log<T>> segments = levels.segments(direction)) {
                return function.apply(segments);
            } catch (Exception e) {
                logger.warn("Failed to acquire segments", e);
            }
            retries++;

        } while (retries < 10);

        throw new RuntimeException("Failed to acquire segment after " + retries + " retries");
    }

    public <R> R acquireSegments(Direction direction, Function<LogIterator<Log<T>>, R> function) {
        int retries = 0;
        do {
            try {
                LogIterator<Log<T>> segments = levels.segments(direction);
                return function.apply(segments);
            } catch (Exception e) {
                logger.warn("Failed to acquire segments", e);
            }
            retries++;

        } while (retries < 10);

        throw new RuntimeException("Failed to acquire segment after " + retries + " retries");
    }

Try With Resources try(LogIterator<Log<T>> segments=levels.segments(direction)) in method public acquireSegments(direction Direction, function Function<LogIterator<Log<T>>,R>) : R from class io.joshworks.fstore.log.appender.LogAppender


    public static <T> List<T> toList(Iterator<T> iterator) {
        List<T> copy = new ArrayList<>();
        while (iterator.hasNext())
            copy.add(iterator.next());
        return copy;
    }

    public static <T> List<T> toList(Iterator<T> iterator) {
        List<T> copy = new ArrayList<T>();
        while (iterator.hasNext())
            copy.add(iterator.next());
        return copy;
    }

Replace Generic With Diamond ArrayList<T> with ArrayList<> in method public toList(iterator Iterator<T>) : List<T> from class io.joshworks.fstore.log.Iterators


    @Test
    public void take_waits_for_available_data() throws InterruptedException, IOException {

        try (PollingSubscriber<String> poller = appender.poller()) {
            int messages = 4000000;
            new Thread(() -> {
                long start = System.currentTimeMillis();
                for (int i = 0; i < messages; i++) {
                    appender.append(String.valueOf(i));
                }
                System.out.println("WRITE: " + (System.currentTimeMillis() - start));
            }).start();

            for (int i = 0; i < messages; i++) {
                String message = poller.take();
                assertEquals(String.valueOf(i), message);
                if (i % 5000 == 0) {
                    System.out.println("Read " + i + ": " + message);
                }
            }
        }
    }

    @Test
    public void poller() throws InterruptedException, IOException {

        PollingSubscriber<String> poller = appender.poller();
        try {
            int messages = 5000000;
            new Thread(() -> {
                long start = System.currentTimeMillis();
                for (int i = 0; i < messages; i++) {
                    appender.append(String.valueOf(i));
                }
                System.out.println("WRITE: " + (System.currentTimeMillis() - start));
            }).start();

            for (int i = 0; i < messages; i++) {
                String message = poller.poll();
                assertEquals(String.valueOf(i), message);
                if (i % 5000 == 0) {
                    System.out.println("Read " + i + ": " + message);
                }
            }
        } finally {
            poller.close();
        }

    }

Try With Resources try(PollingSubscriber<String> poller=appender.poller()) in method public take_waits_for_available_data() : void from class io.joshworks.fstore.log.appender.it.LogAppenderIT


    @Test
    public void delete() throws Exception {

        File temp = Utils.testFile();
        try (Storage store = store(temp, DEFAULT_LENGTH)) {
            store.delete();
            assertFalse(Files.exists(temp.toPath()));
        } finally {
            Utils.tryDelete(temp);
        }
    }

    @Test
    public void delete() throws Exception {
        Storage store = null;
        try {
            Path tobeDeleted = Files.createTempFile("tobeDeleted", null);
            store = store(tobeDeleted.toFile(), DEFAULT_LENGTH);
            store.delete();
            assertFalse(Files.exists(tobeDeleted));
        } finally {
            IOUtils.closeQuietly(store);
        }
    }

Try With Resources try(Storage store=store(temp,DEFAULT_LENGTH)) in method public delete() : void from class io.joshworks.fstore.core.DiskStorageTest


    public static List<File> loadSegments(File directory) {
        try (Stream<Path> files = Files.list(directory.toPath())) {
            return files
                    .filter(p -> isSegmentFile(p.getFileName().toFile().getName()))
                    .map(p -> loadSegment(directory, p.toFile().getName()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            throw new RuntimeException("Failed to load segmentsNames", e);
        }
    }

    public static List<File> loadSegments(File directory) {
        try {
            return Files.list(directory.toPath())
                    .filter(p -> isSegmentFile(p.getFileName().toFile().getName()))
                    .map(p -> loadSegment(directory, p.toFile().getName()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            throw new RuntimeException("Failed to load segmentsNames", e);
        }
    }

Try With Resources try(Stream<Path> files=Files.list(directory.toPath())) in method public loadSegments(directory File) : List<File> from class io.joshworks.fstore.log.LogFileUtils


    @Override
    protected IndexSegment openSegment(Storage storage, Serializer<IndexEntry> serializer, DataReader reader, long position, boolean readonly) {
        return new IndexSegment(storage, new FixedSizeBlockSerializer<>(serializer, IndexEntry.BYTES), reader, position, readonly, directory().toFile());
    }

    @Override
    protected IndexSegment openSegment(Storage storage, Serializer<IndexEntry> serializer, DataReader reader, long position, boolean readonly) {
        return new IndexSegment(storage, new FixedSizeBlockSerializer<IndexEntry>(serializer, IndexEntry.BYTES), reader, position, readonly, directory().toFile());
    }

Replace Generic With Diamond IndexSegment with IndexSegment in method protected openSegment(storage Storage, serializer Serializer<IndexEntry>, reader DataReader, position long, readonly boolean) : IndexSegment from class io.joshworks.fstore.es.index.disk.IndexAppender


    public static <T> LogEntry<T> of(int op, T data) {
        return new LogEntry<>(op, data);
    }

    public static <T> LogEntry<T> of(int op, T data) {
        return new LogEntry<T>(op, data);
    }

Replace Generic With Diamond LogEntry<T> with LogEntry<> in method public of(op int, data T) : LogEntry<T> from class io.joshworks.lsmtree.LogEntry


	private Map<String, SMEBinding> getBindingMapForServiceManager(SMEManager serviceManagerEntity) {
		ClosableIterator iter = serviceManagerEntity.getAllSvcBinding();
		Map<String, SMEBinding> bindings = new HashMap<>();

		while (iter.hasNext()) {
			Resource obj = (Resource) iter.next();

			SMEBinding binding = SMEBinding.getInstance(model2go, obj.asURI());
			SMEDependency dep = binding.getSvcBindDep();
			String depName = dep.getFullyQualifiedJClzName();

			bindings.put(depName, binding);

		}

		return bindings;
	}

	private Map<String, SMEBinding> getBindingMapForServiceManager(SMEManager serviceManagerEntity) {
		ClosableIterator iter = serviceManagerEntity.getAllSvcBinding();
		Map<String, SMEBinding> bindings = new HashMap<String, SMEBinding>();

		while (iter.hasNext()) {
			Resource obj = (Resource) iter.next();

			SMEBinding binding = SMEBinding.getInstance(model2go, obj.asURI());
			SMEDependency dep = binding.getSvcBindDep();
			String depName = dep.getFullyQualifiedJClzName();

			bindings.put(depName, binding);

		}

		return bindings;
	}

Replace Generic With Diamond HashMap<String,SMEBinding> with HashMap<> in method private getBindingMapForServiceManager(serviceManagerEntity SMEManager) : Map<String,SMEBinding> from class org.jflux.spec.services.ServiceManagerExtender2Go


	private RegistrationStrategy getRegStrat(SMEManager serviceManagerEntity) {
		SMSSvcRegStrategy regStrat = serviceManagerEntity.getRegStrategy();
		List<String> classNames = new ArrayList<>();
		ClosableIterator iter = serviceManagerEntity.getAllOSGiServPropBinding();
		Map<String, String> properties = getPropertyMap(iter);

		classNames.add(regStrat.getFullyQualifiedJClzName());

		RegistrationStrategy strat
				= new DefaultRegistrationStrategy(classNames.toArray(new String[classNames.size()]), properties);

		return strat;
	}

	private RegistrationStrategy getRegStrat(SMEManager serviceManagerEntity) {
		SMSSvcRegStrategy regStrat = serviceManagerEntity.getRegStrategy();
		List<String> classNames = new ArrayList<String>();
		ClosableIterator iter = serviceManagerEntity.getAllOSGiServPropBinding();
		Map<String, String> properties = getPropertyMap(iter);

		classNames.add(regStrat.getFullyQualifiedJClzName());

		RegistrationStrategy strat
				= new DefaultRegistrationStrategy(classNames.toArray(new String[classNames.size()]), properties);

		return strat;
	}

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method private getRegStrat(serviceManagerEntity SMEManager) : RegistrationStrategy from class org.jflux.spec.services.ServiceManagerExtender2Go