private Iterator<UniquenessConstraint> applyConstraintsDiff(
     KernelStatement state, Iterator<UniquenessConstraint> constraints) {
   if (state.hasTxStateWithChanges()) {
     return state.txState().constraintsChanges().apply(constraints);
   }
   return constraints;
 }
 @Override
 public PrimitiveIntIterator nodeGetLabels(KernelStatement state, long nodeId)
     throws EntityNotFoundException {
   if (state.hasTxStateWithChanges()) {
     return nodeGetLabels(storeLayer, state.txState(), nodeId);
   }
   return storeLayer.nodeGetLabels(nodeId);
 }
  @Override
  public Iterator<DefinedProperty> graphGetAllProperties(KernelStatement state) {
    if (state.hasTxStateWithChanges()) {
      return state.txState().augmentGraphProperties(storeLayer.graphGetAllProperties());
    }

    return storeLayer.graphGetAllProperties();
  }
  @Override
  public Iterator<IndexDescriptor> uniqueIndexesGetAll(KernelStatement state) {
    if (state.hasTxStateWithChanges()) {
      return state.txState().constraintIndexChanges().apply(storeLayer.uniqueIndexesGetAll());
    }

    return storeLayer.uniqueIndexesGetAll();
  }
 // <Legacy index>
 @Override
 public <EXCEPTION extends Exception> void relationshipVisit(
     KernelStatement statement, long relId, RelationshipVisitor<EXCEPTION> visitor)
     throws EntityNotFoundException, EXCEPTION {
   if (statement.hasTxStateWithChanges()) {
     if (statement.txState().relationshipVisit(relId, visitor)) {
       return;
     }
   }
   storeLayer.relationshipVisit(relId, visitor);
 }
 @Override
 public long countsForNode(KernelStatement statement, int labelId) {
   long count = storeLayer.countsForNode(labelId);
   if (statement.hasTxState()) {
     if (labelId != ReadOperations.ANY_LABEL) {
       throw new UnsupportedOperationException("not implemented");
     }
     count += statement.txState().addedAndRemovedNodes().delta();
   }
   return count;
 }
  private Iterator<UniquenessConstraint> applyConstraintsDiff(
      KernelStatement state, Iterator<UniquenessConstraint> constraints) {
    if (state.hasTxStateWithChanges()) {
      DiffSets<UniquenessConstraint> diff = state.txState().constraintsChanges();
      if (diff != null) {
        return diff.apply(constraints);
      }
    }

    return constraints;
  }
  private PrimitiveLongIterator filterIndexStateChanges(
      KernelStatement state, IndexDescriptor index, Object value, PrimitiveLongIterator nodeIds) {
    if (state.hasTxStateWithChanges()) {
      ReadableDiffSets<Long> labelPropertyChanges = state.txState().indexUpdates(index, value);
      ReadableDiffSets<Long> nodes = state.txState().addedAndRemovedNodes();

      // Apply to actual index lookup
      return nodes.augmentWithRemovals(labelPropertyChanges.augment(nodeIds));
    }
    return nodeIds;
  }
  @Override
  public Iterator<IndexDescriptor> uniqueIndexesGetForLabel(KernelStatement state, int labelId) {
    if (state.hasTxStateWithChanges()) {
      return state
          .txState()
          .constraintIndexDiffSetsByLabel(labelId)
          .apply(storeLayer.uniqueIndexesGetForLabel(labelId));
    }

    return storeLayer.uniqueIndexesGetForLabel(labelId);
  }
 private Iterator<UniquenessConstraint> applyConstraintsDiff(
     KernelStatement state,
     Iterator<UniquenessConstraint> constraints,
     int labelId,
     int propertyKeyId) {
   if (state.hasTxStateWithChanges()) {
     return state
         .txState()
         .constraintsChangesForLabelAndProperty(labelId, propertyKeyId)
         .apply(constraints);
   }
   return constraints;
 }
  @Override
  public PrimitiveLongIterator nodesGetForLabel(KernelStatement state, int labelId) {
    if (state.hasTxStateWithChanges()) {
      PrimitiveLongIterator wLabelChanges =
          state
              .txState()
              .nodesWithLabelChanged(labelId)
              .augment(storeLayer.nodesGetForLabel(state, labelId));
      return state.txState().addedAndRemovedNodes().augmentWithRemovals(wLabelChanges);
    }

    return storeLayer.nodesGetForLabel(state, labelId);
  }
  @Override
  public boolean relationshipExists(KernelStatement state, long relId) {
    if (state.hasTxStateWithChanges()) {
      if (state.txState().relationshipIsDeletedInThisTx(relId)) {
        return false;
      }

      if (state.txState().relationshipIsAddedInThisTx(relId)) {
        return true;
      }
    }

    return storeLayer.relationshipExists(relId);
  }
  @Override
  public IndexDescriptor indexesGetForLabelAndPropertyKey(
      KernelStatement state, int labelId, int propertyKey) {
    IndexDescriptor indexDescriptor =
        storeLayer.indexesGetForLabelAndPropertyKey(labelId, propertyKey);

    Iterator<IndexDescriptor> rules = iterator(indexDescriptor);
    if (state.hasTxStateWithChanges()) {
      rules =
          filterByPropertyKeyId(
              state.txState().indexDiffSetsByLabel(labelId).apply(rules), propertyKey);
    }
    return singleOrNull(rules);
  }
  @Override
  public boolean nodeExists(KernelStatement state, long nodeId) {
    if (state.hasTxStateWithChanges()) {
      if (state.txState().nodeIsDeletedInThisTx(nodeId)) {
        return false;
      }

      if (state.txState().nodeIsAddedInThisTx(nodeId)) {
        return true;
      }
    }

    return storeLayer.nodeExists(nodeId);
  }
 @Override
 public PrimitiveLongIterator nodeGetRelationships(
     KernelStatement state, long nodeId, Direction direction) throws EntityNotFoundException {
   if (state.hasTxStateWithChanges()) {
     ReadableTxState txState = state.txState();
     PrimitiveLongIterator stored;
     if (txState.nodeIsAddedInThisTx(nodeId)) {
       stored = PrimitiveLongCollections.emptyIterator();
     } else {
       stored = storeLayer.nodeListRelationships(nodeId, direction);
     }
     return txState.augmentRelationships(nodeId, direction, stored);
   }
   return storeLayer.nodeListRelationships(nodeId, direction);
 }
 @Override
 public Property relationshipRemoveProperty(
     KernelStatement state, long relationshipId, int propertyKeyId)
     throws EntityNotFoundException {
   state.locks().acquireRelationshipWriteLock(relationshipId);
   return entityWriteDelegate.relationshipRemoveProperty(state, relationshipId, propertyKeyId);
 }
  @Override
  public void relationshipDelete(final KernelStatement state, long relationshipId)
      throws EntityNotFoundException {
    assertRelationshipExists(state, relationshipId);

    // NOTE: We implicitly delegate to neoStoreTransaction via txState.legacyState here. This is
    // because that
    // call returns modified properties, which node manager uses to update legacy tx state. This
    // will be cleaned up
    // once we've removed legacy tx state.
    legacyPropertyTrackers.relationshipDelete(relationshipId);
    final TransactionState txState = state.txState();
    if (txState.relationshipIsAddedInThisTx(relationshipId)) {
      txState.relationshipDoDeleteAddedInThisTx(relationshipId);
    } else {
      try {
        storeLayer.relationshipVisit(
            relationshipId,
            new RelationshipVisitor<RuntimeException>() {
              @Override
              public void visit(long relId, int type, long startNode, long endNode) {
                txState.relationshipDoDelete(relId, type, startNode, endNode);
              }
            });
      } catch (EntityNotFoundException e) {
        // If it doesn't exist, it doesn't exist, and the user got what she wanted.
        return;
      }
    }
  }
 @Override
 public Property graphRemoveProperty(KernelStatement state, int propertyKeyId) {
   state
       .locks()
       .acquireExclusive(ResourceTypes.GRAPH_PROPS, ResourceTypes.graphPropertyResource());
   return entityWriteDelegate.graphRemoveProperty(state, propertyKeyId);
 }
 @Override
 public Property relationshipSetProperty(
     KernelStatement state, long relationshipId, DefinedProperty property)
     throws EntityNotFoundException {
   state.locks().acquireRelationshipWriteLock(relationshipId);
   return entityWriteDelegate.relationshipSetProperty(state, relationshipId, property);
 }
 @Override
 public Property relationshipRemoveProperty(
     KernelStatement state, long relationshipId, int propertyKeyId)
     throws EntityNotFoundException {
   state.locks().acquireExclusive(ResourceTypes.RELATIONSHIP, relationshipId);
   return entityWriteDelegate.relationshipRemoveProperty(state, relationshipId, propertyKeyId);
 }
 @Override
 public Property graphSetProperty(KernelStatement state, DefinedProperty property) {
   state
       .locks()
       .acquireExclusive(ResourceTypes.GRAPH_PROPS, ResourceTypes.graphPropertyResource());
   return entityWriteDelegate.graphSetProperty(state, property);
 }
 @Override
 public long indexGetCommittedId(
     KernelStatement state, IndexDescriptor index, SchemaStorage.IndexRuleKind kind)
     throws SchemaRuleNotFoundException {
   state.locks().acquireShared(ResourceTypes.SCHEMA, schemaResource());
   return schemaReadDelegate.indexGetCommittedId(state, index, kind);
 }
 @Override
 public UniquenessConstraint uniquenessConstraintCreate(
     KernelStatement state, int labelId, int propertyKeyId)
     throws CreateConstraintFailureException, AlreadyConstrainedException,
         AlreadyIndexedException {
   state.locks().acquireExclusive(ResourceTypes.SCHEMA, schemaResource());
   return schemaWriteDelegate.uniquenessConstraintCreate(state, labelId, propertyKeyId);
 }
 @Override
 public long relationshipCreate(
     KernelStatement state, int relationshipTypeId, long startNodeId, long endNodeId) {
   state.locks().acquireExclusive(ResourceTypes.NODE, startNodeId);
   state.locks().acquireExclusive(ResourceTypes.NODE, endNodeId);
   return entityWriteDelegate.relationshipCreate(
       state, relationshipTypeId, startNodeId, endNodeId);
 }
  @Override
  public int nodeGetDegree(KernelStatement state, long nodeId, Direction direction)
      throws EntityNotFoundException {
    if (state.hasTxStateWithChanges()) {
      int degree = 0;
      if (state.txState().nodeIsDeletedInThisTx(nodeId)) {
        return 0;
      }

      if (!state.txState().nodeIsAddedInThisTx(nodeId)) {
        degree = storeLayer.nodeGetDegree(nodeId, direction);
      }
      return state.txState().augmentNodeDegree(nodeId, degree, direction);
    } else {
      return storeLayer.nodeGetDegree(nodeId, direction);
    }
  }
  @Override
  public InternalIndexState indexGetState(KernelStatement state, IndexDescriptor descriptor)
      throws IndexNotFoundKernelException {
    // If index is in our state, then return populating
    if (state.hasTxStateWithChanges()) {
      if (checkIndexState(
          descriptor, state.txState().indexDiffSetsByLabel(descriptor.getLabelId()))) {
        return InternalIndexState.POPULATING;
      }
      if (checkIndexState(
          descriptor, state.txState().constraintIndexDiffSetsByLabel(descriptor.getLabelId()))) {
        return InternalIndexState.POPULATING;
      }
    }

    return storeLayer.indexGetState(descriptor);
  }
 @Override
 public Property graphRemoveProperty(KernelStatement state, int propertyKeyId) {
   Property existingProperty = graphGetProperty(state, propertyKeyId);
   if (existingProperty.isDefined()) {
     state.txState().graphDoRemoveProperty((DefinedProperty) existingProperty);
   }
   return existingProperty;
 }
  @Override
  public PrimitiveLongIterator graphGetPropertyKeys(KernelStatement state) {
    if (state.hasTxStateWithChanges()) {
      return new PropertyKeyIdIterator(graphGetAllProperties(state));
    }

    return storeLayer.graphGetPropertyKeys(state);
  }
  @Override
  public PrimitiveLongIterator relationshipGetPropertyKeys(
      KernelStatement state, long relationshipId) throws EntityNotFoundException {
    if (state.hasTxStateWithChanges()) {
      return new PropertyKeyIdIterator(relationshipGetAllProperties(state, relationshipId));
    }

    return storeLayer.relationshipGetPropertyKeys(relationshipId);
  }
  @Override
  public Iterator<DefinedProperty> nodeGetAllProperties(KernelStatement state, long nodeId)
      throws EntityNotFoundException {
    if (state.hasTxStateWithChanges()) {
      if (state.txState().nodeIsAddedInThisTx(nodeId)) {
        return state.txState().addedAndChangedNodeProperties(nodeId);
      }
      if (state.txState().nodeIsDeletedInThisTx(nodeId)) {
        // TODO Throw IllegalStateException to conform with beans API. We may want to introduce
        // EntityDeletedException instead and use it instead of returning empty values in similar
        // places
        throw new IllegalStateException("Node " + nodeId + " has been deleted");
      }
      return state.txState().augmentNodeProperties(nodeId, storeLayer.nodeGetAllProperties(nodeId));
    }

    return storeLayer.nodeGetAllProperties(nodeId);
  }