// Path: src/main/java/org/homer/versioner/core/exception/VersionerCoreException.java
// public class VersionerCoreException extends RuntimeException {
// 
//     public VersionerCoreException(String s) {
//         super(s);
//     }
// }
// 
// Path: src/main/java/org/homer/versioner/core/output/NodeOutput.java
// public class NodeOutput {
//     public Node node;
// 
//     public NodeOutput(Node node) {
//         this.node = node;
//     }
// }
// 
// Path: src/main/java/org/homer/versioner/core/output/RelationshipOutput.java
// public class RelationshipOutput {
//     public Relationship relationship;
// 
//     public RelationshipOutput(Relationship relationship) {
//         this.relationship = relationship;
//     }
// }


import org.apache.commons.lang3.tuple.Pair;
import org.homer.versioner.core.exception.VersionerCoreException;
import org.homer.versioner.core.output.NodeOutput;
import org.homer.versioner.core.output.RelationshipOutput;
import org.neo4j.graphdb.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
        entity.createRelationshipTo(state, RelationshipType.withName(HAS_STATE_TYPE)).setProperty(START_DATE_PROP, instantDate);
    }

    /**
     * Checks if the given entity is related through the HAS_STATE relationship with the given node
     *
     * @param entity a {@link Node} representing the Entity
     * @param state  a {@link Node} representing the State
     * @return {@link Boolean} result
     */
    public static Boolean checkRelationship(Node entity, Node state) {
        Spliterator<Relationship> stateRelIterator = state.getRelationships(Direction.INCOMING, RelationshipType.withName(Utility.HAS_STATE_TYPE)).spliterator();

        return StreamSupport.stream(stateRelIterator, false).map(hasStateRel -> {
            Node maybeEntity = hasStateRel.getStartNode();
            if (maybeEntity.getId() != entity.getId()) {
                throw new VersionerCoreException("Can't patch the given entity, because the given State is owned by another entity.");
            }
            return true;
        })
                .findFirst()
                .orElseThrow(() -> new VersionerCoreException("Can't find any entity node relate to the given State."));
    }

    /**
     * Converts the nodes to a stream of {@link NodeOutput}
     *
     * @param nodes a {@link List} of {@link Node} that will be converted to stream and mapped into {@link NodeOutput}
     * @return {@link Stream} streamOfNodes
     */
// Path: src/main/java/org/homer/versioner/core/exception/VersionerCoreException.java
// public class VersionerCoreException extends RuntimeException {
// 
//     public VersionerCoreException(String s) {
//         super(s);
//     }
// }
// 
// Path: src/main/java/org/homer/versioner/core/output/NodeOutput.java
// public class NodeOutput {
//     public Node node;
// 
//     public NodeOutput(Node node) {
//         this.node = node;
//     }
// }
// 
// Path: src/main/java/org/homer/versioner/core/output/RelationshipOutput.java
// public class RelationshipOutput {
//     public Relationship relationship;
// 
//     public RelationshipOutput(Relationship relationship) {
//         this.relationship = relationship;
//     }
// }


// Path: src/main/java/org/homer/versioner/core/Utility.java
import org.apache.commons.lang3.tuple.Pair;
import org.homer.versioner.core.exception.VersionerCoreException;
import org.homer.versioner.core.output.NodeOutput;
import org.homer.versioner.core.output.RelationshipOutput;
import org.neo4j.graphdb.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

        entity.createRelationshipTo(state, RelationshipType.withName(HAS_STATE_TYPE)).setProperty(START_DATE_PROP, instantDate);
    }

    /**
     * Checks if the given entity is related through the HAS_STATE relationship with the given node
     *
     * @param entity a {@link Node} representing the Entity
     * @param state  a {@link Node} representing the State
     * @return {@link Boolean} result
     */
    public static Boolean checkRelationship(Node entity, Node state) {
        Spliterator<Relationship> stateRelIterator = state.getRelationships(Direction.INCOMING, RelationshipType.withName(Utility.HAS_STATE_TYPE)).spliterator();

        return StreamSupport.stream(stateRelIterator, false).map(hasStateRel -> {
            Node maybeEntity = hasStateRel.getStartNode();
            if (maybeEntity.getId() != entity.getId()) {
                throw new VersionerCoreException("Can't patch the given entity, because the given State is owned by another entity.");
            }
            return true;
        })
                .findFirst()
                .orElseThrow(() -> new VersionerCoreException("Can't find any entity node relate to the given State."));
    }

    /**
     * Converts the nodes to a stream of {@link NodeOutput}
     *
     * @param nodes a {@link List} of {@link Node} that will be converted to stream and mapped into {@link NodeOutput}
     * @return {@link Stream} streamOfNodes
     */
    public static Stream<NodeOutput> streamOfNodes(Node... nodes) {