class RerouteMoveShard<T> extends RerouteOption {

    private final T shardId;
    private final T fromNodeIdOrName;
    private final T toNodeIdOrName;

    public RerouteMoveShard(T shardId, T fromNodeIdOrName, T toNodeIdOrName) {
        this.shardId = shardId;
        this.fromNodeIdOrName = fromNodeIdOrName;
        this.toNodeIdOrName = toNodeIdOrName;
    }

    public T shardId() {
        return shardId;
    }

    public T fromNodeIdOrName() {
        return fromNodeIdOrName;
    }

    public T toNodeIdOrName() {
        return toNodeIdOrName;
    }

    public <U> RerouteMoveShard<U> map(Function<? super T, ? extends U> mapper) {
        return new RerouteMoveShard<>(
            mapper.apply(shardId),
            mapper.apply(fromNodeIdOrName),
            mapper.apply(toNodeIdOrName));
    }

    @Override
    public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

    @Override
    public int hashCode() {
        return Objects.hash(shardId, fromNodeIdOrName, toNodeIdOrName);
    }

    @Override
    public String toString() {
        return "RerouteMoveShard{" +
               "shardId=" + shardId +
               ", fromNodeId=" + fromNodeIdOrName +
               ", toNodeId=" + toNodeIdOrName +
               '}';
    }

    @Override
    public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
        return visitor.visitRerouteMoveShard(this, context);
    }
}

        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        RerouteMoveShard<?> that = (RerouteMoveShard<?>) o;
        return Objects.equals(shardId, that.shardId) &&
               Objects.equals(fromNodeIdOrName, that.fromNodeIdOrName) &&
               Objects.equals(toNodeIdOrName, that.toNodeIdOrName);
    
<methods>public non-sealed void <init>() <variables>