// Path: state-synchronization-api/src/main/java/pl/marekpazik/state_synchronisation/Version.java
// public final class Version {
//     private final int version;
// 
//     private Version(int version) {
//         this.version = version;
//     }
// 
//     public Version next() {
//         return new Version(version + 1);
//     }
// 
//     public static Version first() {
//         return new Version(1);
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
//         Version version1 = (Version) o;
//         return version == version1.version;
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(version);
//     }
// 
//     @Override
//     public String toString() {
//         return "Version{" +
//                 "version=" + version +
//                 '}';
//     }
// }
// 
// Path: state-synchronization-api/src/main/java/pl/marekpazik/state_synchronisation/common/Id.java
// public interface Id<T> {
// }


import pl.marekpazik.state_synchronisation.Version;
import pl.marekpazik.state_synchronisation.common.Id;
package pl.marekpazik.state_synchronisation.entity;


public abstract class AbstractEntity<
        E extends Entity<E>,
        P extends EntityProperties<E>,
        S extends EntityState<E>
        > implements Entity<E> {
    private final Id<E> id;
    private final P properties;
    private Version version;
    private S state;

    public AbstractEntity(Id<E> id, P properties, S state) {
        this.id = id;
        this.version = Version.first();
        this.properties = properties;
        this.state = state;
    }

    @Override
    public Id<E> getId() {
        return id;
    }

// Path: state-synchronization-api/src/main/java/pl/marekpazik/state_synchronisation/Version.java
// public final class Version {
//     private final int version;
// 
//     private Version(int version) {
//         this.version = version;
//     }
// 
//     public Version next() {
//         return new Version(version + 1);
//     }
// 
//     public static Version first() {
//         return new Version(1);
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
//         Version version1 = (Version) o;
//         return version == version1.version;
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(version);
//     }
// 
//     @Override
//     public String toString() {
//         return "Version{" +
//                 "version=" + version +
//                 '}';
//     }
// }
// 
// Path: state-synchronization-api/src/main/java/pl/marekpazik/state_synchronisation/common/Id.java
// public interface Id<T> {
// }


// Path: state-synchronization-api/src/main/java/pl/marekpazik/state_synchronisation/entity/AbstractEntity.java
import pl.marekpazik.state_synchronisation.Version;
import pl.marekpazik.state_synchronisation.common.Id;

package pl.marekpazik.state_synchronisation.entity;


public abstract class AbstractEntity<
        E extends Entity<E>,
        P extends EntityProperties<E>,
        S extends EntityState<E>
        > implements Entity<E> {
    private final Id<E> id;
    private final P properties;
    private Version version;
    private S state;

    public AbstractEntity(Id<E> id, P properties, S state) {
        this.id = id;
        this.version = Version.first();
        this.properties = properties;
        this.state = state;
    }

    @Override
    public Id<E> getId() {
        return id;
    }

    @Override