class IndexTxStateUpdater {

    void onPropertyChange( NodeCursor node, PropertyCursor propertyCursor, long[] labels, int propertyKeyId, int[] existingPropertyKeyIds,
            Value beforeValue, Value afterValue )
    {
        assert noSchemaChangedInTx();
        Collection<SchemaDescriptor> indexes = indexingService.getRelatedIndexes( labels, propertyKeyId, NODE );
        if ( !indexes.isEmpty() )
        {
            MutableIntObjectMap<Value> materializedProperties = IntObjectMaps.mutable.empty();
            NodeSchemaMatcher.onMatchingSchema( indexes.iterator(), propertyKeyId, existingPropertyKeyIds,
                    index ->
                    {
                        int[] propertyIds = index.getPropertyIds();
                        Value[] valuesAfter = getValueTuple( node, propertyCursor, propertyKeyId, afterValue, propertyIds, materializedProperties );

                        // The valuesBefore tuple is just like valuesAfter, except is has the afterValue instead of the beforeValue
                        Value[] valuesBefore = valuesAfter.clone();
                        int k = ArrayUtils.indexOf( propertyIds, propertyKeyId );
                        valuesBefore[k] = beforeValue;

                        indexingService.validateBeforeCommit( index, valuesAfter );
                        read.txState().indexDoUpdateEntry( index, node.nodeReference(),
                                ValueTuple.of( valuesBefore ), ValueTuple.of( valuesAfter ) );
                    } );
        }
    }

    public  IndexTxStateUpdater( Read read, IndexingService indexingService );

}