    private void init() {
        try {
            FileInputStream fileIn = new FileInputStream(dataFile);
            ObjectInputStream ois = new ObjectInputStream(fileIn);
            userList = (ArrayList<User>) ois.readObject();
            ois.close();
            fileIn.close();
        } catch (IOException | ClassNotFoundException i){
            System.out.println("No users exist or class is not found");
            userList = new ArrayList<>();
        }
    }

    private void init() {
        try {
            FileInputStream fileIn = new FileInputStream(dataFile);
            ObjectInputStream ois = new ObjectInputStream(fileIn);
            userList = (ArrayList<User>) ois.readObject();
            ois.close();
            fileIn.close();
        } catch (IOException | ClassNotFoundException i){
            System.out.println("No users exist or class is not found");
            userList = new ArrayList<User>();
        }
    }

Replace Generic With Diamond ArrayList<User> with ArrayList<> in method private init() : void from class com.photos.models.UserList


        @Override
        public void onOpen(Session session, EndpointConfig config) {
            this.session = session;
            session.addMessageHandler(String.class, (message) -> responses.add(message));
        }

        @Override
        public void onOpen(Session session, EndpointConfig config) {
            this.session = session;
            session.addMessageHandler(new MessageHandler.Whole<String>() {

                @Override
                public void onMessage(String message) {
                    responses.add(message);
                }
            });
        }

Replace Anonymous With Lambda io.undertow.websockets.jsr.test.security.WebsocketBasicAuthTestCase.ProgramaticClientEndpoint.onOpen.addMessageHandler.new MessageHandler.Whole<String> with (message) -> responses.add(message) in method public onOpen(session Session, config EndpointConfig) : void from class io.undertow.websockets.jsr.test.security.WebsocketBasicAuthTestCase.ProgramaticClientEndpoint


    @Test
    public void testServerReadTimeout() throws Exception {
        final AtomicBoolean connected = new AtomicBoolean(false);
        DefaultServer.setRootHandler(new WebSocketProtocolHandshakeHandler(
                (WebSocketConnectionCallback) (exchange, channel) -> {
                    connected.set(true);
                    channel.getReceiveSetter().set(new AbstractReceiveListener() {
                        @Override
                        protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
                            String string = message.getData();

                            if (string.equals("hello")) {
                                WebSockets.sendText("world", channel, null);
                            } else {
                                WebSockets.sendText(string, channel, null);
                            }
                        }
                    });
                    channel.resumeReceives();
                }));

        final FutureResult<?> latch = new FutureResult();
        WebSocketTestClient client = new WebSocketTestClient(getVersion(), new URI("ws://" + NetworkUtils.formatPossibleIpv6Address(DefaultServer.getHostAddress("default")) + ":" + DefaultServer.getHostPort("default") + "/"));
        client.connect();
        client.send(new TextWebSocketFrame(Unpooled.copiedBuffer("hello", CharsetUtil.US_ASCII)), new FrameChecker(TextWebSocketFrame.class, "world".getBytes(CharsetUtil.US_ASCII), latch));
        latch.getIoFuture().get();

        final long watchStart = System.currentTimeMillis();
        final long watchTimeout = System.currentTimeMillis() + TESTABLE_TIMEOUT_VALUE + 500;
        final FutureResult<Long> timeoutLatch = new FutureResult<Long>();
        ReadTimeoutChannelGuard readTimeoutChannelGuard = new ReadTimeoutChannelGuard(client, timeoutLatch, watchTimeout);

        final ScheduledFuture sf = SCHEDULER.scheduleAtFixedRate(readTimeoutChannelGuard, 0, 50, TimeUnit.MILLISECONDS);
        readTimeoutChannelGuard.setTaskScheduledFuture(sf);

        final Long watchTimeEnd = timeoutLatch.getIoFuture().get();
        if(watchTimeEnd == -1) {
            Assert.fail("Timeout did not happen... in time. Were waiting '" + watchTimeout + "' ms, timeout should happen in '" + TESTABLE_TIMEOUT_VALUE + "' ms.");
        } else {
            long timeSpent = watchTimeEnd - watchStart;
            //let's be generous and give 150ms diff( there is "fuzz" coded for 50ms in undertow as well
            if(!(timeSpent <= TESTABLE_TIMEOUT_VALUE + 150)) {
                Assert.fail("Timeout did not happen... in time. Socket timeout out in '" + timeSpent + "' ms, supposed to happen in '" + TESTABLE_TIMEOUT_VALUE + "' ms.");
            }
        }
    }

    @Test
    public void testServerReadTimeout() throws Exception {
        beforeTest(DEFAULTS_IO_TIMEOTU_VALUE, TESTABLE_TIMEOUT_VALUE, NON_TESTABLE_TIMEOUT_VALUE);
        final AtomicBoolean connected = new AtomicBoolean(false);
        DefaultServer.setRootHandler(new WebSocketProtocolHandshakeHandler(new WebSocketConnectionCallback() {
            @Override
            public void onConnect(final WebSocketHttpExchange exchange, final WebSocketChannel channel) {
                connected.set(true);
                channel.getReceiveSetter().set(new AbstractReceiveListener() {
                    @Override
                    protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
                        String string = message.getData();

                        if (string.equals("hello")) {
                            WebSockets.sendText("world", channel, null);
                        } else {
                            WebSockets.sendText(string, channel, null);
                        }
                    }
                });
                channel.resumeReceives();
            }
        }));

        final FutureResult<?> latch = new FutureResult();
        WebSocketTestClient client = new WebSocketTestClient(getVersion(), new URI("ws://" + NetworkUtils.formatPossibleIpv6Address(DefaultServer.getHostAddress("default")) + ":" + DefaultServer.getHostPort("default") + "/"));
        client.connect();
        client.send(new TextWebSocketFrame(Unpooled.copiedBuffer("hello", CharsetUtil.US_ASCII)), new FrameChecker(TextWebSocketFrame.class, "world".getBytes(CharsetUtil.US_ASCII), latch));
        latch.getIoFuture().get();

        final long watchStart = System.currentTimeMillis();
        final long watchTimeout = System.currentTimeMillis()+TESTABLE_TIMEOUT_VALUE+500;
        final FutureResult<Long> timeoutLatch = new FutureResult<Long>();
        ReadTimeoutChannelGuard readTimeoutChannelGuard = new ReadTimeoutChannelGuard(client, timeoutLatch, watchTimeout);

        final ScheduledFuture sf = SCHEDULER.scheduleAtFixedRate(readTimeoutChannelGuard, 0, 50, TimeUnit.MILLISECONDS);
        readTimeoutChannelGuard.setTaskScheduledFuture(sf);

        final Long watchTimeEnd = timeoutLatch.getIoFuture().get();
        if(watchTimeEnd == -1) {
            Assert.fail("Timeout did not happen... in time. Were waiting '"+watchTimeout+"' ms, timeout should happen in '"+TESTABLE_TIMEOUT_VALUE+"' ms.");
        } else {
            long timeSpent = watchTimeEnd - watchStart;
            //lets be generous and give 150ms diff( there is "fuzz" coded for 50ms in undertow as well
            if(!(timeSpent<=TESTABLE_TIMEOUT_VALUE+150)) {
                Assert.fail("Timeout did not happen... in time. Socket timeout out in '"+timeSpent+"' ms, supposed to happen in '"+TESTABLE_TIMEOUT_VALUE+"' ms.");
            }
        }
    }

Replace Anonymous With Lambda io.undertow.websockets.core.protocol.WebSocketTimeoutTestCase.testServerReadTimeout.setRootHandler.new WebSocketProtocolHandshakeHandler.new WebSocketConnectionCallback with (exchange, channel) -> {connected.set(true); in method public testServerReadTimeout() : void from class io.undertow.websockets.core.protocol.WebSocketTimeoutTestCase


    /**
     * Flushes all ready stream sink conduits to the channel.
     * <p>
     * Frames will be batched up, to allow them all to be written out via a gathering
     * write. The {@link #framePriority} implementation will be invoked to decide which
     * frames are eligible for sending and in what order.
     */
    protected synchronized void flushSenders() {
        if(flushingSenders) {
            throw UndertowMessages.MESSAGES.recursiveCallToFlushingSenders();
        }
        flushingSenders = true;
        try {
            int toSend = 0;
            S frame;
            while ((frame = newFrames.poll()) != null) {
                frame.preWrite();
                if (framePriority.insertFrame(frame, pendingFrames)) {
                    if (!heldFrames.isEmpty()) {
                        framePriority.frameAdded(frame, pendingFrames, heldFrames);
                    }
                } else {
                    // frame not ready for sending, add in held queue and start the timeout task
                    frame.addReadyForFlushTask();
                    heldFrames.add(frame);
                }
            }

            boolean finalFrame = false;
            ListIterator<S> it = pendingFrames.listIterator();
            while (it.hasNext()) {
                S sender = it.next();
                if (sender.isReadyForFlush()) {
                    ++toSend;
                } else {
                    break;
                }
                if (sender.isLastFrame()) {
                    finalFrame = true;
                }
            }
            if (toSend == 0) {
                //if there is nothing to send we just attempt a flush on the underlying channel
                try {
                    if(channel.getSinkChannel().flush()) {
                        channel.getSinkChannel().suspendWrites();
                    }
                } catch (Throwable e) {
                    safeClose(channel);
                    markWritesBroken(e);
                }
                return;
            }
            ByteBuffer[] data = new ByteBuffer[toSend * 3];
            int j = 0;
            it = pendingFrames.listIterator();
            try {
                while (j < toSend) {
                    S next = it.next();
                    //todo: rather than adding empty buffers just store the offsets
                    SendFrameHeader frameHeader = next.getFrameHeader();
                    PooledByteBuffer frameHeaderByteBuffer = frameHeader.getByteBuffer();
                    ByteBuffer frameTrailerBuffer = frameHeader.getTrailer();
                    data[j * 3] = frameHeaderByteBuffer != null
                            ? frameHeaderByteBuffer.getBuffer()
                            : Buffers.EMPTY_BYTE_BUFFER;
                    data[(j * 3) + 1] = next.getBuffer() == null ? Buffers.EMPTY_BYTE_BUFFER : next.getBuffer();
                    data[(j * 3) + 2] = frameTrailerBuffer != null ? frameTrailerBuffer : Buffers.EMPTY_BYTE_BUFFER;
                    ++j;
                }
                long toWrite = Buffers.remaining(data);
                long res;
                do {
                    res = channel.getSinkChannel().write(data);
                    toWrite -= res;
                } while (res > 0 && toWrite > 0);
                int max = toSend;

                while (max > 0) {
                    S sinkChannel = pendingFrames.get(0);
                    PooledByteBuffer frameHeaderByteBuffer = sinkChannel.getFrameHeader().getByteBuffer();
                    ByteBuffer frameTrailerBuffer = sinkChannel.getFrameHeader().getTrailer();
                    if (frameHeaderByteBuffer != null && frameHeaderByteBuffer.getBuffer().hasRemaining()
                            || sinkChannel.getBuffer() != null && sinkChannel.getBuffer().hasRemaining()
                            || frameTrailerBuffer != null && frameTrailerBuffer.hasRemaining()) {
                        break;
                    }
                    sinkChannel.flushComplete();
                    pendingFrames.remove(sinkChannel);
                    max--;
                }
                if (!pendingFrames.isEmpty() || !channel.getSinkChannel().flush()) {
                    channel.getSinkChannel().resumeWrites();
                } else {
                    channel.getSinkChannel().suspendWrites();
                }
                if (pendingFrames.isEmpty() && finalFrame) {
                    //all data has been sent. Close gracefully
                    channel.getSinkChannel().shutdownWrites();
                    if (!channel.getSinkChannel().flush()) {
                        channel.getSinkChannel().setWriteListener(ChannelListeners.flushingChannelListener(null, null));
                        channel.getSinkChannel().resumeWrites();
                    }
                } else if (pendingFrames.size() > queuedFrameHighWaterMark) {
                    new UpdateResumeState(null, null, true).run();
                } else if (receivesSuspendedTooManyQueuedMessages && pendingFrames.size() < queuedFrameLowWaterMark) {
                    new UpdateResumeState(null, null, false).run();
                }

            } catch (IOException|RuntimeException|Error e) {
                safeClose(channel);
                markWritesBroken(e);
            }
        } finally {
            flushingSenders = false;
            if(!newFrames.isEmpty()) {
                runInIoThread(this::flushSenders);
            }
        }
    }

    /**
     * Flushes all ready stream sink conduits to the channel.
     * <p>
     * Frames will be batched up, to allow them all to be written out via a gathering
     * write. The {@link #framePriority} implementation will be invoked to decide which
     * frames are eligible for sending and in what order.
     */
    protected synchronized void flushSenders() {
        if(flushingSenders) {
            throw UndertowMessages.MESSAGES.recursiveCallToFlushingSenders();
        }
        flushingSenders = true;
        try {
            int toSend = 0;
            S frame;
            while ((frame = newFrames.poll()) != null) {
                frame.preWrite();
                if (framePriority.insertFrame(frame, pendingFrames)) {
                    if (!heldFrames.isEmpty()) {
                        framePriority.frameAdded(frame, pendingFrames, heldFrames);
                    }
                } else {
                    // frame not ready for sending, add in held queue and start the timeout task
                    frame.addReadyForFlushTask();
                    heldFrames.add(frame);
                }
            }

            boolean finalFrame = false;
            ListIterator<S> it = pendingFrames.listIterator();
            while (it.hasNext()) {
                S sender = it.next();
                if (sender.isReadyForFlush()) {
                    ++toSend;
                } else {
                    break;
                }
                if (sender.isLastFrame()) {
                    finalFrame = true;
                }
            }
            if (toSend == 0) {
                //if there is nothing to send we just attempt a flush on the underlying channel
                try {
                    if(channel.getSinkChannel().flush()) {
                        channel.getSinkChannel().suspendWrites();
                    }
                } catch (Throwable e) {
                    safeClose(channel);
                    markWritesBroken(e);
                }
                return;
            }
            ByteBuffer[] data = new ByteBuffer[toSend * 3];
            int j = 0;
            it = pendingFrames.listIterator();
            try {
                while (j < toSend) {
                    S next = it.next();
                    //todo: rather than adding empty buffers just store the offsets
                    SendFrameHeader frameHeader = next.getFrameHeader();
                    PooledByteBuffer frameHeaderByteBuffer = frameHeader.getByteBuffer();
                    ByteBuffer frameTrailerBuffer = frameHeader.getTrailer();
                    data[j * 3] = frameHeaderByteBuffer != null
                            ? frameHeaderByteBuffer.getBuffer()
                            : Buffers.EMPTY_BYTE_BUFFER;
                    data[(j * 3) + 1] = next.getBuffer() == null ? Buffers.EMPTY_BYTE_BUFFER : next.getBuffer();
                    data[(j * 3) + 2] = frameTrailerBuffer != null ? frameTrailerBuffer : Buffers.EMPTY_BYTE_BUFFER;
                    ++j;
                }
                long toWrite = Buffers.remaining(data);
                long res;
                do {
                    res = channel.getSinkChannel().write(data);
                    toWrite -= res;
                } while (res > 0 && toWrite > 0);
                int max = toSend;

                while (max > 0) {
                    S sinkChannel = pendingFrames.get(0);
                    PooledByteBuffer frameHeaderByteBuffer = sinkChannel.getFrameHeader().getByteBuffer();
                    ByteBuffer frameTrailerBuffer = sinkChannel.getFrameHeader().getTrailer();
                    if (frameHeaderByteBuffer != null && frameHeaderByteBuffer.getBuffer().hasRemaining()
                            || sinkChannel.getBuffer() != null && sinkChannel.getBuffer().hasRemaining()
                            || frameTrailerBuffer != null && frameTrailerBuffer.hasRemaining()) {
                        break;
                    }
                    sinkChannel.flushComplete();
                    pendingFrames.remove(sinkChannel);
                    max--;
                }
                if (!pendingFrames.isEmpty() || !channel.getSinkChannel().flush()) {
                    channel.getSinkChannel().resumeWrites();
                } else {
                    channel.getSinkChannel().suspendWrites();
                }
                if (pendingFrames.isEmpty() && finalFrame) {
                    //all data has been sent. Close gracefully
                    channel.getSinkChannel().shutdownWrites();
                    if (!channel.getSinkChannel().flush()) {
                        channel.getSinkChannel().setWriteListener(ChannelListeners.flushingChannelListener(null, null));
                        channel.getSinkChannel().resumeWrites();
                    }
                } else if (pendingFrames.size() > queuedFrameHighWaterMark) {
                    new UpdateResumeState(null, null, true).run();
                } else if (receivesSuspendedTooManyQueuedMessages && pendingFrames.size() < queuedFrameLowWaterMark) {
                    new UpdateResumeState(null, null, false).run();
                }

            } catch (IOException|RuntimeException|Error e) {
                safeClose(channel);
                markWritesBroken(e);
            }
        } finally {
            flushingSenders = false;
            if(!newFrames.isEmpty()) {
                runInIoThread(new Runnable() {
                    @Override
                    public void run() {
                        flushSenders();
                    }
                });
            }
        }
    }

Replace Anonymous With Lambda io.undertow.server.protocol.framed.AbstractFramedChannel.flushSenders.runInIoThread.new Runnable with this::flushSenders in method protected flushSenders() : void from class io.undertow.server.protocol.framed.AbstractFramedChannel


    public static ObjectPool<Deflater> newInstanceDeflaterPool(int deflateLevel) {
        return new NewInstanceObjectPool<>(() -> new Deflater(deflateLevel, true), Deflater::end);
    }

    public static ObjectPool<Deflater> newInstanceDeflaterPool(int deflateLevel) {
        return new NewInstanceObjectPool<Deflater>(() -> new Deflater(deflateLevel, true), Deflater::end);
    }

Replace Generic With Diamond NewInstanceObjectPool<Deflater> with NewInstanceObjectPool<> in method public newInstanceDeflaterPool(deflateLevel int) : ObjectPool<Deflater> from class io.undertow.conduits.DeflatingStreamSinkConduit


    public static ObjectPool<Deflater> simpleDeflaterPool(int poolSize, int deflateLevel) {
        return new SimpleObjectPool<>(poolSize, () -> new Deflater(deflateLevel, true), Deflater::reset, Deflater::end);
    }

    public static ObjectPool<Deflater> simpleDeflaterPool(int poolSize, int deflateLevel) {
        return new SimpleObjectPool<Deflater>(poolSize, () -> new Deflater(deflateLevel, true), Deflater::reset, Deflater::end);
    }

Replace Generic With Diamond SimpleObjectPool<Deflater> with SimpleObjectPool<> in method public simpleDeflaterPool(poolSize int, deflateLevel int) : ObjectPool<Deflater> from class io.undertow.conduits.DeflatingStreamSinkConduit


    public static ObjectPool<Inflater> newInstanceInflaterPool() {
        return new NewInstanceObjectPool<>(() -> new Inflater(true), Inflater::end);
    }

    public static ObjectPool<Inflater> newInstanceInflaterPool() {
        return new NewInstanceObjectPool<Inflater>(() -> new Inflater(true), Inflater::end);
    }

Replace Generic With Diamond NewInstanceObjectPool<Inflater> with NewInstanceObjectPool<> in method public newInstanceInflaterPool() : ObjectPool<Inflater> from class io.undertow.conduits.InflatingStreamSourceConduit


    public static ObjectPool<Inflater> simpleInflaterPool(int poolSize) {
        return new SimpleObjectPool<>(poolSize, () -> new Inflater(true), Inflater::reset, Inflater::end);
    }

    public static ObjectPool<Inflater> simpleInflaterPool(int poolSize) {
        return new SimpleObjectPool<Inflater>(poolSize, () -> new Inflater(true), Inflater::reset, Inflater::end);
    }

Replace Generic With Diamond SimpleObjectPool<Inflater> with SimpleObjectPool<> in method public simpleInflaterPool(poolSize int) : ObjectPool<Inflater> from class io.undertow.conduits.InflatingStreamSourceConduit


    public ExchangeAttribute parse(String pattern) {
        List<ExchangeAttribute> list = new ArrayList<>();

        PatternTokenizer tokenizer = new PatternTokenizer(pattern);
        try {

            // Ignore leading whitespace.
            tokenizer.getWhiteSpaces();

            if (tokenizer.isEnded()) {
                UndertowLogger.ROOT_LOGGER.extendedAccessLogEmptyPattern();
                return null;
            }

            String token = tokenizer.getToken();
            while (token != null) {
                if (UndertowLogger.ROOT_LOGGER.isDebugEnabled()) {
                    UndertowLogger.ROOT_LOGGER.debug("token = " + token);
                }
                ExchangeAttribute element = getLogElement(token, tokenizer);
                if (element == null) {
                    break;
                }
                list.add(element);
                String whiteSpaces = tokenizer.getWhiteSpaces();
                if (whiteSpaces.length() > 0) {
                    list.add(new ConstantExchangeAttribute(whiteSpaces));
                }
                if (tokenizer.isEnded()) {
                    break;
                }
                token = tokenizer.getToken();
            }
            if (UndertowLogger.ROOT_LOGGER.isDebugEnabled()) {
                UndertowLogger.ROOT_LOGGER.debug("finished decoding with element size of: " + list.size());
            }
            return new CompositeExchangeAttribute(list.toArray(new ExchangeAttribute[list.size()]));
        } catch (IOException e) {
            UndertowLogger.ROOT_LOGGER.extendedAccessLogPatternParseError(e);
            return null;
        }
    }

    public ExchangeAttribute parse(String pattern) {
        List<ExchangeAttribute> list = new ArrayList<ExchangeAttribute>();

        PatternTokenizer tokenizer = new PatternTokenizer(pattern);
        try {

            // Ignore leading whitespace.
            tokenizer.getWhiteSpaces();

            if (tokenizer.isEnded()) {
                UndertowLogger.ROOT_LOGGER.extendedAccessLogEmptyPattern();
                return null;
            }

            String token = tokenizer.getToken();
            while (token != null) {
                if (UndertowLogger.ROOT_LOGGER.isDebugEnabled()) {
                    UndertowLogger.ROOT_LOGGER.debug("token = " + token);
                }
                ExchangeAttribute element = getLogElement(token, tokenizer);
                if (element == null) {
                    break;
                }
                list.add(element);
                String whiteSpaces = tokenizer.getWhiteSpaces();
                if (whiteSpaces.length() > 0) {
                    list.add(new ConstantExchangeAttribute(whiteSpaces));
                }
                if (tokenizer.isEnded()) {
                    break;
                }
                token = tokenizer.getToken();
            }
            if (UndertowLogger.ROOT_LOGGER.isDebugEnabled()) {
                UndertowLogger.ROOT_LOGGER.debug("finished decoding with element size of: " + list.size());
            }
            return new CompositeExchangeAttribute(list.toArray(new ExchangeAttribute[list.size()]));
        } catch (IOException e) {
            UndertowLogger.ROOT_LOGGER.extendedAccessLogPatternParseError(e);
            return null;
        }
    }

Replace Generic With Diamond ArrayList<ExchangeAttribute> with ArrayList<> in method public parse(pattern String) : ExchangeAttribute from class io.undertow.server.handlers.accesslog.ExtendedAccessLogParser


    /**
     * Gets a pre-encoded resource.
     * <p>
     * TODO: blocking / non-blocking semantics
     *
     * @param resource
     * @param exchange
     * @return
     * @throws IOException
     */
    public ContentEncodedResource getResource(final Resource resource, final HttpServerExchange exchange) throws IOException {
        final String path = resource.getPath();
        Path file = resource.getFilePath();
        if (file == null) {
            return null;
        }
        if (minResourceSize > 0 && resource.getContentLength() < minResourceSize ||
                maxResourceSize > 0 && resource.getContentLength() > maxResourceSize ||
                !(encodingAllowed == null || encodingAllowed.resolve(exchange))) {
            return null;
        }
        AllowedContentEncodings encodings = contentEncodingRepository.getContentEncodings(exchange);
        if (encodings == null || encodings.isNoEncodingsAllowed()) {
            return null;
        }
        EncodingMapping encoding = encodings.getEncoding();
        if (encoding == null || encoding.getName().equals(ContentEncodingRepository.IDENTITY)) {
            return null;
        }
        String newPath = path + ".undertow.encoding." + encoding.getName();
        Resource preCompressed = encoded.getResource(newPath);
        if (preCompressed != null) {
            return new ContentEncodedResource(preCompressed, encoding.getName());
        }
        final LockKey key = new LockKey(path, encoding.getName());
        if (fileLocks.putIfAbsent(key, this) != null) {
            //another thread is already compressing
            //we don't do anything fancy here, just return and serve non-compressed content
            return null;
        }
        FileChannel targetFileChannel = null;
        FileChannel sourceFileChannel = null;
        try {
            //double check, the compressing thread could have finished just before we acquired the lock
            preCompressed = encoded.getResource(newPath);
            if (preCompressed != null) {
                return new ContentEncodedResource(preCompressed, encoding.getName());
            }

            final Path finalTarget = encodedResourcesRoot.resolve(newPath);
            final Path tempTarget = encodedResourcesRoot.resolve(newPath);

            //horrible hack to work around XNIO issue
            OutputStream tmp = Files.newOutputStream(tempTarget);
            try {
                tmp.close();
            } finally {
                IoUtils.safeClose(tmp);
            }

            targetFileChannel = FileChannel.open(tempTarget, StandardOpenOption.READ, StandardOpenOption.WRITE);
            sourceFileChannel = FileChannel.open(file, StandardOpenOption.READ);

            StreamSinkConduit conduit = encoding.getEncoding().getResponseWrapper().wrap(new ImmediateConduitFactory<>(new FileConduitTarget(targetFileChannel, exchange)), exchange);
            final ConduitStreamSinkChannel targetChannel = new ConduitStreamSinkChannel(null, conduit);
            long transferred = sourceFileChannel.transferTo(0, resource.getContentLength(), targetChannel);
            targetChannel.shutdownWrites();
            org.xnio.channels.Channels.flushBlocking(targetChannel);
            if (transferred != resource.getContentLength()) {
                UndertowLogger.REQUEST_LOGGER.failedToWritePreCachedFile();
            }
            Files.move(tempTarget, finalTarget);
            encoded.invalidate(newPath);
            final Resource encodedResource = encoded.getResource(newPath);
            return new ContentEncodedResource(encodedResource, encoding.getName());
        } finally {
            IoUtils.safeClose(targetFileChannel);
            IoUtils.safeClose(sourceFileChannel);
            fileLocks.remove(key);
        }
    }

    /**
     * Gets a pre-encoded resource.
     * <p>
     * TODO: blocking / non-blocking semantics
     *
     * @param resource
     * @param exchange
     * @return
     * @throws IOException
     */
    public ContentEncodedResource getResource(final Resource resource, final HttpServerExchange exchange) throws IOException {
        final String path = resource.getPath();
        Path file = resource.getFilePath();
        if (file == null) {
            return null;
        }
        if (minResourceSize > 0 && resource.getContentLength() < minResourceSize ||
                maxResourceSize > 0 && resource.getContentLength() > maxResourceSize ||
                !(encodingAllowed == null || encodingAllowed.resolve(exchange))) {
            return null;
        }
        AllowedContentEncodings encodings = contentEncodingRepository.getContentEncodings(exchange);
        if (encodings == null || encodings.isNoEncodingsAllowed()) {
            return null;
        }
        EncodingMapping encoding = encodings.getEncoding();
        if (encoding == null || encoding.getName().equals(ContentEncodingRepository.IDENTITY)) {
            return null;
        }
        String newPath = path + ".undertow.encoding." + encoding.getName();
        Resource preCompressed = encoded.getResource(newPath);
        if (preCompressed != null) {
            return new ContentEncodedResource(preCompressed, encoding.getName());
        }
        final LockKey key = new LockKey(path, encoding.getName());
        if (fileLocks.putIfAbsent(key, this) != null) {
            //another thread is already compressing
            //we don't do anything fancy here, just return and serve non-compressed content
            return null;
        }
        FileChannel targetFileChannel = null;
        FileChannel sourceFileChannel = null;
        try {
            //double check, the compressing thread could have finished just before we acquired the lock
            preCompressed = encoded.getResource(newPath);
            if (preCompressed != null) {
                return new ContentEncodedResource(preCompressed, encoding.getName());
            }

            final Path finalTarget = encodedResourcesRoot.resolve(newPath);
            final Path tempTarget = encodedResourcesRoot.resolve(newPath);

            //horrible hack to work around XNIO issue
            OutputStream tmp = Files.newOutputStream(tempTarget);
            try {
                tmp.close();
            } finally {
                IoUtils.safeClose(tmp);
            }

            targetFileChannel = FileChannel.open(tempTarget, StandardOpenOption.READ, StandardOpenOption.WRITE);
            sourceFileChannel = FileChannel.open(file, StandardOpenOption.READ);

            StreamSinkConduit conduit = encoding.getEncoding().getResponseWrapper().wrap(new ImmediateConduitFactory<StreamSinkConduit>(new FileConduitTarget(targetFileChannel, exchange)), exchange);
            final ConduitStreamSinkChannel targetChannel = new ConduitStreamSinkChannel(null, conduit);
            long transferred = sourceFileChannel.transferTo(0, resource.getContentLength(), targetChannel);
            targetChannel.shutdownWrites();
            org.xnio.channels.Channels.flushBlocking(targetChannel);
            if (transferred != resource.getContentLength()) {
                UndertowLogger.REQUEST_LOGGER.failedToWritePreCachedFile();
            }
            Files.move(tempTarget, finalTarget);
            encoded.invalidate(newPath);
            final Resource encodedResource = encoded.getResource(newPath);
            return new ContentEncodedResource(encodedResource, encoding.getName());
        } finally {
            IoUtils.safeClose(targetFileChannel);
            IoUtils.safeClose(sourceFileChannel);
            fileLocks.remove(key);
        }
    }

Replace Generic With Diamond ImmediateConduitFactory<StreamSinkConduit> with ImmediateConduitFactory<> in method public getResource(resource Resource, exchange HttpServerExchange) : ContentEncodedResource from class io.undertow.server.handlers.encoding.ContentEncodedResourceManager


    public synchronized HostTable addHost(H host) {
        if(hosts.containsKey(host)) {
            throw UndertowMessages.MESSAGES.hostAlreadyRegistered(host);
        }
        hosts.put(host, new CopyOnWriteArraySet<>());
        return this;
    }

    public synchronized HostTable addHost(H host) {
        if(hosts.containsKey(host)) {
            throw UndertowMessages.MESSAGES.hostAlreadyRegistered(host);
        }
        hosts.put(host, new CopyOnWriteArraySet<Target>());
        return this;
    }

Replace Generic With Diamond CopyOnWriteArraySet<Target> with CopyOnWriteArraySet<> in method public addHost(host H) : HostTable from class io.undertow.server.handlers.proxy.HostTable


    static void execute(Runnable runnable) {
        if (EXECUTOR == null) {
            synchronized (ShutdownFallbackExecutor.class) {
                if (EXECUTOR == null) {
                    EXECUTOR = new ThreadPoolExecutor(0, 1,
                            10, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<>(),
                            new ShutdownFallbackThreadFactory());
                }
            }
        }
        EXECUTOR.execute(runnable);
    }

    static void execute(Runnable runnable) {
        if (EXECUTOR == null) {
            synchronized (ShutdownFallbackExecutor.class) {
                if (EXECUTOR == null) {
                    EXECUTOR = new ThreadPoolExecutor(0, 1,
                            10, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            new ShutdownFallbackThreadFactory());
                }
            }
        }
        EXECUTOR.execute(runnable);
    }

Replace Generic With Diamond ThreadPoolExecutor with ThreadPoolExecutor in method package execute(runnable Runnable) : void from class io.undertow.server.protocol.framed.ShutdownFallbackExecutor


    /**
     * Returns a new node holding item.  Uses relaxed write because item
     * can only be seen after piggy-backing publication via CAS.
     */
    static <E> Node<E> newNode(E item) {
        Node<E> node = new Node<>();
        ITEM.set(node, item);
        return node;
    }

    /**
     * Returns a new node holding item.  Uses relaxed write because item
     * can only be seen after piggy-backing publication via CAS.
     */
    static <E> Node<E> newNode(E item) {
        Node<E> node = new Node<E>();
        ITEM.set(node, item);
        return node;
    }

Replace Generic With Diamond Node<E> with Node<> in method package newNode(item E) : Node<E> from class io.undertow.util.FastConcurrentDirectDeque


    /**
     * Constructs an empty deque.
     */
    public FastConcurrentDirectDeque() {
        head = tail = new Node<>();
    }

    /**
     * Constructs an empty deque.
     */
    public FastConcurrentDirectDeque() {
        head = tail = new Node<E>();
    }

Replace Generic With Diamond Node<E> with Node<> in method public FastConcurrentDirectDeque() from class io.undertow.util.FastConcurrentDirectDeque


    public SimpleObjectPool(int poolSize, Supplier<T> supplier, Consumer<T> recycler, Consumer<T> consumer) {
        this.supplier = supplier;
        this.recycler = recycler;
        this.consumer = consumer;
        pool = new LinkedBlockingDeque<>(poolSize);
    }

    public SimpleObjectPool(int poolSize, Supplier<T> supplier, Consumer<T> recycler, Consumer<T> consumer) {
        this.supplier = supplier;
        this.recycler = recycler;
        this.consumer = consumer;
        pool = new LinkedBlockingDeque<T>(poolSize);
    }

Replace Generic With Diamond LinkedBlockingDeque<T> with LinkedBlockingDeque<> in method public SimpleObjectPool(poolSize int, supplier Supplier<T>, recycler Consumer<T>, consumer Consumer<T>) from class io.undertow.util.SimpleObjectPool


    /**
     * Initiate a low-copy transfer between two stream channels.  The pool should be a direct buffer pool for best
     * performance.
     *
     * @param source the source channel
     * @param sink the target channel
     * @param sourceListener the source listener to set and call when the transfer is complete, or {@code null} to clear the listener at that time
     * @param sinkListener the target listener to set and call when the transfer is complete, or {@code null} to clear the listener at that time
     * @param readExceptionHandler the read exception handler to call if an error occurs during a read operation
     * @param writeExceptionHandler the write exception handler to call if an error occurs during a write operation
     * @param pool the pool from which the transfer buffer should be allocated
     */
    public static <I extends StreamSourceChannel, O extends StreamSinkChannel> void initiateTransfer(final I source, final O sink, final ChannelListener<? super I> sourceListener, final ChannelListener<? super O> sinkListener, final ChannelExceptionHandler<? super I> readExceptionHandler, final ChannelExceptionHandler<? super O> writeExceptionHandler, ByteBufferPool pool) {
        if (pool == null) {
            throw UndertowMessages.MESSAGES.argumentCannotBeNull("pool");
        }
        final PooledByteBuffer allocated = pool.allocate();
        boolean free = true;
        try {
            final ByteBuffer buffer = allocated.getBuffer();
            long read;
            for(;;) {
                try {
                    read = source.read(buffer);
                    buffer.flip();
                } catch (IOException e) {
                    ChannelListeners.invokeChannelExceptionHandler(source, readExceptionHandler, e);
                    return;
                }
                if (read == 0 && !buffer.hasRemaining()) {
                    break;
                }
                if (read == -1 && !buffer.hasRemaining()) {
                    done(source, sink, sourceListener, sinkListener);
                    return;
                }
                while (buffer.hasRemaining()) {
                    final int res;
                    try {
                        res = sink.write(buffer);
                    } catch (IOException e) {
                        ChannelListeners.invokeChannelExceptionHandler(sink, writeExceptionHandler, e);
                        return;
                    }
                    if (res == 0) {
                        break;
                    }
                }
                if(buffer.hasRemaining()) {
                    break;
                }
                buffer.clear();
            }
            PooledByteBuffer current = null;
            if(buffer.hasRemaining()) {
                current = allocated;
                free = false;
            }

            final TransferListener<I, O> listener = new TransferListener<>(pool, current, source, sink, sourceListener, sinkListener, writeExceptionHandler, readExceptionHandler, read == -1);
            sink.getWriteSetter().set(listener);
            source.getReadSetter().set(listener);
            //we resume both reads and writes, as we want to keep trying to fill the buffer
            if(current == null || buffer.capacity() != buffer.remaining()) {
                //we don't resume if the buffer is 100% full
                source.resumeReads();
            }
            if(current != null) {
                //we don't resume writes if we have nothing to write
                sink.resumeWrites();
            }
        } finally {
            if (free) {
                allocated.close();
            }
        }
    }

    /**
     * Initiate a low-copy transfer between two stream channels.  The pool should be a direct buffer pool for best
     * performance.
     *
     * @param source the source channel
     * @param sink the target channel
     * @param sourceListener the source listener to set and call when the transfer is complete, or {@code null} to clear the listener at that time
     * @param sinkListener the target listener to set and call when the transfer is complete, or {@code null} to clear the listener at that time
     * @param readExceptionHandler the read exception handler to call if an error occurs during a read operation
     * @param writeExceptionHandler the write exception handler to call if an error occurs during a write operation
     * @param pool the pool from which the transfer buffer should be allocated
     */
    public static <I extends StreamSourceChannel, O extends StreamSinkChannel> void initiateTransfer(final I source, final O sink, final ChannelListener<? super I> sourceListener, final ChannelListener<? super O> sinkListener, final ChannelExceptionHandler<? super I> readExceptionHandler, final ChannelExceptionHandler<? super O> writeExceptionHandler, ByteBufferPool pool) {
        if (pool == null) {
            throw UndertowMessages.MESSAGES.argumentCannotBeNull("pool");
        }
        final PooledByteBuffer allocated = pool.allocate();
        boolean free = true;
        try {
            final ByteBuffer buffer = allocated.getBuffer();
            long read;
            for(;;) {
                try {
                    read = source.read(buffer);
                    buffer.flip();
                } catch (IOException e) {
                    ChannelListeners.invokeChannelExceptionHandler(source, readExceptionHandler, e);
                    return;
                }
                if (read == 0 && !buffer.hasRemaining()) {
                    break;
                }
                if (read == -1 && !buffer.hasRemaining()) {
                    done(source, sink, sourceListener, sinkListener);
                    return;
                }
                while (buffer.hasRemaining()) {
                    final int res;
                    try {
                        res = sink.write(buffer);
                    } catch (IOException e) {
                        ChannelListeners.invokeChannelExceptionHandler(sink, writeExceptionHandler, e);
                        return;
                    }
                    if (res == 0) {
                        break;
                    }
                }
                if(buffer.hasRemaining()) {
                    break;
                }
                buffer.clear();
            }
            PooledByteBuffer current = null;
            if(buffer.hasRemaining()) {
                current = allocated;
                free = false;
            }

            final TransferListener<I, O> listener = new TransferListener<I, O>(pool, current, source, sink, sourceListener, sinkListener, writeExceptionHandler, readExceptionHandler, read == -1);
            sink.getWriteSetter().set(listener);
            source.getReadSetter().set(listener);
            //we resume both reads and writes, as we want to keep trying to fill the buffer
            if(current == null || buffer.capacity() != buffer.remaining()) {
                //we don't resume if the buffer is 100% full
                source.resumeReads();
            }
            if(current != null) {
                //we don't resume writes if we have nothing to write
                sink.resumeWrites();
            }
        } finally {
            if (free) {
                allocated.close();
            }
        }
    }

Replace Generic With Diamond TransferListener<I,O> with TransferListener<> in method public initiateTransfer(source I, sink O, sourceListener ChannelListener<? super I>, sinkListener ChannelListener<? super O>, readExceptionHandler ChannelExceptionHandler<? super I>, writeExceptionHandler ChannelExceptionHandler<? super O>, pool ByteBufferPool) : void from class io.undertow.util.Transfer


        public IoFuture<WebSocketChannel> connect() {
            return connectImpl(uri, new FutureResult<>(), 0);
        }

        public IoFuture<WebSocketChannel> connect() {
            return connectImpl(uri, new FutureResult<WebSocketChannel>(), 0);
        }

Replace Generic With Diamond FutureResult<WebSocketChannel> with FutureResult<> in method public connect() : IoFuture<WebSocketChannel> from class io.undertow.websockets.client.WebSocketClient.ConnectionBuilder


    protected void createStateMachine(final String[] originalItems, final String className, final ClassFile file, final ClassMethod sctor, final AtomicInteger fieldCounter, final String methodName, final CustomStateMachine stateMachine, boolean expectNewline) {

        //list of all states except the initial
        final List<State> allStates = new ArrayList<>();
        final State initial = new State((byte) 0, "");
        for (String value : originalItems) {
            addStates(initial, value, allStates);
        }
        //we want initial to be number 0
        final AtomicInteger stateCounter = new AtomicInteger(-1);
        setupStateNo(initial, stateCounter, fieldCounter);
        for (State state : allStates) {
            setupStateNo(state, stateCounter, fieldCounter);
            createStateField(state, file, sctor.getCodeAttribute());
        }

        final int noStates = stateCounter.get();

        final ClassMethod handle = file.addMethod(Modifier.PROTECTED | Modifier.FINAL, methodName, "V", DescriptorUtils.makeDescriptor(ByteBuffer.class), parseStateDescriptor, httpExchangeDescriptor);
        handle.addCheckedExceptions(BAD_REQUEST_EXCEPTION);
        writeStateMachine(className, file, handle.getCodeAttribute(), initial, allStates, noStates, stateMachine, expectNewline);
    }

    protected void createStateMachine(final String[] originalItems, final String className, final ClassFile file, final ClassMethod sctor, final AtomicInteger fieldCounter, final String methodName, final CustomStateMachine stateMachine, boolean expectNewline) {

        //list of all states except the initial
        final List<State> allStates = new ArrayList<State>();
        final State initial = new State((byte) 0, "");
        for (String value : originalItems) {
            addStates(initial, value, allStates);
        }
        //we want initial to be number 0
        final AtomicInteger stateCounter = new AtomicInteger(-1);
        setupStateNo(initial, stateCounter, fieldCounter);
        for (State state : allStates) {
            setupStateNo(state, stateCounter, fieldCounter);
            createStateField(state, file, sctor.getCodeAttribute());
        }

        final int noStates = stateCounter.get();

        final ClassMethod handle = file.addMethod(Modifier.PROTECTED | Modifier.FINAL, methodName, "V", DescriptorUtils.makeDescriptor(ByteBuffer.class), parseStateDescriptor, httpExchangeDescriptor);
        handle.addCheckedExceptions(BAD_REQUEST_EXCEPTION);
        writeStateMachine(className, file, handle.getCodeAttribute(), initial, allStates, noStates, stateMachine, expectNewline);
    }

Replace Generic With Diamond ArrayList<State> with ArrayList<> in method protected createStateMachine(originalItems String[], className String, file ClassFile, sctor ClassMethod, fieldCounter AtomicInteger, methodName String, stateMachine CustomStateMachine, expectNewline boolean) : void from class io.undertow.annotationprocessor.AbstractParserGenerator


    private void invokeState(final String className, final ClassFile file, final CodeAttribute c, final State currentState, final State initialState, final CodeLocation noStateStart, final CodeLocation prefixStart, final CodeLocation returnIncompleteCode, final CodeLocation returnCompleteCode, final CustomStateMachine stateMachine, boolean expectNewline) {
        currentState.mark(c);

        BranchEnd parseDone = null;

        if (currentState == initialState) {
            //if this is the initial state there is a possibility that we need to deal with a left over character first
            //we need to see if we start with a left over character
            c.aload(PARSE_STATE_VAR);
            c.getfield(parseStateClass, "leftOver", "B");
            c.dup();
            final BranchEnd end = c.ifne();
            c.pop();
            //load 2 copies of the current byte into the stack
            handleReturnIfNoMoreBytes(c, returnIncompleteCode);
            c.aload(BYTE_BUFFER_VAR);
            c.invokevirtual(ByteBuffer.class.getName(), "get", "()B");
            BranchEnd cont = c.gotoInstruction();
            c.branchEnd(end);
            c.aload(PARSE_STATE_VAR);
            c.iconst(0);
            c.putfield(parseStateClass, "leftOver", "B");

            c.branchEnd(cont);

        } else {
            handleReturnIfNoMoreBytes(c, returnIncompleteCode);
            //load 2 copies of the current byte into the stack
            c.aload(BYTE_BUFFER_VAR);
            c.invokevirtual(ByteBuffer.class.getName(), "get", "()B");
        }

        c.dup();
        final Set<BranchEnd> tokenEnds = new LinkedHashSet<>();
        final Set<BranchEnd> badTokenEnds = new LinkedHashSet<>();
        final Map<State, BranchEnd> ends = new IdentityHashMap<>();
        for (State state : currentState.next.values()) {
            c.iconst(state.value);
            ends.put(state, c.ifIcmpeq());
            c.dup();
        }
        if (stateMachine.isHeader()) {
            c.iconst(':');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\r');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\n');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst(' ');
            tokenEnds.add(c.ifIcmpeq());
        }else if (expectNewline) {
            c.iconst('\r');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\n');
            tokenEnds.add(c.ifIcmpeq());
        } else {
            c.iconst(' ');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\r');
            badTokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\n');
            badTokenEnds.add(c.ifIcmpeq());
        }

        c.iconst(NO_STATE);
        c.istore(CURRENT_STATE_VAR);

        //create the string builder
        c.aload(STATE_STRING_BUILDER_VAR);
        c.ldc(currentState.soFar);
        c.invokevirtual(StringBuilder.class.getName(), "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
        c.swap();
        c.invokevirtual(StringBuilder.class.getName(), "append", "(C)Ljava/lang/StringBuilder;");
        c.pop();

        c.gotoInstruction(noStateStart);

        if(!badTokenEnds.isEmpty()) {
            //handle the space case
            for (BranchEnd b : badTokenEnds) {
                c.branchEnd(b);
            }
            c.newInstruction(BAD_REQUEST_EXCEPTION);
            c.dup();
            c.invokespecial(BAD_REQUEST_EXCEPTION, "<init>", "()V");
            c.athrow();
        }
        //now we write out tokenEnd
        for (BranchEnd tokenEnd : tokenEnds) {
            c.branchEnd(tokenEnd);
        }

        if (!currentState.soFar.isEmpty()) {
            c.getstatic(file.getName(), currentState.httpStringFieldName, HTTP_STRING_DESCRIPTOR);
            stateMachine.handleStateMachineMatchedToken(c);
            //TODO: exit if it returns null
            tokenDone(c, returnCompleteCode, stateMachine);
        } else {
            if (stateMachine.initialNewlineMeansRequestDone()) {
                c.iconst('\n');
                parseDone = c.ifIcmpeq();
            } else {
                c.pop();
            }
            setupLocalVariables(c);
            handleReturnIfNoMoreBytes(c, returnIncompleteCode);
            initialState.jumpTo(c);
        }

        for (Map.Entry<State, BranchEnd> e : ends.entrySet()) {
            c.branchEnd(e.getValue());
            c.pop();
            final State state = e.getKey();
            if (state.stateno < 0) {
                //prefix match
                c.iconst(state.stateno);
                c.istore(CURRENT_STATE_VAR);
                c.getstatic(className, state.httpStringFieldName, HTTP_STRING_DESCRIPTOR);
                c.astore(STATE_CURRENT_VAR);
                c.getstatic(className, state.fieldName, "[B");
                c.astore(STATE_CURRENT_BYTES_VAR);
                c.iconst(state.soFar.length());
                c.istore(STATE_POS_VAR);
                c.gotoInstruction(prefixStart);
            } else {

                c.iconst(state.stateno);
                c.istore(CURRENT_STATE_VAR);
                state.jumpTo(c);
            }
        }
        if (parseDone != null) {
            c.branchEnd(parseDone);

            c.aload(PARSE_STATE_VAR);
            c.invokevirtual(parseStateClass, "parseComplete", "()V");
            c.iconst(0);
            c.returnInstruction();
        }
    }

    private void invokeState(final String className, final ClassFile file, final CodeAttribute c, final State currentState, final State initialState, final CodeLocation noStateStart, final CodeLocation prefixStart, final CodeLocation returnIncompleteCode, final CodeLocation returnCompleteCode, final CustomStateMachine stateMachine, boolean expectNewline) {
        currentState.mark(c);

        BranchEnd parseDone = null;

        if (currentState == initialState) {
            //if this is the initial state there is a possibility that we need to deal with a left over character first
            //we need to see if we start with a left over character
            c.aload(PARSE_STATE_VAR);
            c.getfield(parseStateClass, "leftOver", "B");
            c.dup();
            final BranchEnd end = c.ifne();
            c.pop();
            //load 2 copies of the current byte into the stack
            handleReturnIfNoMoreBytes(c, returnIncompleteCode);
            c.aload(BYTE_BUFFER_VAR);
            c.invokevirtual(ByteBuffer.class.getName(), "get", "()B");
            BranchEnd cont = c.gotoInstruction();
            c.branchEnd(end);
            c.aload(PARSE_STATE_VAR);
            c.iconst(0);
            c.putfield(parseStateClass, "leftOver", "B");

            c.branchEnd(cont);

        } else {
            handleReturnIfNoMoreBytes(c, returnIncompleteCode);
            //load 2 copies of the current byte into the stack
            c.aload(BYTE_BUFFER_VAR);
            c.invokevirtual(ByteBuffer.class.getName(), "get", "()B");
        }

        c.dup();
        final Set<BranchEnd> tokenEnds = new LinkedHashSet<>();
        final Set<BranchEnd> badTokenEnds = new LinkedHashSet<>();
        final Map<State, BranchEnd> ends = new IdentityHashMap<State, BranchEnd>();
        for (State state : currentState.next.values()) {
            c.iconst(state.value);
            ends.put(state, c.ifIcmpeq());
            c.dup();
        }
        if (stateMachine.isHeader()) {
            c.iconst(':');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\r');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\n');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst(' ');
            tokenEnds.add(c.ifIcmpeq());
        }else if (expectNewline) {
            c.iconst('\r');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\n');
            tokenEnds.add(c.ifIcmpeq());
        } else {
            c.iconst(' ');
            tokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\r');
            badTokenEnds.add(c.ifIcmpeq());
            c.dup();
            c.iconst('\n');
            badTokenEnds.add(c.ifIcmpeq());
        }

        c.iconst(NO_STATE);
        c.istore(CURRENT_STATE_VAR);

        //create the string builder
        c.aload(STATE_STRING_BUILDER_VAR);
        c.ldc(currentState.soFar);
        c.invokevirtual(StringBuilder.class.getName(), "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
        c.swap();
        c.invokevirtual(StringBuilder.class.getName(), "append", "(C)Ljava/lang/StringBuilder;");
        c.pop();

        c.gotoInstruction(noStateStart);

        if(!badTokenEnds.isEmpty()) {
            //handle the space case
            for (BranchEnd b : badTokenEnds) {
                c.branchEnd(b);
            }
            c.newInstruction(BAD_REQUEST_EXCEPTION);
            c.dup();
            c.invokespecial(BAD_REQUEST_EXCEPTION, "<init>", "()V");
            c.athrow();
        }
        //now we write out tokenEnd
        for (BranchEnd tokenEnd : tokenEnds) {
            c.branchEnd(tokenEnd);
        }

        if (!currentState.soFar.isEmpty()) {
            c.getstatic(file.getName(), currentState.httpStringFieldName, HTTP_STRING_DESCRIPTOR);
            stateMachine.handleStateMachineMatchedToken(c);
            //TODO: exit if it returns null
            tokenDone(c, returnCompleteCode, stateMachine);
        } else {
            if (stateMachine.initialNewlineMeansRequestDone()) {
                c.iconst('\n');
                parseDone = c.ifIcmpeq();
            } else {
                c.pop();
            }
            setupLocalVariables(c);
            handleReturnIfNoMoreBytes(c, returnIncompleteCode);
            initialState.jumpTo(c);
        }

        for (Map.Entry<State, BranchEnd> e : ends.entrySet()) {
            c.branchEnd(e.getValue());
            c.pop();
            final State state = e.getKey();
            if (state.stateno < 0) {
                //prefix match
                c.iconst(state.stateno);
                c.istore(CURRENT_STATE_VAR);
                c.getstatic(className, state.httpStringFieldName, HTTP_STRING_DESCRIPTOR);
                c.astore(STATE_CURRENT_VAR);
                c.getstatic(className, state.fieldName, "[B");
                c.astore(STATE_CURRENT_BYTES_VAR);
                c.iconst(state.soFar.length());
                c.istore(STATE_POS_VAR);
                c.gotoInstruction(prefixStart);
            } else {

                c.iconst(state.stateno);
                c.istore(CURRENT_STATE_VAR);
                state.jumpTo(c);
            }
        }
        if (parseDone != null) {
            c.branchEnd(parseDone);

            c.aload(PARSE_STATE_VAR);
            c.invokevirtual(parseStateClass, "parseComplete", "()V");
            c.iconst(0);
            c.returnInstruction();
        }
    }

Replace Generic With Diamond IdentityHashMap<State,BranchEnd> with IdentityHashMap<> in method private invokeState(className String, file ClassFile, c CodeAttribute, currentState State, initialState State, noStateStart CodeLocation, prefixStart CodeLocation, returnIncompleteCode CodeLocation, returnCompleteCode CodeLocation, stateMachine CustomStateMachine, expectNewline boolean) : void from class io.undertow.annotationprocessor.AbstractParserGenerator


    public void parse(Map<String, RewriteMap> maps) {
        // Parse the substitution
        if (!"-".equals(substitutionString)) {
            substitution = new Substitution();
            substitution.setSub(substitutionString);
            substitution.parse(maps);
        }
        // Parse the pattern
        int flags = 0;
        if (isNocase()) {
            flags |= Pattern.CASE_INSENSITIVE;
        }
        Pattern.compile(patternString, flags);
        // Parse conditions
        for (int i = 0; i < conditions.length; i++) {
            conditions[i].parse(maps);
        }
        // Parse flag which have substitution values
        if (isEnv()) {
            for (int i = 0; i < envValue.size(); i++) {
                Substitution newEnvSubstitution = new Substitution();
                newEnvSubstitution.setSub(envValue.get(i));
                newEnvSubstitution.parse(maps);
                envSubstitution.add(newEnvSubstitution);
                envResult.add(new ThreadLocal<>());
            }
        }
        if (isCookie()) {
            cookieSubstitution = new Substitution();
            cookieSubstitution.setSub(cookieValue);
            cookieSubstitution.parse(maps);
        }
    }

    public void parse(Map<String, RewriteMap> maps) {
        // Parse the substitution
        if (!"-".equals(substitutionString)) {
            substitution = new Substitution();
            substitution.setSub(substitutionString);
            substitution.parse(maps);
        }
        // Parse the pattern
        int flags = 0;
        if (isNocase()) {
            flags |= Pattern.CASE_INSENSITIVE;
        }
        Pattern.compile(patternString, flags);
        // Parse conditions
        for (int i = 0; i < conditions.length; i++) {
            conditions[i].parse(maps);
        }
        // Parse flag which have substitution values
        if (isEnv()) {
            for (int i = 0; i < envValue.size(); i++) {
                Substitution newEnvSubstitution = new Substitution();
                newEnvSubstitution.setSub(envValue.get(i));
                newEnvSubstitution.parse(maps);
                envSubstitution.add(newEnvSubstitution);
                envResult.add(new ThreadLocal<String>());
            }
        }
        if (isCookie()) {
            cookieSubstitution = new Substitution();
            cookieSubstitution.setSub(cookieValue);
            cookieSubstitution.parse(maps);
        }
    }

Replace Generic With Diamond ThreadLocal<String> with ThreadLocal<> in method public parse(maps Map<String,RewriteMap>) : void from class io.undertow.servlet.compat.rewrite.RewriteRule


    public void parse(Map<String, RewriteMap> maps) {

        ArrayList<SubstitutionElement> elements = new ArrayList<>();
        int pos = 0;
        int percentPos = 0;
        int dollarPos = 0;

        while (pos < sub.length()) {
            percentPos = sub.indexOf('%', pos);
            dollarPos = sub.indexOf('$', pos);
            if (percentPos == -1 && dollarPos == -1) {
                // Static text
                StaticElement newElement = new StaticElement();
                newElement.value = sub.substring(pos, sub.length());
                pos = sub.length();
                elements.add(newElement);
            } else if (percentPos == -1 || ((dollarPos != -1) && (dollarPos < percentPos))) {
                // $: back reference to rule or map lookup
                if (dollarPos + 1 == sub.length()) {
                    throw new IllegalArgumentException(sub);
                }
                if (pos < dollarPos) {
                    // Static text
                    StaticElement newElement = new StaticElement();
                    newElement.value = sub.substring(pos, dollarPos);
                    pos = dollarPos;
                    elements.add(newElement);
                }
                if (Character.isDigit(sub.charAt(dollarPos + 1))) {
                    // $: back reference to rule
                    RewriteRuleBackReferenceElement newElement = new RewriteRuleBackReferenceElement();
                    newElement.n = Character.digit(sub.charAt(dollarPos + 1), 10);
                    pos = dollarPos + 2;
                    elements.add(newElement);
                } else {
                    // $: map lookup as ${mapname:key|default}
                    MapElement newElement = new MapElement();
                    int open = sub.indexOf('{', dollarPos);
                    int colon = sub.indexOf(':', dollarPos);
                    int def = sub.indexOf('|', dollarPos);
                    int close = sub.indexOf('}', dollarPos);
                    if (!(-1 < open && open < colon && colon < close)) {
                        throw new IllegalArgumentException(sub);
                    }
                    newElement.map = maps.get(sub.substring(open + 1, colon));
                    if (newElement.map == null) {
                        throw new IllegalArgumentException(sub + ": No map: " + sub.substring(open + 1, colon));
                    }
                    if (def > -1) {
                        if (!(colon < def && def < close)) {
                            throw new IllegalArgumentException(sub);
                        }
                        newElement.key = sub.substring(colon + 1, def);
                        newElement.defaultValue = sub.substring(def + 1, close);
                    } else {
                        newElement.key = sub.substring(colon + 1, close);
                    }
                    pos = close + 1;
                    elements.add(newElement);
                }
            } else {
                // %: back reference to condition or server variable
                if (percentPos + 1 == sub.length()) {
                    throw new IllegalArgumentException(sub);
                }
                if (pos < percentPos) {
                    // Static text
                    StaticElement newElement = new StaticElement();
                    newElement.value = sub.substring(pos, percentPos);
                    pos = percentPos;
                    elements.add(newElement);
                }
                if (Character.isDigit(sub.charAt(percentPos + 1))) {
                    // %: back reference to condition
                    RewriteCondBackReferenceElement newElement = new RewriteCondBackReferenceElement();
                    newElement.n = Character.digit(sub.charAt(percentPos + 1), 10);
                    pos = percentPos + 2;
                    elements.add(newElement);
                } else {
                    // %: server variable as %{variable}
                    SubstitutionElement newElement = null;
                    int open = sub.indexOf('{', percentPos);
                    int colon = sub.indexOf(':', percentPos);
                    int close = sub.indexOf('}', percentPos);
                    if (!(-1 < open && open < close)) {
                        throw new IllegalArgumentException(sub);
                    }
                    if (colon > -1) {
                        if (!(open < colon && colon < close)) {
                            throw new IllegalArgumentException(sub);
                        }
                        String type = sub.substring(open + 1, colon);
                        if (type.equals("ENV")) {
                            newElement = new ServerVariableEnvElement();
                            ((ServerVariableEnvElement) newElement).key = sub.substring(colon + 1, close);
                        } else if (type.equals("SSL")) {
                            newElement = new ServerVariableSslElement();
                            ((ServerVariableSslElement) newElement).key = sub.substring(colon + 1, close);
                        } else if (type.equals("HTTP")) {
                            newElement = new ServerVariableHttpElement();
                            ((ServerVariableHttpElement) newElement).key = sub.substring(colon + 1, close);
                        } else {
                            throw new IllegalArgumentException(sub + ": Bad type: " + type);
                        }
                    } else {
                        newElement = new ServerVariableElement();
                        ((ServerVariableElement) newElement).key = sub.substring(open + 1, close);
                    }
                    pos = close + 1;
                    elements.add(newElement);
                }
            }
        }

        this.elements = elements.toArray(new SubstitutionElement[0]);

    }

    public void parse(Map<String, RewriteMap> maps) {

        ArrayList<SubstitutionElement> elements = new ArrayList<SubstitutionElement>();
        int pos = 0;
        int percentPos = 0;
        int dollarPos = 0;

        while (pos < sub.length()) {
            percentPos = sub.indexOf('%', pos);
            dollarPos = sub.indexOf('$', pos);
            if (percentPos == -1 && dollarPos == -1) {
                // Static text
                StaticElement newElement = new StaticElement();
                newElement.value = sub.substring(pos, sub.length());
                pos = sub.length();
                elements.add(newElement);
            } else if (percentPos == -1 || ((dollarPos != -1) && (dollarPos < percentPos))) {
                // $: back reference to rule or map lookup
                if (dollarPos + 1 == sub.length()) {
                    throw new IllegalArgumentException(sub);
                }
                if (pos < dollarPos) {
                    // Static text
                    StaticElement newElement = new StaticElement();
                    newElement.value = sub.substring(pos, dollarPos);
                    pos = dollarPos;
                    elements.add(newElement);
                }
                if (Character.isDigit(sub.charAt(dollarPos + 1))) {
                    // $: back reference to rule
                    RewriteRuleBackReferenceElement newElement = new RewriteRuleBackReferenceElement();
                    newElement.n = Character.digit(sub.charAt(dollarPos + 1), 10);
                    pos = dollarPos + 2;
                    elements.add(newElement);
                } else {
                    // $: map lookup as ${mapname:key|default}
                    MapElement newElement = new MapElement();
                    int open = sub.indexOf('{', dollarPos);
                    int colon = sub.indexOf(':', dollarPos);
                    int def = sub.indexOf('|', dollarPos);
                    int close = sub.indexOf('}', dollarPos);
                    if (!(-1 < open && open < colon && colon < close)) {
                        throw new IllegalArgumentException(sub);
                    }
                    newElement.map = maps.get(sub.substring(open + 1, colon));
                    if (newElement.map == null) {
                        throw new IllegalArgumentException(sub + ": No map: " + sub.substring(open + 1, colon));
                    }
                    if (def > -1) {
                        if (!(colon < def && def < close)) {
                            throw new IllegalArgumentException(sub);
                        }
                        newElement.key = sub.substring(colon + 1, def);
                        newElement.defaultValue = sub.substring(def + 1, close);
                    } else {
                        newElement.key = sub.substring(colon + 1, close);
                    }
                    pos = close + 1;
                    elements.add(newElement);
                }
            } else {
                // %: back reference to condition or server variable
                if (percentPos + 1 == sub.length()) {
                    throw new IllegalArgumentException(sub);
                }
                if (pos < percentPos) {
                    // Static text
                    StaticElement newElement = new StaticElement();
                    newElement.value = sub.substring(pos, percentPos);
                    pos = percentPos;
                    elements.add(newElement);
                }
                if (Character.isDigit(sub.charAt(percentPos + 1))) {
                    // %: back reference to condition
                    RewriteCondBackReferenceElement newElement = new RewriteCondBackReferenceElement();
                    newElement.n = Character.digit(sub.charAt(percentPos + 1), 10);
                    pos = percentPos + 2;
                    elements.add(newElement);
                } else {
                    // %: server variable as %{variable}
                    SubstitutionElement newElement = null;
                    int open = sub.indexOf('{', percentPos);
                    int colon = sub.indexOf(':', percentPos);
                    int close = sub.indexOf('}', percentPos);
                    if (!(-1 < open && open < close)) {
                        throw new IllegalArgumentException(sub);
                    }
                    if (colon > -1) {
                        if (!(open < colon && colon < close)) {
                            throw new IllegalArgumentException(sub);
                        }
                        String type = sub.substring(open + 1, colon);
                        if (type.equals("ENV")) {
                            newElement = new ServerVariableEnvElement();
                            ((ServerVariableEnvElement) newElement).key = sub.substring(colon + 1, close);
                        } else if (type.equals("SSL")) {
                            newElement = new ServerVariableSslElement();
                            ((ServerVariableSslElement) newElement).key = sub.substring(colon + 1, close);
                        } else if (type.equals("HTTP")) {
                            newElement = new ServerVariableHttpElement();
                            ((ServerVariableHttpElement) newElement).key = sub.substring(colon + 1, close);
                        } else {
                            throw new IllegalArgumentException(sub + ": Bad type: " + type);
                        }
                    } else {
                        newElement = new ServerVariableElement();
                        ((ServerVariableElement) newElement).key = sub.substring(open + 1, close);
                    }
                    pos = close + 1;
                    elements.add(newElement);
                }
            }
        }

        this.elements = elements.toArray(new SubstitutionElement[0]);

    }

Replace Generic With Diamond ArrayList<SubstitutionElement> with ArrayList<> in method public parse(maps Map<String,RewriteMap>) : void from class io.undertow.servlet.compat.rewrite.Substitution