    /**
     * NOTE the tests using this will currently succeed for the wrong reasons,
     * because the data-changing transaction does not actually release the
     * schema read lock early enough for the PopulatingUpdater to come into
     * play.
     */
    private Future<?> applyChangesToPopulatingUpdater(
            long blockDataChangeTransactionOnLockOnId,
            long blockPopulatorOnLockOnId,
            final Action... actions ) throws InterruptedException, ExecutionException
    {
        // We want to issue an update to an index populator for a constraint.
        // However, creating a constraint takes a schema write lock, while
        // creating nodes and setting their properties takes a schema read
        // lock. We need to sneak past these locks.
        final CountDownLatch createNodeReadyLatch = new CountDownLatch( 1 );
        final CountDownLatch createNodeCommitLatch = new CountDownLatch( 1 );
        Future<?> updatingTransaction = executor.submit( () ->
        {
            try ( Transaction tx = db.beginTx() )
            {
                for ( Action action : actions )
                {
                    action.accept( tx );
                }
                tx.success();
                createNodeReadyLatch.countDown();
                awaitUninterruptibly( createNodeCommitLatch );
            }
        } );
        createNodeReadyLatch.await();

        // The above transaction now contain the changes we want to expose to
        // the IndexUpdater as updates. This will happen when we commit the
        // transaction. The transaction now also holds the schema read lock,
        // so we can't begin creating our constraint just yet.
        // We first have to unlock the schema, and then block just before we
        // send off our updates. We can do that by making another thread take a
        // read lock on the node we just created, and then initiate our commit.
        Lock lockBlockingDataChangeTransaction = getLockService().acquireNodeLock(
                blockDataChangeTransactionOnLockOnId,
                LockType.WRITE_LOCK );

        // Before we begin creating the constraint, we take a write lock on an
        // "earlier" node, to hold up the populator for the constraint index.
        Lock lockBlockingIndexPopulator = getLockService().acquireNodeLock(
                blockPopulatorOnLockOnId,
                LockType.WRITE_LOCK );

        // This thread tries to create a constraint. It should block, waiting for it's
        // population job to finish, and it's population job should in turn be blocked
        // on the lockBlockingIndexPopulator above:
        final CountDownLatch createConstraintTransactionStarted = new CountDownLatch( 1 );
        Future<?> createConstraintTransaction = executor.submit(
                () -> createUniqueConstraint( createConstraintTransactionStarted ) );
        createConstraintTransactionStarted.await();

        // Now we can initiate the data-changing commit. It should then
        // release the schema read lock, and block on the
        // lockBlockingDataChangeTransaction.
        createNodeCommitLatch.countDown();

        // Now we can issue updates to the populator in the still ongoing population job.
        // We do that by releasing the lock that is currently preventing our
        // data-changing transaction from committing.
        lockBlockingDataChangeTransaction.release();

        // And we observe that our updating transaction has completed as well:
        updatingTransaction.get();

        // Now we can release the lock blocking the populator, allowing it to finish:
        lockBlockingIndexPopulator.release();

        // And return the future for examination:
        return createConstraintTransaction;
    }

    /**
     * NOTE the tests using this will currently succeed for the wrong reasons,
     * because the data-changing transaction does not actually release the
     * schema read lock early enough for the PopulatingUpdater to come into
     * play.
     */
    private Future<?> applyChangesToPopulatingUpdater(
            long blockDataChangeTransactionOnLockOnId,
            long blockPopulatorOnLockOnId,
            final Action... actions ) throws InterruptedException, ExecutionException
    {
        // We want to issue an update to an index populator for a constraint.
        // However, creating a constraint takes a schema write lock, while
        // creating nodes and setting their properties takes a schema read
        // lock. We need to sneak past these locks.
        final CountDownLatch createNodeReadyLatch = new CountDownLatch( 1 );
        final CountDownLatch createNodeCommitLatch = new CountDownLatch( 1 );
        Future<?> updatingTransaction = executor.submit( new Runnable()
        {
            @Override
            public void run()
            {
                try ( Transaction tx = db.beginTx() )
                {
                    for ( Action action : actions )
                    {
                        action.accept( tx );
                    }
                    tx.success();
                    createNodeReadyLatch.countDown();
                    awaitUninterruptibly( createNodeCommitLatch );
                }
            }
        } );
        createNodeReadyLatch.await();

        // The above transaction now contain the changes we want to expose to
        // the IndexUpdater as updates. This will happen when we commit the
        // transaction. The transaction now also holds the schema read lock,
        // so we can't begin creating our constraint just yet.
        // We first have to unlock the schema, and then block just before we
        // send off our updates. We can do that by making another thread take a
        // read lock on the node we just created, and then initiate our commit.
        Lock lockBlockingDataChangeTransaction = getLockService().acquireNodeLock(
                blockDataChangeTransactionOnLockOnId,
                LockType.WRITE_LOCK );

        // Before we begin creating the constraint, we take a write lock on an
        // "earlier" node, to hold up the populator for the constraint index.
        Lock lockBlockingIndexPopulator = getLockService().acquireNodeLock(
                blockPopulatorOnLockOnId,
                LockType.WRITE_LOCK );

        // This thread tries to create a constraint. It should block, waiting for it's
        // population job to finish, and it's population job should in turn be blocked
        // on the lockBlockingIndexPopulator above:
        final CountDownLatch createConstraintTransactionStarted = new CountDownLatch( 1 );
        Future<?> createConstraintTransaction = executor.submit( new Runnable()
        {
            @Override
            public void run()
            {

                createUniqueConstraint( createConstraintTransactionStarted );
            }
        } );
        createConstraintTransactionStarted.await();

        // Now we can initiate the data-changing commit. It should then
        // release the schema read lock, and block on the
        // lockBlockingDataChangeTransaction.
        createNodeCommitLatch.countDown();

        // Now we can issue updates to the populator in the still ongoing population job.
        // We do that by releasing the lock that is currently preventing our
        // data-changing transaction from committing.
        lockBlockingDataChangeTransaction.release();

        // And we observe that our updating transaction has completed as well:
        updatingTransaction.get();

        // Now we can release the lock blocking the populator, allowing it to finish:
        lockBlockingIndexPopulator.release();

        // And return the future for examination:
        return createConstraintTransaction;
    }

Replace Anonymous With Lambda org.neo4j.kernel.api.index.UniqueConstraintCompatibility.applyChangesToPopulatingUpdater.updatingTransaction.submit.new Runnable with () -> {try(Transaction tx=db.beginTx())for(Action action: actions){action.accept(tx); in method private applyChangesToPopulatingUpdater(blockDataChangeTransactionOnLockOnId long, blockPopulatorOnLockOnId long, actions Action...) : Future<?> from class org.neo4j.kernel.api.index.UniqueConstraintCompatibility


    private OtherThreadExecutor.WorkerCommand<Void, Void> dropTheIndex( final FlippableIndexProxy flippable )
    {
        return state ->
        {
            awaitFuture( flippable.drop() );
            return null;
        };
    }

    private OtherThreadExecutor.WorkerCommand<Void, Void> dropTheIndex( final FlippableIndexProxy flippable )
    {
        return new OtherThreadExecutor.WorkerCommand<Void, Void>()
        {
            @Override
            public Void doWork( Void state ) throws IOException
            {
                awaitFuture( flippable.drop() );
                return null;
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.api.index.FlippableIndexProxyTest.dropTheIndex.new OtherThreadExecutor.WorkerCommand<Void,Void> with state -> {awaitFuture(flippable.drop()); in method private dropTheIndex(flippable FlippableIndexProxy) : OtherThreadExecutor.WorkerCommand<Void,Void> from class org.neo4j.kernel.impl.api.index.FlippableIndexProxyTest


    private OtherThreadExecutor.WorkerCommand<Void, Void> startFlipAndWaitForLatchBeforeFinishing(
            final FlippableIndexProxy flippable, final CountDownLatch triggerFinishFlip,
            final CountDownLatch triggerExternalAccess )
    {
        return state ->
        {
            flippable.flip( () ->
            {
                triggerExternalAccess.countDown();
                assertTrue( awaitLatch( triggerFinishFlip ) );
                return null;
            }, null );
            return null;
        };
    }

    private OtherThreadExecutor.WorkerCommand<Void, Void> startFlipAndWaitForLatchBeforeFinishing(
            final FlippableIndexProxy flippable, final CountDownLatch triggerFinishFlip,
            final CountDownLatch triggerExternalAccess )
    {
        return new OtherThreadExecutor.WorkerCommand<Void, Void>()
        {
            @Override
            public Void doWork( Void state ) throws FlipFailedKernelException
            {
                flippable.flip( new Callable<Void>()
                {
                    @Override
                    public Void call()
                    {
                        triggerExternalAccess.countDown();
                        assertTrue( awaitLatch( triggerFinishFlip ) );
                        return null;
                    }
                }, null );
                return null;
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.api.index.FlippableIndexProxyTest.startFlipAndWaitForLatchBeforeFinishing.new OtherThreadExecutor.WorkerCommand<Void,Void> with state -> {flippable.flip(() -> { in method private startFlipAndWaitForLatchBeforeFinishing(flippable FlippableIndexProxy, triggerFinishFlip CountDownLatch, triggerExternalAccess CountDownLatch) : OtherThreadExecutor.WorkerCommand<Void,Void> from class org.neo4j.kernel.impl.api.index.FlippableIndexProxyTest


                @Override
                public void remove( PrimitiveLongSet nodeIds ) throws IOException
                {
                    nodeIds.visitKeys( nodeId ->
                    {
                        recoveredNodes.add( nodeId );
                        return false;
                    } );
                }

                @Override
                public void remove( PrimitiveLongSet nodeIds ) throws IOException
                {
                    nodeIds.visitKeys( new PrimitiveLongVisitor<RuntimeException>()
                    {
                        @Override
                        public boolean visited( long nodeId ) throws RuntimeException
                        {
                            recoveredNodes.add( nodeId );
                            return false;
                        }
                    } );
                }

Replace Anonymous With Lambda org.neo4j.kernel.impl.api.index.IndexRecoveryIT.GatheringIndexWriter.newUpdater.new CollectingIndexUpdater.remove.visitKeys.new PrimitiveLongVisitor<RuntimeException> with nodeId -> {recoveredNodes.add(nodeId); in method public remove(nodeIds PrimitiveLongSet) : void from class org.neo4j.kernel.impl.api.index.IndexRecoveryIT.GatheringIndexWriter.newUpdater.new CollectingIndexUpdater


    private Future<Void> killDbInSeparateThread()
    {
        ExecutorService executor = newSingleThreadExecutor();
        Future<Void> result = executor.submit( () ->
        {
            killDb();
            return null;
        } );
        executor.shutdown();
        return result;
    }

    private Future<Void> killDbInSeparateThread()
    {
        ExecutorService executor = newSingleThreadExecutor();
        Future<Void> result = executor.submit( new Callable<Void>()
        {
            @Override
            public Void call() throws Exception
            {
                killDb();
                return null;
            }
        } );
        executor.shutdown();
        return result;
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.api.index.IndexRecoveryIT.killDbInSeparateThread.result.submit.new Callable<Void> with () -> {killDb(); in method private killDbInSeparateThread() : Future<Void> from class org.neo4j.kernel.impl.api.index.IndexRecoveryIT


    private long[] repeatCreateNamedPeopleFor( int totalNumberOfPeople ) throws Exception
    {
        // Parallelize the creation of persons
        final long[] nodes = new long[totalNumberOfPeople];
        final int threads = 100;
        final int peoplePerThread = totalNumberOfPeople / threads;

        final ExecutorService service = Executors.newFixedThreadPool( threads );
        final AtomicReference<KernelException> exception = new AtomicReference<>();

        final List<Callable<Void>> jobs = new ArrayList<>( threads );
        // Start threads that creates these people, relying on batched writes to speed things up
        for ( int i = 0; i < threads; i++ )
        {
            final int finalI = i;

            jobs.add( () ->
            {
                int offset = finalI * peoplePerThread;
                while ( offset < (finalI + 1) * peoplePerThread )
                {
                    try
                    {
                        offset += createNamedPeople( nodes, offset );
                    }
                    catch ( KernelException e )
                    {
                        exception.compareAndSet( null, e );
                        throw new RuntimeException( e );
                    }
                }
                return null;
            } );
        }

        for ( Future<?> job : service.invokeAll( jobs ) )
        {
            job.get();
        }

        service.awaitTermination( 1, TimeUnit.SECONDS );
        service.shutdown();

        // Make any KernelException thrown from a creation thread visible in the main thread
        Exception ex = exception.get();
        if ( ex != null )
        {
            throw ex;
        }

        return nodes;
    }

    private long[] repeatCreateNamedPeopleFor( int totalNumberOfPeople ) throws Exception
    {
        // Parallelize the creation of persons
        final long[] nodes = new long[totalNumberOfPeople];
        final int threads = 100;
        final int peoplePerThread = totalNumberOfPeople / threads;

        final ExecutorService service = Executors.newFixedThreadPool( threads );
        final AtomicReference<KernelException> exception = new AtomicReference<>();

        final List<Callable<Void>> jobs = new ArrayList<>( threads );
        // Start threads that creates these people, relying on batched writes to speed things up
        for ( int i = 0; i < threads; i++ )
        {
            final int finalI = i;

            jobs.add( new Callable<Void>()
            {
                @Override
                public Void call() throws Exception
                {
                    int offset = finalI * peoplePerThread;
                    while ( offset < (finalI + 1) * peoplePerThread )
                    {
                        try
                        {
                            offset += createNamedPeople( nodes, offset );
                        }
                        catch ( KernelException e )
                        {
                            exception.compareAndSet( null, e );
                            throw new RuntimeException( e );
                        }
                    }
                    return null;
                }
            } );
        }

        for ( Future<?> job : service.invokeAll( jobs ) )
        {
            job.get();
        }

        service.awaitTermination( 1, TimeUnit.SECONDS );
        service.shutdown();

        // Make any KernelException thrown from a creation thread visible in the main thread
        Exception ex = exception.get();
        if ( ex != null )
        {
            throw ex;
        }

        return nodes;
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.api.index.IndexStatisticsTest.repeatCreateNamedPeopleFor.add.new Callable<Void> with () -> {int offset=finalI * peoplePerThread; in method private repeatCreateNamedPeopleFor(totalNumberOfPeople int) : long[] from class org.neo4j.kernel.impl.api.index.IndexStatisticsTest


    private WorkerCommand<Void, Lock> acquireWriteLock( final Node resource )
    {
        return state ->
        {
            try ( Transaction tx = db.beginTx() )
            {
                return tx.acquireWriteLock( resource );
            }
        };
    }

    private WorkerCommand<Void, Lock> acquireWriteLock( final Node resource )
    {
        return new WorkerCommand<Void, Lock>()
        {
            @Override
            public Lock doWork( Void state )
            {
                try ( Transaction tx = db.beginTx() )
                {
                    return tx.acquireWriteLock( resource );
                }
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.core.NestedTransactionLocksIT.acquireWriteLock.new WorkerCommand<Void,Lock> with state -> {try(Transaction tx=db.beginTx())return tx.acquireWriteLock(resource); in method private acquireWriteLock(resource Node) : WorkerCommand<Void,Lock> from class org.neo4j.kernel.impl.core.NestedTransactionLocksIT


    @Test
    public void getAllRelationshipsIteratorShouldPickUpHigherIdsThanHighIdWhenStarted() throws Exception
    {
        // GIVEN
        Transaction tx = db.beginTx();
        createRelationshipAssumingTxWith( "key", 1 );
        createRelationshipAssumingTxWith( "key", 2 );
        tx.success();
        tx.close();

        // WHEN
        tx = db.beginTx();
        Iterator<Relationship> allRelationships = db.getAllRelationships().iterator();

        Thread thread = new Thread( () ->
        {
            Transaction newTx = db.beginTx();
            assertThat( newTx, not( instanceOf( PlaceboTransaction.class ) ) );
            createRelationshipAssumingTxWith( "key", 3 );
            newTx.success();
            newTx.close();
        } );
        thread.start();
        thread.join();

        // THEN
        assertThat( addToCollection( allRelationships, new ArrayList<Relationship>() ).size(), is(3) );
        tx.success();
        tx.close();
    }

    @Test
    public void getAllRelationshipsIteratorShouldPickUpHigherIdsThanHighIdWhenStarted() throws Exception
    {
        // GIVEN
        Transaction tx = db.beginTx();
        createRelationshipAssumingTxWith( "key", 1 );
        createRelationshipAssumingTxWith( "key", 2 );
        tx.success();
        tx.close();

        // WHEN
        tx = db.beginTx();
        Iterator<Relationship> allRelationships = db.getAllRelationships().iterator();

        Thread thread = new Thread( new Runnable()
        {
            @Override
            public void run()
            {
                Transaction newTx = db.beginTx();
                assertThat( newTx, not( instanceOf( PlaceboTransaction.class ) ) );
                createRelationshipAssumingTxWith( "key", 3 );
                newTx.success();
                newTx.close();
            }
        } );
        thread.start();
        thread.join();

        // THEN
        assertThat( addToCollection( allRelationships, new ArrayList<Relationship>() ).size(), is(3) );
        tx.success();
        tx.close();
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.core.NodeManagerTest.getAllRelationshipsIteratorShouldPickUpHigherIdsThanHighIdWhenStarted.thread.new Thread.new Runnable with () -> {Transaction newTx=db.beginTx(); in method public getAllRelationshipsIteratorShouldPickUpHigherIdsThanHighIdWhenStarted() : void from class org.neo4j.kernel.impl.core.NodeManagerTest


    @Test
    public void getAllPropertiesShouldWorkFineWithConcurrentPropertyModifications() throws Exception
    {
        // Given
        ExecutorService executor = cleanup.add( Executors.newFixedThreadPool( 2, named( "Test-executor-thread" ) ) );

        final int propertiesCount = 100;

        final long nodeId;
        try ( Transaction tx = db.beginTx() )
        {
            Node node = db.createNode();
            nodeId = node.getId();
            for ( int i = 0; i < propertiesCount; i++ )
            {
                node.setProperty( "property-" + i, i );
            }
            tx.success();
        }

        final CountDownLatch start = new CountDownLatch( 1 );
        final AtomicBoolean writerDone = new AtomicBoolean();

        Runnable writer = () ->
        {
            try
            {
                awaitLatch( start );
                int propertyKey = 0;
                while ( propertyKey < propertiesCount )
                {
                    try ( Transaction tx = db.beginTx() )
                    {
                        Node node = db.getNodeById( nodeId );
                        for ( int i = 0; i < 10 && propertyKey < propertiesCount; i++, propertyKey++ )
                        {
                            node.setProperty( "property-" + propertyKey, UUID.randomUUID().toString() );
                        }
                        tx.success();
                    }
                }
            }
            finally
            {
                writerDone.set( true );
            }
        };
        Runnable reader = () ->
        {
            try ( Transaction tx = db.beginTx() )
            {
                Node node = db.getNodeById( nodeId );
                awaitLatch( start );
                while ( !writerDone.get() )
                {
                    int size = node.getAllProperties().size();
                    assertThat( size, greaterThan( 0 ) );
                }
                tx.success();
            }
        };

        Future<?> readerFuture = executor.submit( reader );
        Future<?> writerFuture = executor.submit( writer );

        start.countDown();

        // When
        writerFuture.get();
        readerFuture.get();

        // Then
        try ( Transaction tx = db.beginTx() )
        {
            assertEquals( propertiesCount, db.getNodeById( nodeId ).getAllProperties().size() );
            tx.success();
        }
    }

    @Test
    public void getAllPropertiesShouldWorkFineWithConcurrentPropertyModifications() throws Exception
    {
        // Given
        ExecutorService executor = cleanup.add( Executors.newFixedThreadPool( 2, named( "Test-executor-thread" ) ) );

        final int propertiesCount = 100;

        final long nodeId;
        try ( Transaction tx = db.beginTx() )
        {
            Node node = db.createNode();
            nodeId = node.getId();
            for ( int i = 0; i < propertiesCount; i++ )
            {
                node.setProperty( "property-" + i, i );
            }
            tx.success();
        }

        final CountDownLatch start = new CountDownLatch( 1 );
        final AtomicBoolean writerDone = new AtomicBoolean();

        Runnable writer = new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    awaitLatch( start );
                    int propertyKey = 0;
                    while ( propertyKey < propertiesCount )
                    {
                        try ( Transaction tx = db.beginTx() )
                        {
                            Node node = db.getNodeById( nodeId );
                            for ( int i = 0; i < 10 && propertyKey < propertiesCount; i++, propertyKey++ )
                            {
                                node.setProperty( "property-" + propertyKey, UUID.randomUUID().toString() );
                            }
                            tx.success();
                        }
                    }
                }
                finally
                {
                    writerDone.set( true );
                }
            }
        };
        Runnable reader = new Runnable()
        {
            @Override
            public void run()
            {
                try ( Transaction tx = db.beginTx() )
                {
                    Node node = db.getNodeById( nodeId );
                    awaitLatch( start );
                    while ( !writerDone.get() )
                    {
                        int size = node.getAllProperties().size();
                        assertThat( size, greaterThan( 0 ) );
                    }
                    tx.success();
                }
            }
        };

        Future<?> readerFuture = executor.submit( reader );
        Future<?> writerFuture = executor.submit( writer );

        start.countDown();

        // When
        writerFuture.get();
        readerFuture.get();

        // Then
        try ( Transaction tx = db.beginTx() )
        {
            assertEquals( propertiesCount, db.getNodeById( nodeId ).getAllProperties().size() );
            tx.success();
        }
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.core.NodeProxyTest.getAllPropertiesShouldWorkFineWithConcurrentPropertyModifications.writer.new Runnable with () -> {tryawaitLatch(start); in method public getAllPropertiesShouldWorkFineWithConcurrentPropertyModifications() : void from class org.neo4j.kernel.impl.core.NodeProxyTest


    private static Map<IdType,Long> getHighIds( GraphDatabaseAPI db )
    {
        final Map<IdType,Long> highIds = new HashMap<>();
        NeoStores neoStores = db.getDependencyResolver().resolveDependency(
                RecordStorageEngine.class ).testAccessNeoStores();
        Visitor<CommonAbstractStore,RuntimeException> visitor = store ->
        {
            highIds.put( store.getIdType(), store.getHighId() );
            return true;
        };
        neoStores.visitStore( visitor );
        return highIds;
    }

    private static Map<IdType,Long> getHighIds( GraphDatabaseAPI db )
    {
        final Map<IdType,Long> highIds = new HashMap<>();
        NeoStores neoStores = db.getDependencyResolver().resolveDependency(
                RecordStorageEngine.class ).testAccessNeoStores();
        Visitor<CommonAbstractStore,RuntimeException> visitor = new Visitor<CommonAbstractStore,RuntimeException>()
        {
            @Override
            public boolean visit( CommonAbstractStore store ) throws RuntimeException
            {
                highIds.put( store.getIdType(), store.getHighId() );
                return true;
            }
        };
        neoStores.visitStore( visitor );
        return highIds;
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.core.TestCrashWithRebuildSlow.getHighIds.visitor.new Visitor<CommonAbstractStore,RuntimeException> with store -> {highIds.put(store.getIdType(),store.getHighId()); in method private getHighIds(db GraphDatabaseAPI) : Map<IdType,Long> from class org.neo4j.kernel.impl.core.TestCrashWithRebuildSlow


    @Test
    public void testSimpleTransactionIsolation() throws Exception
    {
        // Start setup - create base data
        commit();
        final CountDownLatch latch1 = new CountDownLatch( 1 );
        final CountDownLatch latch2 = new CountDownLatch( 1 );
        Node n1;
        Node n2;
        Relationship r1;
        try ( Transaction tx = getGraphDb().beginTx() )
        {
            n1 = getGraphDb().createNode();
            n2 = getGraphDb().createNode();
            r1 = n1.createRelationshipTo( n2,
                    RelationshipType.withName( "TEST" ) );
            tx.success();
        }

        final Node node1 = n1;
        final Node node2 = n2;
        final Relationship rel1 = r1;

        try ( Transaction tx = getGraphDb().beginTx() )
        {
            node1.setProperty( "key", "old" );
            rel1.setProperty( "key", "old" );
            tx.success();
        }
        assertPropertyEqual( node1, "key", "old" );
        assertPropertyEqual( rel1, "key", "old" );
        assertRelationshipCount( node1, 1 );
        assertRelationshipCount( node2, 1 );

        // This is the mutating transaction - it will change stuff which will be read in between
        final AtomicReference<Exception> t1Exception = new AtomicReference<>();
        Thread t1 = new Thread( () ->
        {

            try ( Transaction tx = getGraphDb().beginTx() )
            {
                node1.setProperty( "key", "new" );
                rel1.setProperty( "key", "new" );
                node1.createRelationshipTo( node2, RelationshipType.withName( "TEST" ) );
                assertPropertyEqual( node1, "key", "new" );
                assertPropertyEqual( rel1, "key", "new" );
                assertRelationshipCount( node1, 2 );
                assertRelationshipCount( node2, 2 );
                latch1.countDown();
                latch2.await();
                assertPropertyEqual( node1, "key", "new" );
                assertPropertyEqual( rel1, "key", "new" );
                assertRelationshipCount( node1, 2 );
                assertRelationshipCount( node2, 2 );
                // no tx.success();
            }
            catch ( Exception e )
            {
                e.printStackTrace();
                Thread.interrupted();
                t1Exception.set( e );
            }
            finally
            {
                try
                {
                    assertPropertyEqual( node1, "key", "old" );
                    assertPropertyEqual( rel1, "key", "old" );
                    assertRelationshipCount( node1, 1 );
                    assertRelationshipCount( node2, 1 );
                }
                catch ( Exception e )
                {
                    t1Exception.compareAndSet( null, e );
                }
            }
        } );
        t1.start();

        latch1.await();

        // The transaction started above that runs in t1 has not finished. The old values should still be visible.
        assertPropertyEqual( node1, "key", "old" );
        assertPropertyEqual( rel1, "key", "old" );
        assertRelationshipCount( node1, 1 );
        assertRelationshipCount( node2, 1 );

        latch2.countDown();
        t1.join();

        // The transaction in t1 has finished but not committed. Its changes should still not be visible.
        assertPropertyEqual( node1, "key", "old" );
        assertPropertyEqual( rel1, "key", "old" );
        assertRelationshipCount( node1, 1 );
        assertRelationshipCount( node2, 1 );

        if ( t1Exception.get() != null )
        {
            throw t1Exception.get();
        }

        try ( Transaction tx = getGraphDb().beginTx() )
        {
            for ( Relationship rel : node1.getRelationships() )
            {
                rel.delete();
            }
            node1.delete();
            node2.delete();
            tx.success();
        }
    }

    @Test
    public void testSimpleTransactionIsolation() throws Exception
    {
        // Start setup - create base data
        commit();
        final CountDownLatch latch1 = new CountDownLatch( 1 );
        final CountDownLatch latch2 = new CountDownLatch( 1 );
        Node n1;
        Node n2;
        Relationship r1;
        try ( Transaction tx = getGraphDb().beginTx() )
        {
            n1 = getGraphDb().createNode();
            n2 = getGraphDb().createNode();
            r1 = n1.createRelationshipTo( n2,
                    RelationshipType.withName( "TEST" ) );
            tx.success();
        }

        final Node node1 = n1;
        final Node node2 = n2;
        final Relationship rel1 = r1;

        try ( Transaction tx = getGraphDb().beginTx() )
        {
            node1.setProperty( "key", "old" );
            rel1.setProperty( "key", "old" );
            tx.success();
        }
        assertPropertyEqual( node1, "key", "old" );
        assertPropertyEqual( rel1, "key", "old" );
        assertRelationshipCount( node1, 1 );
        assertRelationshipCount( node2, 1 );

        // This is the mutating transaction - it will change stuff which will be read in between
        final AtomicReference<Exception> t1Exception = new AtomicReference<>();
        Thread t1 = new Thread( new Runnable()
        {
            public void run()
            {

                try ( Transaction tx = getGraphDb().beginTx() )
                {
                    node1.setProperty( "key", "new" );
                    rel1.setProperty( "key", "new" );
                    node1.createRelationshipTo( node2, RelationshipType.withName( "TEST" ) );
                    assertPropertyEqual( node1, "key", "new" );
                    assertPropertyEqual( rel1, "key", "new" );
                    assertRelationshipCount( node1, 2 );
                    assertRelationshipCount( node2, 2 );
                    latch1.countDown();
                    latch2.await();
                    assertPropertyEqual( node1, "key", "new" );
                    assertPropertyEqual( rel1, "key", "new" );
                    assertRelationshipCount( node1, 2 );
                    assertRelationshipCount( node2, 2 );
                    // no tx.success();
                }
                catch ( Exception e )
                {
                    e.printStackTrace();
                    Thread.interrupted();
                    t1Exception.set( e );
                }
                finally
                {
                    try
                    {
                        assertPropertyEqual( node1, "key", "old" );
                        assertPropertyEqual( rel1, "key", "old" );
                        assertRelationshipCount( node1, 1 );
                        assertRelationshipCount( node2, 1 );
                    }
                    catch ( Exception e )
                    {
                        t1Exception.compareAndSet( null, e );
                    }
                }
            }
        } );
        t1.start();

        latch1.await();

        // The transaction started above that runs in t1 has not finished. The old values should still be visible.
        assertPropertyEqual( node1, "key", "old" );
        assertPropertyEqual( rel1, "key", "old" );
        assertRelationshipCount( node1, 1 );
        assertRelationshipCount( node2, 1 );

        latch2.countDown();
        t1.join();

        // The transaction in t1 has finished but not committed. Its changes should still not be visible.
        assertPropertyEqual( node1, "key", "old" );
        assertPropertyEqual( rel1, "key", "old" );
        assertRelationshipCount( node1, 1 );
        assertRelationshipCount( node2, 1 );

        if ( t1Exception.get() != null )
        {
            throw t1Exception.get();
        }

        try ( Transaction tx = getGraphDb().beginTx() )
        {
            for ( Relationship rel : node1.getRelationships() )
            {
                rel.delete();
            }
            node1.delete();
            node2.delete();
            tx.success();
        }
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.core.TestIsolationBasic.testSimpleTransactionIsolation.t1.new Thread.new Runnable with () -> {try(Transaction tx=getGraphDb().beginTx())node1.setProperty("key","new"); in method public testSimpleTransactionIsolation() : void from class org.neo4j.kernel.impl.core.TestIsolationBasic


    @Test
    public void shouldForceChannelAfterWritingMetadata() throws IOException
    {
        // Given
        final StoreChannel[] channelUsedToCreateFile = {null};

        FileSystemAbstraction fs = spy( fileSystem );
        StoreChannel tempChannel;
        when( tempChannel = fs.open( file, "rw" ) ).then( ignored ->
        {
            StoreChannel channel = fileSystem.open( file, "rw" );
            if ( channelUsedToCreateFile[0] == null )
            {
                StoreChannel channelSpy = spy( channel );
                channelUsedToCreateFile[0] = channelSpy;
                channel = channelSpy;
            }
            return channel;
        } );

        // Doing the FSA spying above, calling fs.open, actually invokes that method and so a channel
        // is opened. We put that in tempChannel and close it before deleting the file below.
        tempChannel.close();
        fs.deleteFile( file );

        // When
        IndexProviderStore store = new IndexProviderStore( file, fs, MetaDataStore.versionStringToLong( "3.5" ), false );

        // Then
        StoreChannel channel = channelUsedToCreateFile[0];
        verify( channel ).write( any( ByteBuffer.class ), eq( 0L ) );
        verify( channel ).force( true );
        verify( channel ).close();
        verifyNoMoreInteractions( channel );
        store.close();
    }

    @Test
    public void shouldForceChannelAfterWritingMetadata() throws IOException
    {
        // Given
        final StoreChannel[] channelUsedToCreateFile = {null};

        FileSystemAbstraction fs = spy( fileSystem );
        StoreChannel tempChannel;
        when( tempChannel = fs.open( file, "rw" ) ).then( new Answer<StoreChannel>()
        {
            @Override
            public StoreChannel answer( InvocationOnMock ignored ) throws Throwable
            {
                StoreChannel channel = fileSystem.open( file, "rw" );
                if ( channelUsedToCreateFile[0] == null )
                {
                    StoreChannel channelSpy = spy( channel );
                    channelUsedToCreateFile[0] = channelSpy;
                    channel = channelSpy;
                }
                return channel;
            }
        } );

        // Doing the FSA spying above, calling fs.open, actually invokes that method and so a channel
        // is opened. We put that in tempChannel and close it before deleting the file below.
        tempChannel.close();
        fs.deleteFile( file );

        // When
        IndexProviderStore store = new IndexProviderStore( file, fs, MetaDataStore.versionStringToLong( "3.5" ), false );

        // Then
        StoreChannel channel = channelUsedToCreateFile[0];
        verify( channel ).write( any( ByteBuffer.class ), eq( 0L ) );
        verify( channel ).force( true );
        verify( channel ).close();
        verifyNoMoreInteractions( channel );
        store.close();
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.index.TestIndexProviderStore.shouldForceChannelAfterWritingMetadata.then.new Answer<StoreChannel> with ignored -> {StoreChannel channel=fileSystem.open(file,"rw"); in method public shouldForceChannelAfterWritingMetadata() : void from class org.neo4j.kernel.impl.index.TestIndexProviderStore


    @Test
    public void shouldNotDeadlockWhenConcurrentCreateAndDeleteRelationships() throws Throwable
    {
        // GIVEN (A) -[R]-> (B)
        final Node a;
        final Node b;
        try ( Transaction tx = db.beginTx() )
        {
            (a = db.createNode()).createRelationshipTo( b = db.createNode(), MyRelTypes.TEST );
            tx.success();
        }

        // WHEN
        Race race = new Race();
        // a bunch of deleters
        for ( int i = 0; i < 30; i++ )
        {
            race.addContestant( () ->
            {
                try ( Transaction tx = db.beginTx() )
                {
                    Node node = random.nextBoolean() ? a : b;
                    for ( Relationship relationship : node.getRelationships() )
                    {
                        try
                        {
                            relationship.delete();
                        }
                        catch ( NotFoundException e )
                        {
                            // This is OK and expected since there are multiple threads deleting
                            assertTrue( e.getMessage().contains( "already deleted" ) );
                        }
                    }
                    tx.success();
                }
            } );
        }

        // a bunch of creators
        for ( int i = 0; i < 30; i++ )
        {
            race.addContestant( () ->
            {
                try ( Transaction tx = db.beginTx() )
                {
                    boolean order = random.nextBoolean();
                    Node start = order ? a : b;
                    Node end = order ? b : a;
                    start.createRelationshipTo( end, MyRelTypes.TEST );
                    tx.success();
                }
            } );
        }

        // THEN there should be no thread throwing exception, especially DeadlockDetectedException
        race.go();
    }

    @Test
    public void shouldNotDeadlockWhenConcurrentCreateAndDeleteRelationships() throws Throwable
    {
        // GIVEN (A) -[R]-> (B)
        final Node a;
        final Node b;
        try ( Transaction tx = db.beginTx() )
        {
            (a = db.createNode()).createRelationshipTo( b = db.createNode(), MyRelTypes.TEST );
            tx.success();
        }

        // WHEN
        Race race = new Race();
        // a bunch of deleters
        for ( int i = 0; i < 30; i++ )
        {
            race.addContestant( new Runnable()
            {
                @Override
                public void run()
                {
                    try ( Transaction tx = db.beginTx() )
                    {
                        Node node = random.nextBoolean() ? a : b;
                        for ( Relationship relationship : node.getRelationships() )
                        {
                            try
                            {
                                relationship.delete();
                            }
                            catch ( NotFoundException e )
                            {
                                // This is OK and expected since there are multiple threads deleting
                                assertTrue( e.getMessage().contains( "already deleted" ) );
                            }
                        }
                        tx.success();
                    }
                }
            } );
        }

        // a bunch of creators
        for ( int i = 0; i < 30; i++ )
        {
            race.addContestant( new Runnable()
            {
                @Override
                public void run()
                {
                    try ( Transaction tx = db.beginTx() )
                    {
                        boolean order = random.nextBoolean();
                        Node start = order ? a : b;
                        Node end = order ? b : a;
                        start.createRelationshipTo( end, MyRelTypes.TEST );
                        tx.success();
                    }
                }
            } );
        }

        // THEN there should be no thread throwing exception, especially DeadlockDetectedException
        race.go();
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.locking.RelationshipCreateDeleteLockOrderingIT.shouldNotDeadlockWhenConcurrentCreateAndDeleteRelationships.addContestant.new Runnable with () -> {try(Transaction tx=db.beginTx())Node node=random.nextBoolean() ? a : b; in method public shouldNotDeadlockWhenConcurrentCreateAndDeleteRelationships() : void from class org.neo4j.kernel.impl.locking.RelationshipCreateDeleteLockOrderingIT


    @Test
    public void shouldKeepHighestDuringConcurrentOfferings() throws Throwable
    {
        // GIVEN
        final HighestTransactionId highest = new HighestTransactionId( -1, -1, -1 );
        Race race = new Race();
        int updaters = max( 2, getRuntime().availableProcessors() );
        final AtomicInteger accepted = new AtomicInteger();
        for ( int i = 0; i < updaters; i++ )
        {
            final long id = i + 1;
            race.addContestant( () ->
            {
                if ( highest.offer( id, id, id ) )
                {
                    accepted.incrementAndGet();
                }
            } );
        }

        // WHEN
        race.go();

        // THEN
        assertTrue( accepted.get() > 0 );
        assertEquals( updaters, highest.get().transactionId() );
    }

    @Test
    public void shouldKeepHighestDuringConcurrentOfferings() throws Throwable
    {
        // GIVEN
        final HighestTransactionId highest = new HighestTransactionId( -1, -1, -1 );
        Race race = new Race();
        int updaters = max( 2, getRuntime().availableProcessors() );
        final AtomicInteger accepted = new AtomicInteger();
        for ( int i = 0; i < updaters; i++ )
        {
            final long id = i + 1;
            race.addContestant( new Runnable()
            {
                @Override
                public void run()
                {
                    if ( highest.offer( id, id, id ) )
                    {
                        accepted.incrementAndGet();
                    }
                }
            } );
        }

        // WHEN
        race.go();

        // THEN
        assertTrue( accepted.get() > 0 );
        assertEquals( updaters, highest.get().transactionId() );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.HighestTransactionIdTest.shouldKeepHighestDuringConcurrentOfferings.addContestant.new Runnable with () -> {if(highest.offer(id,id,id)){accepted.incrementAndGet(); in method public shouldKeepHighestDuringConcurrentOfferings() : void from class org.neo4j.kernel.impl.store.HighestTransactionIdTest


    private void assertRelationshipData( long rel, final long firstNode, final long secondNode,
            final int relType )
    {
        try
        {
            storeLayer.relationshipVisit( rel, ( relId, type, startNode, endNode ) ->
            {
                assertEquals( firstNode, startNode );
                assertEquals( secondNode, endNode );
                assertEquals( relType, type );
            } );
        }
        catch ( EntityNotFoundException e )
        {
            throw new RuntimeException( e );
        }
    }

    private void assertRelationshipData( long rel, final long firstNode, final long secondNode,
            final int relType )
    {
        try
        {
            storeLayer.relationshipVisit( rel, new RelationshipVisitor<RuntimeException>()
            {
                @Override
                public void visit( long relId, int type, long startNode, long endNode )
                {
                    assertEquals( firstNode, startNode );
                    assertEquals( secondNode, endNode );
                    assertEquals( relType, type );
                }
            } );
        }
        catch ( EntityNotFoundException e )
        {
            throw new RuntimeException( e );
        }
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.NeoStoresTest.assertRelationshipData.relationshipVisit.new RelationshipVisitor<RuntimeException> with (relId, type, startNode, endNode) -> {assertEquals(firstNode,startNode); in method private assertRelationshipData(rel long, firstNode long, secondNode long, relType int) : void from class org.neo4j.kernel.impl.store.NeoStoresTest


    @Test
    public void scanningRecordsShouldVisitEachInUseRecordOnce() throws IOException
    {
        // GIVEN we have a NodeStore with data that spans several pages...
        EphemeralFileSystemAbstraction fs = efs.get();
        nodeStore = newNodeStore( fs );

        ThreadLocalRandom rng = ThreadLocalRandom.current();
        final PrimitiveLongSet nextRelSet = Primitive.longSet();
        for ( int i = 0; i < 10_000; i++ )
        {
            // Enough records to span several pages
            int nextRelCandidate = rng.nextInt( 0, Integer.MAX_VALUE );
            if ( nextRelSet.add( nextRelCandidate ) )
            {
                long nodeId = nodeStore.nextId();
                NodeRecord record = new NodeRecord(
                        nodeId, false, nextRelCandidate, 20, true );
                nodeStore.updateRecord( record );
                if ( rng.nextInt( 0, 10 ) < 3 )
                {
                    nextRelSet.remove( nextRelCandidate );
                    record.setInUse( false );
                    nodeStore.updateRecord( record );
                }
            }
        }

        // ...WHEN we now have an interesting set of node records, and we
        // visit each and remove that node from our nextRelSet...

        Visitor<NodeRecord,IOException> scanner = record ->
        {
            // ...THEN we should observe that no nextRel is ever removed twice...
            assertTrue( nextRelSet.remove( record.getNextRel() ) );
            return false;
        };
        nodeStore.scanAllRecords( scanner );

        // ...NOR do we have anything left in the set afterwards.
        assertTrue( nextRelSet.isEmpty() );
    }

    @Test
    public void scanningRecordsShouldVisitEachInUseRecordOnce() throws IOException
    {
        // GIVEN we have a NodeStore with data that spans several pages...
        EphemeralFileSystemAbstraction fs = efs.get();
        nodeStore = newNodeStore( fs );

        ThreadLocalRandom rng = ThreadLocalRandom.current();
        final PrimitiveLongSet nextRelSet = Primitive.longSet();
        for ( int i = 0; i < 10_000; i++ )
        {
            // Enough records to span several pages
            int nextRelCandidate = rng.nextInt( 0, Integer.MAX_VALUE );
            if ( nextRelSet.add( nextRelCandidate ) )
            {
                long nodeId = nodeStore.nextId();
                NodeRecord record = new NodeRecord(
                        nodeId, false, nextRelCandidate, 20, true );
                nodeStore.updateRecord( record );
                if ( rng.nextInt( 0, 10 ) < 3 )
                {
                    nextRelSet.remove( nextRelCandidate );
                    record.setInUse( false );
                    nodeStore.updateRecord( record );
                }
            }
        }

        // ...WHEN we now have an interesting set of node records, and we
        // visit each and remove that node from our nextRelSet...

        Visitor<NodeRecord,IOException> scanner = new Visitor<NodeRecord,IOException>()
        {
            @Override
            public boolean visit( NodeRecord record ) throws IOException
            {
                // ...THEN we should observe that no nextRel is ever removed twice...
                assertTrue( nextRelSet.remove( record.getNextRel() ) );
                return false;
            }
        };
        nodeStore.scanAllRecords( scanner );

        // ...NOR do we have anything left in the set afterwards.
        assertTrue( nextRelSet.isEmpty() );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.NodeStoreTest.scanningRecordsShouldVisitEachInUseRecordOnce.scanner.new Visitor<NodeRecord,IOException> with record -> {assertTrue(nextRelSet.remove(record.getNextRel())); in method public scanningRecordsShouldVisitEachInUseRecordOnce() : void from class org.neo4j.kernel.impl.store.NodeStoreTest


    @Test
    public void shouldWriteOutTheDynamicChainBeforeUpdatingThePropertyRecord() throws IOException
    {
        // given
        PageCache pageCache = pageCacheRule.getPageCache( fileSystemAbstraction );
        Config config =
                Config.embeddedDefaults( singletonMap( PropertyStore.Configuration.rebuild_idgenerators_fast.name(), "true" ));

        DynamicStringStore stringPropertyStore = mock( DynamicStringStore.class );

        final PropertyStore store = new PropertyStore( path, config, new JumpingIdGeneratorFactory( 1 ), pageCache,
                NullLogProvider.getInstance(), stringPropertyStore,
                mock( PropertyKeyTokenStore.class ), mock( DynamicArrayStore.class ),
                RecordFormatSelector.defaultFormat() );
        store.initialise( true );

        try
        {
            store.makeStoreOk();
            final long propertyRecordId = store.nextId();

            PropertyRecord record = new PropertyRecord( propertyRecordId );
            record.setInUse( true );

            DynamicRecord dynamicRecord = dynamicRecord();
            PropertyBlock propertyBlock = propertyBlockWith( dynamicRecord );
            record.setPropertyBlock( propertyBlock );

            doAnswer( invocation ->
            {
                PropertyRecord recordBeforeWrite = store.getRecord( propertyRecordId, store.newRecord(), FORCE );
                assertFalse( recordBeforeWrite.inUse() );
                return null;
            } ).when( stringPropertyStore ).updateRecord( dynamicRecord );

            // when
            store.updateRecord( record );

            // then verify that our mocked method above, with the assert, was actually called
            verify( stringPropertyStore ).updateRecord( dynamicRecord );
        }
        finally
        {
            store.close();
        }
    }

    @Test
    public void shouldWriteOutTheDynamicChainBeforeUpdatingThePropertyRecord() throws IOException
    {
        // given
        PageCache pageCache = pageCacheRule.getPageCache( fileSystemAbstraction );
        Config config =
                Config.embeddedDefaults( singletonMap( PropertyStore.Configuration.rebuild_idgenerators_fast.name(), "true" ));

        DynamicStringStore stringPropertyStore = mock( DynamicStringStore.class );

        final PropertyStore store = new PropertyStore( path, config, new JumpingIdGeneratorFactory( 1 ), pageCache,
                NullLogProvider.getInstance(), stringPropertyStore,
                mock( PropertyKeyTokenStore.class ), mock( DynamicArrayStore.class ),
                RecordFormatSelector.defaultFormat() );
        store.initialise( true );

        try
        {
            store.makeStoreOk();
            final long propertyRecordId = store.nextId();

            PropertyRecord record = new PropertyRecord( propertyRecordId );
            record.setInUse( true );

            DynamicRecord dynamicRecord = dynamicRecord();
            PropertyBlock propertyBlock = propertyBlockWith( dynamicRecord );
            record.setPropertyBlock( propertyBlock );

            doAnswer( new Answer()
            {
                @Override
                public Object answer( InvocationOnMock invocation ) throws Throwable
                {
                    PropertyRecord recordBeforeWrite = store.getRecord( propertyRecordId, store.newRecord(), FORCE );
                    assertFalse( recordBeforeWrite.inUse() );
                    return null;
                }
            } ).when( stringPropertyStore ).updateRecord( dynamicRecord );

            // when
            store.updateRecord( record );

            // then verify that our mocked method above, with the assert, was actually called
            verify( stringPropertyStore ).updateRecord( dynamicRecord );
        }
        finally
        {
            store.close();
        }
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.PropertyStoreTest.shouldWriteOutTheDynamicChainBeforeUpdatingThePropertyRecord.updateRecord.when.doAnswer.new Answer with invocation -> {PropertyRecord recordBeforeWrite=store.getRecord(propertyRecordId,store.newRecord(),FORCE); in method public shouldWriteOutTheDynamicChainBeforeUpdatingThePropertyRecord() : void from class org.neo4j.kernel.impl.store.PropertyStoreTest


    private void deleteRelationshipsInSeparateThread( final Relationship... relationships ) throws InterruptedException
    {
        executeTransactionInSeparateThread( () ->
        {
            for ( Relationship relationship : relationships )
            {
                relationship.delete();
            }
        } );
    }

    private void deleteRelationshipsInSeparateThread( final Relationship... relationships ) throws InterruptedException
    {
        executeTransactionInSeparateThread( new Runnable()
        {
            @Override
            public void run()
            {
                for ( Relationship relationship : relationships )
                {
                    relationship.delete();
                }
            }
        } );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.RelationshipChainPointerChasingTest.deleteRelationshipsInSeparateThread.executeTransactionInSeparateThread.new Runnable with () -> {for(Relationship relationship: relationships){relationship.delete(); in method private deleteRelationshipsInSeparateThread(relationships Relationship...) : void from class org.neo4j.kernel.impl.store.RelationshipChainPointerChasingTest


    @Test
    public void shouldHandleTheWholeWorkloadShebang() throws Throwable
    {
        // GIVEN
        final int size = 1_000;
        final long bufferTime = 3;
        VerifyingConsumer consumer = new VerifyingConsumer( size );
        final Clock clock = Clocks.systemClock();
        Supplier<Long> chunkThreshold = clock::millis;
        Predicate<Long> safeThreshold = time -> clock.millis() - bufferTime >= time;
        final DelayedBuffer<Long> buffer = new DelayedBuffer<>( chunkThreshold, safeThreshold, 10, consumer );
        MaintenanceThread maintenance = new MaintenanceThread( buffer, 5 );
        Race adders = new Race();
        final int numberOfAdders = 20;
        final byte[] offeredIds = new byte[size];
        for ( int i = 0; i < numberOfAdders; i++ )
        {
            final int finalI = i;
            adders.addContestant( () ->
            {
                for ( int j = 0; j < size; j++ )
                {
                    if ( j % numberOfAdders == finalI )
                    {
                        buffer.offer( j );
                        offeredIds[j] = 1;
                        parkNanos( MILLISECONDS.toNanos( current().nextInt( 2 ) ) );
                    }
                }
            } );
        }

        // WHEN (multi-threadded) offering of ids
        adders.go();
        // ... ensuring the test is sane itself (did we really offer all these IDs?)
        for ( int i = 0; i < size; i++ )
        {
            assertEquals( "ID " + i, (byte) 1, offeredIds[i] );
        }
        maintenance.halt();
        buffer.close();

        // THEN
        consumer.assertHaveOnlySeenRange( 0, size - 1 );
    }

    @Test
    public void shouldHandleTheWholeWorkloadShebang() throws Throwable
    {
        // GIVEN
        final int size = 1_000;
        final long bufferTime = 3;
        VerifyingConsumer consumer = new VerifyingConsumer( size );
        final Clock clock = Clocks.systemClock();
        Supplier<Long> chunkThreshold = clock::millis;
        Predicate<Long> safeThreshold = time -> clock.millis() - bufferTime >= time;
        final DelayedBuffer<Long> buffer = new DelayedBuffer<>( chunkThreshold, safeThreshold, 10, consumer );
        MaintenanceThread maintenance = new MaintenanceThread( buffer, 5 );
        Race adders = new Race();
        final int numberOfAdders = 20;
        final byte[] offeredIds = new byte[size];
        for ( int i = 0; i < numberOfAdders; i++ )
        {
            final int finalI = i;
            adders.addContestant( new Runnable()
            {
                @Override
                public void run()
                {
                    for ( int j = 0; j < size; j++ )
                    {
                        if ( j % numberOfAdders == finalI )
                        {
                            buffer.offer( j );
                            offeredIds[j] = 1;
                            parkNanos( MILLISECONDS.toNanos( current().nextInt( 2 ) ) );
                        }
                    }
                }
            } );
        }

        // WHEN (multi-threadded) offering of ids
        adders.go();
        // ... ensuring the test is sane itself (did we really offer all these IDs?)
        for ( int i = 0; i < size; i++ )
        {
            assertEquals( "ID " + i, (byte) 1, offeredIds[i] );
        }
        maintenance.halt();
        buffer.close();

        // THEN
        consumer.assertHaveOnlySeenRange( 0, size - 1 );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.id.DelayedBufferTest.shouldHandleTheWholeWorkloadShebang.addContestant.new Runnable with () -> {for(int j=0; j < size; j++){if(j % numberOfAdders == finalI){buffer.offer(j); in method public shouldHandleTheWholeWorkloadShebang() : void from class org.neo4j.kernel.impl.store.id.DelayedBufferTest


    @Test
    public void shouldNotPickCorruptStoreFile() throws Exception
    {
        // given
        Store store = createTestStore();
        RotationStrategy rotation = store.rotationStrategy;

        // when
        File[] files = new File[10];
        {
            Pair<File,KeyValueStoreFile> file = rotation.create( EMPTY_DATA_PROVIDER, 1 );
            files[0] = file.first();
            for ( int txId = 2, i = 1; i < files.length; txId <<= 1, i++ )
            {
                KeyValueStoreFile old = file.other();
                final int data = txId;
                file = rotation.next( file.first(), Headers.headersBuilder().put( TX_ID, (long) txId ).headers(), data(
                        (Entry) ( key, value ) ->
                        {
                            key.putByte( 0, (byte) 'f' );
                            key.putByte( 1, (byte) 'o' );
                            key.putByte( 2, (byte) 'o' );
                            value.putInt( 0, data );
                        }
                ) );
                old.close();
                files[i] = file.first();
            }
            file.other().close();
        }
        // Corrupt the last files
        try ( StoreChannel channel = resourceManager.fileSystem().open( files[9], "rw" ) )
        {   // ruin the header
            channel.position( 16 );
            ByteBuffer value = ByteBuffer.allocate( 16 );
            value.put( (byte) 0 );
            value.flip();
            channel.writeAll( value );
        }
        try ( StoreChannel channel = resourceManager.fileSystem().open( files[8], "rw" ) )
        {   // ruin the header
            channel.position( 32 );
            ByteBuffer value = ByteBuffer.allocate( 16 );
            value.put( (byte) 17 );
            value.flip();
            channel.writeAll( value );
        }
        try ( StoreChannel channel = resourceManager.fileSystem().open( files[7], "rw" ) )
        {   // ruin the header
            channel.position( 32 + 32 + 32 + 16 );
            ByteBuffer value = ByteBuffer.allocate( 16 );
            value.putLong( 0 );
            value.putLong( 0 );
            value.flip();
            channel.writeAll( value );
        }

        // then
        try ( Lifespan life = new Lifespan() )
        {
            life.add( store );

            assertEquals( 64L, store.headers().get( TX_ID ).longValue() );
        }
    }

    @Test
    public void shouldNotPickCorruptStoreFile() throws Exception
    {
        // given
        Store store = createTestStore();
        RotationStrategy rotation = store.rotationStrategy;

        // when
        File[] files = new File[10];
        {
            Pair<File,KeyValueStoreFile> file = rotation.create( EMPTY_DATA_PROVIDER, 1 );
            files[0] = file.first();
            for ( int txId = 2, i = 1; i < files.length; txId <<= 1, i++ )
            {
                KeyValueStoreFile old = file.other();
                final int data = txId;
                file = rotation.next( file.first(), Headers.headersBuilder().put( TX_ID, (long) txId ).headers(), data(
                        new Entry()
                        {
                            @Override
                            public void write( WritableBuffer key, WritableBuffer value )
                            {
                                key.putByte( 0, (byte) 'f' );
                                key.putByte( 1, (byte) 'o' );
                                key.putByte( 2, (byte) 'o' );
                                value.putInt( 0, data );
                            }
                        }
                ) );
                old.close();
                files[i] = file.first();
            }
            file.other().close();
        }
        // Corrupt the last files
        try ( StoreChannel channel = resourceManager.fileSystem().open( files[9], "rw" ) )
        {   // ruin the header
            channel.position( 16 );
            ByteBuffer value = ByteBuffer.allocate( 16 );
            value.put( (byte) 0 );
            value.flip();
            channel.writeAll( value );
        }
        try ( StoreChannel channel = resourceManager.fileSystem().open( files[8], "rw" ) )
        {   // ruin the header
            channel.position( 32 );
            ByteBuffer value = ByteBuffer.allocate( 16 );
            value.put( (byte) 17 );
            value.flip();
            channel.writeAll( value );
        }
        try ( StoreChannel channel = resourceManager.fileSystem().open( files[7], "rw" ) )
        {   // ruin the header
            channel.position( 32 + 32 + 32 + 16 );
            ByteBuffer value = ByteBuffer.allocate( 16 );
            value.putLong( 0 );
            value.putLong( 0 );
            value.flip();
            channel.writeAll( value );
        }

        // then
        try ( Lifespan life = new Lifespan() )
        {
            life.add( store );

            assertEquals( 64L, store.headers().get( TX_ID ).longValue() );
        }
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.kvstore.AbstractKeyValueStoreTest.shouldNotPickCorruptStoreFile.next.data.new Entry with (key, value) -> {key.putByte(0,(byte)'f'); in method public shouldNotPickCorruptStoreFile() : void from class org.neo4j.kernel.impl.store.kvstore.AbstractKeyValueStoreTest


    static KeyValueVisitor expectData( final Data expected )
    {
        expected.index = 0; // reset the visitor
        return ( key, value ) ->
        {
            byte[] expectedKey = new byte[key.size()];
            byte[] expectedValue = new byte[value.size()];
            if ( !expected.visit( new BigEndianByteArrayBuffer( expectedKey ),
                    new BigEndianByteArrayBuffer( expectedValue ) ) )
            {
                return false;
            }
            assertEqualContent( expectedKey, key );
            return true;
        };
    }

    static KeyValueVisitor expectData( final Data expected )
    {
        expected.index = 0; // reset the visitor
        return new KeyValueVisitor()
        {
            @Override
            public boolean visit( ReadableBuffer key, ReadableBuffer value )
            {
                byte[] expectedKey = new byte[key.size()];
                byte[] expectedValue = new byte[value.size()];
                if ( !expected.visit( new BigEndianByteArrayBuffer( expectedKey ),
                        new BigEndianByteArrayBuffer( expectedValue ) ) )
                {
                    return false;
                }
                assertEqualContent( expectedKey, key );
                return true;
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.store.kvstore.KeyValueStoreFileFormatTest.expectData.new KeyValueVisitor with (key, value) -> {byte[] expectedKey=new byte[key.size()]; in method package expectData(expected Data) : KeyValueVisitor from class org.neo4j.kernel.impl.store.kvstore.KeyValueStoreFileFormatTest


    private <R extends PrimitiveRecord> void setUpPropertyChain( long id, Class<R> recordClass,
            CommonAbstractStore<R,? extends StoreHeader> store, int... propertyValues )
    {
        when( store.getRecord( eq( id ), any( recordClass ), any( RecordLoad.class ) ) ).thenAnswer( invocation ->
        {
            R record = (R) invocation.getArguments()[1];
            record.setId( ((Number)invocation.getArguments()[0]).longValue() );
            record.setNextProp( 1 );
            return record;
        } );
        List<PropertyRecord> propertyChain = new ArrayList<>( propertyValues.length );
        for ( int i = 0; i < propertyValues.length; i++ )
        {
            propertyChain.add( newSingleIntProperty( i + 1, propertyValues[i] ) );
        }
        doReturn( propertyChain ).when( propertyStore ).getPropertyRecordChain( 1L );
    }

    private <R extends PrimitiveRecord> void setUpPropertyChain( long id, Class<R> recordClass,
            CommonAbstractStore<R,? extends StoreHeader> store, int... propertyValues )
    {
        when( store.getRecord( eq( id ), any( recordClass ), any( RecordLoad.class ) ) ).thenAnswer( new Answer<R>()
        {
            @Override
            public R answer( InvocationOnMock invocation ) throws Throwable
            {
                R record = (R) invocation.getArguments()[1];
                record.setId( ((Number)invocation.getArguments()[0]).longValue() );
                record.setNextProp( 1 );
                return record;
            }
        } );
        List<PropertyRecord> propertyChain = new ArrayList<>( propertyValues.length );
        for ( int i = 0; i < propertyValues.length; i++ )
        {
            propertyChain.add( newSingleIntProperty( i + 1, propertyValues[i] ) );
        }
        doReturn( propertyChain ).when( propertyStore ).getPropertyRecordChain( 1L );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.transaction.state.PropertyLoaderTest.setUpPropertyChain.thenAnswer.new Answer<R> with invocation -> {R record=(R)invocation.getArguments()[1]; in method private setUpPropertyChain(id long, recordClass Class<R>, store CommonAbstractStore<R,? extends StoreHeader>, propertyValues int...) : void from class org.neo4j.kernel.impl.transaction.state.PropertyLoaderTest


    @Test
    public void mirroredTraversalReversesInitialState() throws Exception
    {
        /*
         * (a)-->(b)-->(c)-->(d)
         */
        createGraph( "a TO b", "b TO c", "c TO d" );

        BranchCollisionPolicy collisionPolicy =
                ( evaluator, pathPredicate ) -> new StandardBranchCollisionDetector( null, null )
                {
                    @Override
                    protected boolean includePath( Path path, TraversalBranch startPath, TraversalBranch endPath )
                    {
                        assertEquals( 0, startPath.state() );
                        assertEquals( 10, endPath.state() );
                        return true;
                    }
                };

        Iterables.count( getGraphDb().bidirectionalTraversalDescription()
                // Just make up a number bigger than the path length (in this case 10) so that we can assert it in
                // the collision policy later
                .mirroredSides( getGraphDb().traversalDescription().uniqueness( NODE_PATH ).expand(
                        PathExpanders.forType( to ),
                        new InitialBranchState.State<>( 0, 10 ) ) )
                .collisionPolicy( collisionPolicy )
                .traverse( getNodeWithName( "a" ), getNodeWithName( "d" ) ) );
    }

    @Test
    public void mirroredTraversalReversesInitialState() throws Exception
    {
        /*
         * (a)-->(b)-->(c)-->(d)
         */
        createGraph( "a TO b", "b TO c", "c TO d" );

        BranchCollisionPolicy collisionPolicy = new BranchCollisionPolicy()
        {
            @Override
            public BranchCollisionDetector create( Evaluator evaluator, Predicate<Path> pathPredicate )
            {
                return new StandardBranchCollisionDetector( null, null )
                {
                    @Override
                    protected boolean includePath( Path path, TraversalBranch startPath, TraversalBranch endPath )
                    {
                        assertEquals( 0, startPath.state() );
                        assertEquals( 10, endPath.state() );
                        return true;
                    }
                };
            }
        };

        Iterables.count( getGraphDb().bidirectionalTraversalDescription()
                // Just make up a number bigger than the path length (in this case 10) so that we can assert it in
                // the collision policy later
                .mirroredSides( getGraphDb().traversalDescription().uniqueness( NODE_PATH ).expand(
                        PathExpanders.forType( to ),
                        new InitialBranchState.State<>( 0, 10 ) ) )
                .collisionPolicy( collisionPolicy )
                .traverse( getNodeWithName( "a" ), getNodeWithName( "d" ) ) );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.traversal.TestBidirectionalTraversal.mirroredTraversalReversesInitialState.collisionPolicy.new BranchCollisionPolicy with (evaluator, pathPredicate) -> new StandardBranchCollisionDetector(null,null){ in method public mirroredTraversalReversesInitialState() : void from class org.neo4j.kernel.impl.traversal.TestBidirectionalTraversal


    @Test
    public void testMaxDepthAndCustomPruneEvaluatorCombined()
    {
        Evaluator lessThanThreeRels =
                path -> count( path.endNode().getRelationships( Direction.OUTGOING ).iterator() ) < 3 ?
                        Evaluation.INCLUDE_AND_PRUNE : Evaluation.INCLUDE_AND_CONTINUE;

        TraversalDescription description = getGraphDb().traversalDescription().evaluator( Evaluators.all() )
                .evaluator( toDepth( 1 ) ).evaluator( lessThanThreeRels );
        Set<String> expectedNodes = new HashSet<String>(
                asList( "a", "b", "c", "d", "e" ) );
        try ( Transaction tx = beginTx() )
        {
            for ( Path position : description.traverse( node( "a" ) ) )
            {
                String name = (String) position.endNode().getProperty( "name" );
                assertTrue( name + " shouldn't have been returned", expectedNodes.remove( name ) );
            }
            tx.success();
        }
        assertTrue( expectedNodes.isEmpty() );
    }

    @Test
    public void testMaxDepthAndCustomPruneEvaluatorCombined()
    {
        Evaluator lessThanThreeRels = new Evaluator()
        {
            public Evaluation evaluate( Path path )
            {
                return count( path.endNode().getRelationships( Direction.OUTGOING ).iterator() ) < 3 ?
                        Evaluation.INCLUDE_AND_PRUNE : Evaluation.INCLUDE_AND_CONTINUE;
            }
        };

        TraversalDescription description = getGraphDb().traversalDescription().evaluator( Evaluators.all() )
                .evaluator( toDepth( 1 ) ).evaluator( lessThanThreeRels );
        Set<String> expectedNodes = new HashSet<String>(
                asList( "a", "b", "c", "d", "e" ) );
        try ( Transaction tx = beginTx() )
        {
            for ( Path position : description.traverse( node( "a" ) ) )
            {
                String name = (String) position.endNode().getProperty( "name" );
                assertTrue( name + " shouldn't have been returned", expectedNodes.remove( name ) );
            }
            tx.success();
        }
        assertTrue( expectedNodes.isEmpty() );
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.traversal.TestMultiPruneEvaluators.testMaxDepthAndCustomPruneEvaluatorCombined.lessThanThreeRels.new Evaluator with path -> count(path.endNode().getRelationships(Direction.OUTGOING).iterator()) < 3 ? Evaluation.INCLUDE_AND_PRUNE : Evaluation.INCLUDE_AND_CONTINUE in method public testMaxDepthAndCustomPruneEvaluatorCombined() : void from class org.neo4j.kernel.impl.traversal.TestMultiPruneEvaluators


    /**
     * @return a {@link Factory} that via reflection instantiates objects of the supplied {@code valueType},
     * assuming zero-argument constructor.
     */
    public static <V> Factory<V> values( final Class<V> valueType )
    {
        return () ->
        {
            try
            {
                return valueType.newInstance();
            }
            catch ( InstantiationException | IllegalAccessException e )
            {
                throw new RuntimeException( e );
            }
        };
    }

    /**
     * @return a {@link Factory} that via reflection instantiates objects of the supplied {@code valueType},
     * assuming zero-argument constructor.
     */
    public static <V> Factory<V> values( final Class<V> valueType )
    {
        return new Factory<V>()
        {
            @Override
            public V newInstance()
            {
                try
                {
                    return valueType.newInstance();
                }
                catch ( InstantiationException | IllegalAccessException e )
                {
                    throw new RuntimeException( e );
                }
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.util.AutoCreatingHashMap.values.new Factory<V> with () -> {tryreturn valueType.newInstance(); in method public values(valueType Class<V>) : Factory<V> from class org.neo4j.kernel.impl.util.AutoCreatingHashMap


    private WorkerCommand<Void,Void> invalidate( final LazySingleReference<Integer> ref )
    {
        return state ->
        {
            ref.invalidate();
            return null;
        };
    }

    private WorkerCommand<Void,Void> invalidate( final LazySingleReference<Integer> ref )
    {
        return new WorkerCommand<Void,Void>()
        {
            @Override
            public Void doWork( Void state ) throws Exception
            {
                ref.invalidate();
                return null;
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.kernel.impl.util.LazySingleReferenceTest.invalidate.new WorkerCommand<Void,Void> with state -> {ref.invalidate(); in method private invalidate(ref LazySingleReference<Integer>) : WorkerCommand<Void,Void> from class org.neo4j.kernel.impl.util.LazySingleReferenceTest


    private AutoCloseable closeable( final Method method, final Object target )
    {
        return () ->
        {
            try
            {
                method.invoke( target );
            }
            catch ( IllegalAccessException | IllegalArgumentException | InvocationTargetException e )
            {
                throw new RuntimeException( e );
            }
        };
    }

    private AutoCloseable closeable( final Method method, final Object target )
    {
        return new AutoCloseable()
        {
            @Override
            public void close() throws IOException
            {
                try
                {
                    method.invoke( target );
                }
                catch ( IllegalAccessException | IllegalArgumentException | InvocationTargetException e )
                {
                    throw new RuntimeException( e );
                }
            }
        };
    }

Replace Anonymous With Lambda org.neo4j.test.rule.CleanupRule.closeable.new AutoCloseable with () -> {trymethod.invoke(target); in method private closeable(method Method, target Object) : AutoCloseable from class org.neo4j.test.rule.CleanupRule


    @Override
    protected synchronized void before() throws Throwable
    {
        if ( null == thunk )
        {
            super.before();
            thunk = executor.schedule( (Callable<Void>) () ->
            {
                dump();
                return null;
            }, duration, timeUnit );
        }
        else
        {
            throw new IllegalStateException( "process dumping thunk already started" );
        }
    }

    @Override
    protected synchronized void before() throws Throwable
    {
        if ( null == thunk )
        {
            super.before();
            thunk = executor.schedule( new Callable<Void>()
            {
                @Override
                public Void call() throws Exception
                {
                    dump();
                    return null;
                }
            }, duration, timeUnit );
        }
        else
        {
            throw new IllegalStateException( "process dumping thunk already started" );
        }
    }

Replace Anonymous With Lambda org.neo4j.test.rule.dump.DumpProcessInformationRule.before.schedule.new Callable<Void> with () -> {dump(); in method protected before() : void from class org.neo4j.test.rule.dump.DumpProcessInformationRule


    @Test
    public void shouldCacheMultipleDenseNodeRelationshipHeads() throws Exception
    {
        // GIVEN
        cache = new NodeRelationshipCache( NumberArrayFactory.HEAP, 1 );
        cache.setHighNodeId( 10 );
        long nodeId = 3;
        cache.setCount( nodeId, 10, /*these do not matter ==>*/ 0, OUTGOING );

        // WHEN
        Map<Pair<Integer,Direction>,Long> firstRelationshipIds = new HashMap<>();
        int typeCount = 3;
        for ( int typeId = 0, relationshipId = 0; typeId < typeCount; typeId++ )
        {
            for ( Direction direction : Direction.values() )
            {
                long firstRelationshipId = relationshipId++;
                cache.getAndPutRelationship( nodeId, typeId, direction, firstRelationshipId, true );
                firstRelationshipIds.put( Pair.of( typeId, direction ), firstRelationshipId );
            }
        }
        AtomicInteger visitCount = new AtomicInteger();
        GroupVisitor visitor = ( nodeId1, typeId, out, in, loop ) ->
        {
            visitCount.incrementAndGet();
            assertEquals( firstRelationshipIds.get( Pair.of( typeId, OUTGOING ) ).longValue(), out );
            assertEquals( firstRelationshipIds.get( Pair.of( typeId, INCOMING ) ).longValue(), in );
            assertEquals( firstRelationshipIds.get( Pair.of( typeId, BOTH ) ).longValue(), loop );
            return 0;
        };
        cache.getFirstRel( nodeId, visitor );

        // THEN
        assertEquals( typeCount, visitCount.get() );
    }

    @Test
    public void shouldCacheMultipleDenseNodeRelationshipHeads() throws Exception
    {
        // GIVEN
        cache = new NodeRelationshipCache( NumberArrayFactory.HEAP, 1 );
        cache.setHighNodeId( 10 );
        long nodeId = 3;
        cache.setCount( nodeId, 10, /*these do not matter ==>*/ 0, OUTGOING );

        // WHEN
        Map<Pair<Integer,Direction>,Long> firstRelationshipIds = new HashMap<>();
        int typeCount = 3;
        for ( int typeId = 0, relationshipId = 0; typeId < typeCount; typeId++ )
        {
            for ( Direction direction : Direction.values() )
            {
                long firstRelationshipId = relationshipId++;
                cache.getAndPutRelationship( nodeId, typeId, direction, firstRelationshipId, true );
                firstRelationshipIds.put( Pair.of( typeId, direction ), firstRelationshipId );
            }
        }
        AtomicInteger visitCount = new AtomicInteger();
        GroupVisitor visitor = new GroupVisitor()
        {
            @Override
            public long visit( long nodeId, int typeId, long out, long in, long loop )
            {
                visitCount.incrementAndGet();
                assertEquals( firstRelationshipIds.get( Pair.of( typeId, OUTGOING ) ).longValue(), out );
                assertEquals( firstRelationshipIds.get( Pair.of( typeId, INCOMING ) ).longValue(), in );
                assertEquals( firstRelationshipIds.get( Pair.of( typeId, BOTH ) ).longValue(), loop );
                return 0;
            }
        };
        cache.getFirstRel( nodeId, visitor );

        // THEN
        assertEquals( typeCount, visitCount.get() );
    }

Replace Anonymous With Lambda org.neo4j.unsafe.impl.batchimport.cache.NodeRelationshipCacheTest.shouldCacheMultipleDenseNodeRelationshipHeads.visitor.new GroupVisitor with (nodeId1, typeId, out, in, loop) -> {visitCount.incrementAndGet(); in method public shouldCacheMultipleDenseNodeRelationshipHeads() : void from class org.neo4j.unsafe.impl.batchimport.cache.NodeRelationshipCacheTest


    @Test
    public void shouldDetectCorrectDuplicateInputIdsWhereManyAccidentalInManyGroups() throws Exception
    {
        // GIVEN
        final ControlledEncoder encoder = new ControlledEncoder( new LongEncoder() );
        IdMapper mapper = mapper( encoder, Radix.LONG, NO_MONITOR );
        final int idsPerGroup = 20;
        int groups = 5;
        final AtomicReference<Group> group = new AtomicReference<>();
        InputIterable<Object> ids = SimpleInputIteratorWrapper.wrap( "source", () -> new PrefetchingIterator<Object>()
        {
            private int i;

            @Override
            protected Object fetchNextOrNull()
            {
                // Change group every <idsPerGroup> id
                if ( i % idsPerGroup == 0 )
                {
                    int groupId = i / idsPerGroup;
                    if ( groupId == groups )
                    {
                        return null;
                    }
                    group.set( new Group.Adapter( groupId, "Group " + groupId ) );
                }
                try
                {
                    // Let the first 10% in each group be accidental collisions with each other
                    // i.e. all first 10% in each group collides with all other first 10% in each group
                    if ( i % idsPerGroup < 2 )
                    {   // Let these colliding values encode into the same eId as well,
                        // so that they are definitely marked as collisions
                        encoder.useThisIdToEncodeNoMatterWhatComesIn( Long.valueOf( 1234567 ) );
                        return Long.valueOf( i % idsPerGroup );
                    }

                    // The other 90% will be accidental collisions for something else
                    encoder.useThisIdToEncodeNoMatterWhatComesIn( Long.valueOf( 123456 - group.get().id() ) );
                    return Long.valueOf( i );
                }
                finally
                {
                    i++;
                }
            }
        } );

        // WHEN
        long actualId = 0;
        for ( Object id : ids )
        {
            mapper.put( id, actualId++, group.get() );
        }
        Collector collector = mock( Collector.class );
        mapper.prepare( ids, collector, NONE );

        // THEN
        verifyNoMoreInteractions( collector );
        actualId = 0;
        for ( Object id : ids )
        {
            assertEquals( actualId++, mapper.get( id, group.get() ) );
        }
    }

    @Test
    public void shouldDetectCorrectDuplicateInputIdsWhereManyAccidentalInManyGroups() throws Exception
    {
        // GIVEN
        final ControlledEncoder encoder = new ControlledEncoder( new LongEncoder() );
        IdMapper mapper = mapper( encoder, Radix.LONG, NO_MONITOR );
        final int idsPerGroup = 20;
        int groups = 5;
        final AtomicReference<Group> group = new AtomicReference<>();
        InputIterable<Object> ids = SimpleInputIteratorWrapper.wrap( "source", new Iterable<Object>()
        {
            @Override
            public Iterator<Object> iterator()
            {
                return new PrefetchingIterator<Object>()
                {
                    private int i;

                    @Override
                    protected Object fetchNextOrNull()
                    {
                        // Change group every <idsPerGroup> id
                        if ( i % idsPerGroup == 0 )
                        {
                            int groupId = i / idsPerGroup;
                            if ( groupId == groups )
                            {
                                return null;
                            }
                            group.set( new Group.Adapter( groupId, "Group " + groupId ) );
                        }
                        try
                        {
                            // Let the first 10% in each group be accidental collisions with each other
                            // i.e. all first 10% in each group collides with all other first 10% in each group
                            if ( i % idsPerGroup < 2 )
                            {   // Let these colliding values encode into the same eId as well,
                                // so that they are definitely marked as collisions
                                encoder.useThisIdToEncodeNoMatterWhatComesIn( Long.valueOf( 1234567 ) );
                                return Long.valueOf( i % idsPerGroup );
                            }

                            // The other 90% will be accidental collisions for something else
                            encoder.useThisIdToEncodeNoMatterWhatComesIn( Long.valueOf( 123456 - group.get().id() ) );
                            return Long.valueOf( i );
                        }
                        finally
                        {
                            i++;
                        }
                    }
                };
            }
        } );

        // WHEN
        long actualId = 0;
        for ( Object id : ids )
        {
            mapper.put( id, actualId++, group.get() );
        }
        Collector collector = mock( Collector.class );
        mapper.prepare( ids, collector, NONE );

        // THEN
        verifyNoMoreInteractions( collector );
        actualId = 0;
        for ( Object id : ids )
        {
            assertEquals( actualId++, mapper.get( id, group.get() ) );
        }
    }

Replace Anonymous With Lambda org.neo4j.unsafe.impl.batchimport.cache.idmapping.string.EncodingIdMapperTest.shouldDetectCorrectDuplicateInputIdsWhereManyAccidentalInManyGroups.ids.wrap.new Iterable<Object> with () -> new PrefetchingIterator<Object>(){ in method public shouldDetectCorrectDuplicateInputIdsWhereManyAccidentalInManyGroups() : void from class org.neo4j.unsafe.impl.batchimport.cache.idmapping.string.EncodingIdMapperTest


    @Test
    public void shouldLetShutdownCompleteInEventOfPanic() throws Exception
    {
        // GIVEN
        final TaskExecutor<Void> executor = new DynamicTaskExecutor<>( 2, 0, 10, PARK,
                getClass().getSimpleName() );
        IOException exception = new IOException( "Failure" );

        // WHEN
        FailingTask failingTask = new FailingTask( exception );
        executor.submit( failingTask );
        failingTask.latch.await();

        // WHEN
        try ( OtherThreadExecutor<Void> closer = new OtherThreadExecutor<>( "closer", null ) )
        {
            Future<Void> shutdown = closer.executeDontWait( state ->
            {
                executor.close();
                return null;
            } );
            while ( !closer.waitUntilWaiting().isAt( DynamicTaskExecutor.class, "close" ) )
            {
                Thread.sleep( 10 );
            }

            // Here we've got a shutdown call stuck awaiting queue to be empty (since true was passed in)
            // at the same time we've got a FailingTask ready to throw its exception and another task
            // sitting in the queue after it. Now make the task throw that exception.
            failingTask.latch.release();

            // Some time after throwing this, the shutdown request should have been completed.
            shutdown.get();
        }
    }

    @Test
    public void shouldLetShutdownCompleteInEventOfPanic() throws Exception
    {
        // GIVEN
        final TaskExecutor<Void> executor = new DynamicTaskExecutor<>( 2, 0, 10, PARK,
                getClass().getSimpleName() );
        IOException exception = new IOException( "Failure" );

        // WHEN
        FailingTask failingTask = new FailingTask( exception );
        executor.submit( failingTask );
        failingTask.latch.await();

        // WHEN
        try ( OtherThreadExecutor<Void> closer = new OtherThreadExecutor<>( "closer", null ) )
        {
            Future<Void> shutdown = closer.executeDontWait( new WorkerCommand<Void,Void>()
            {
                @Override
                public Void doWork( Void state ) throws Exception
                {
                    executor.close();
                    return null;
                }
            } );
            while ( !closer.waitUntilWaiting().isAt( DynamicTaskExecutor.class, "close" ) )
            {
                Thread.sleep( 10 );
            }

            // Here we've got a shutdown call stuck awaiting queue to be empty (since true was passed in)
            // at the same time we've got a FailingTask ready to throw its exception and another task
            // sitting in the queue after it. Now make the task throw that exception.
            failingTask.latch.release();

            // Some time after throwing this, the shutdown request should have been completed.
            shutdown.get();
        }
    }

Replace Anonymous With Lambda org.neo4j.unsafe.impl.batchimport.executor.DynamicTaskExecutorTest.shouldLetShutdownCompleteInEventOfPanic.shutdown.executeDontWait.new WorkerCommand<Void,Void> with state -> {executor.close(); in method public shouldLetShutdownCompleteInEventOfPanic() : void from class org.neo4j.unsafe.impl.batchimport.executor.DynamicTaskExecutorTest


    @Test
    public void shouldBeAbleToAskForSourceInformationEvenBetweenTwoSources() throws Exception
    {
        // GIVEN
        List<DataFactory<InputNode>> data = asList( data( ":ID\n1" ), data( "2" ) );
        final AtomicInteger flips = new AtomicInteger();
        final AtomicReference<InputGroupsDeserializer<InputNode>> deserializerTestHack = new AtomicReference<>( null );
        InputGroupsDeserializer<InputNode> deserializer = new InputGroupsDeserializer<>(
                data.iterator(), defaultFormatNodeFileHeader(), lowBufferSize( COMMAS, true ), INTEGER,
                Runtime.getRuntime().availableProcessors(), 1, ( header, stream, decorator, validator ) ->
                {
                    // This is the point where the currentInput field in InputGroupsDeserializer was null
                    // so ensure that's no longer the case, just by poking those source methods right here and now.
                    if ( flips.get() == 0 )
                    {
                        assertNotNull( deserializerTestHack.get().sourceDescription() );
                    }
                    else
                    {
                        assertEquals( "" + flips.get(), deserializerTestHack.get().sourceDescription() );
                    }

                    flips.incrementAndGet();
                    @SuppressWarnings( "unchecked" )
                    InputEntityDeserializer<InputNode> result = mock( InputEntityDeserializer.class );
                    when( result.sourceDescription() ).thenReturn( String.valueOf( flips.get() ) );
                    doAnswer( invocation ->
                    {
                        stream.close();
                        return null;
                    } ).when( result ).close();
                    return result;
                }, Validators.emptyValidator(), InputNode.class );
        deserializerTestHack.set( deserializer );

        // WHEN running through the iterator
        count( deserializer );

        // THEN there should have been two data source flips
        assertEquals( 2, flips.get() );
        deserializer.close();
    }

    @Test
    public void shouldBeAbleToAskForSourceInformationEvenBetweenTwoSources() throws Exception
    {
        // GIVEN
        List<DataFactory<InputNode>> data = asList( data( ":ID\n1" ), data( "2" ) );
        final AtomicInteger flips = new AtomicInteger();
        final AtomicReference<InputGroupsDeserializer<InputNode>> deserializerTestHack = new AtomicReference<>( null );
        InputGroupsDeserializer<InputNode> deserializer = new InputGroupsDeserializer<>(
                data.iterator(), defaultFormatNodeFileHeader(), lowBufferSize( COMMAS, true ), INTEGER,
                Runtime.getRuntime().availableProcessors(), 1, ( header, stream, decorator, validator ) ->
                {
                    // This is the point where the currentInput field in InputGroupsDeserializer was null
                    // so ensure that's no longer the case, just by poking those source methods right here and now.
                    if ( flips.get() == 0 )
                    {
                        assertNotNull( deserializerTestHack.get().sourceDescription() );
                    }
                    else
                    {
                        assertEquals( "" + flips.get(), deserializerTestHack.get().sourceDescription() );
                    }

                    flips.incrementAndGet();
                    @SuppressWarnings( "unchecked" )
                    InputEntityDeserializer<InputNode> result = mock( InputEntityDeserializer.class );
                    when( result.sourceDescription() ).thenReturn( String.valueOf( flips.get() ) );
                    doAnswer( new Answer<Void>()
                    {
                        @Override
                        public Void answer( InvocationOnMock invocation ) throws Throwable
                        {
                            stream.close();
                            return null;
                        }
                    } ).when( result ).close();
                    return result;
                }, Validators.emptyValidator(), InputNode.class );
        deserializerTestHack.set( deserializer );

        // WHEN running through the iterator
        count( deserializer );

        // THEN there should have been two data source flips
        assertEquals( 2, flips.get() );
        deserializer.close();
    }

Replace Anonymous With Lambda org.neo4j.unsafe.impl.batchimport.input.csv.InputGroupsDeserializerTest.shouldBeAbleToAskForSourceInformationEvenBetweenTwoSources.deserializer.new InputGroupsDeserializer<>.close.when.doAnswer.new Answer<Void> with invocation -> {stream.close(); in method public shouldBeAbleToAskForSourceInformationEvenBetweenTwoSources() : void from class org.neo4j.unsafe.impl.batchimport.input.csv.InputGroupsDeserializerTest