class LimitAndOffsetProjection extends Projection {

    private final int limit;
    private final int offset;
    private final List<Symbol> outputs;

    public LimitAndOffsetProjection(int limit, int offset, List<DataType<?>> outputTypes) {
        this.limit = limit;
        this.offset = offset;
        this.outputs = InputColumn.mapToInputColumns(outputTypes);
    }

    public LimitAndOffsetProjection(StreamInput in) throws IOException {
        offset = in.readVInt();
        limit = in.readVInt();
        outputs = Symbols.listFromStream(in);
    }

    @Override
    public List<Symbol> outputs() {
        return outputs;
    }

    public int limit() {
        return limit;
    }

    public int offset() {
        return offset;
    }

    @Override
    public ProjectionType projectionType() {
        return ProjectionType.LIMITANDOFFSET;
    }

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

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeVInt(offset);
        out.writeVInt(limit);
        Symbols.toStream(outputs, out);
    }

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

    @Override
    public int hashCode() {
        int result = limit;
        result = 31 * result + offset;
        result = 31 * result + outputs.hashCode();
        return result;
    }

    @Override
    public Map<String, Object> mapRepresentation() {
        return MapBuilder.<String, Object>newMapBuilder()
            .put("type", "LimitAndOffset")
            .put("limit", limit)
            .put("offset", offset)
            .put("outputs", Lists.joinOn(", ", outputs, Symbol::toString))
            .map();
    }

    @Override
    public String toString() {
        return "LimitAndOffsetProjection{" +
               "outputs=" + outputs +
               ", limit=" + limit +
               ", offset=" + offset +
               '}';
    }

}

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        LimitAndOffsetProjection that = (LimitAndOffsetProjection) o;

        if (limit != that.limit) return false;
        if (offset != that.offset) return false;
        if (!outputs.equals(that.outputs)) return false;
        return true;
    
<methods>public non-sealed void <init>() ,public abstract R accept(ProjectionVisitor<C,R>, C) ,public abstract boolean equals(java.lang.Object) ,public static io.crate.execution.dsl.projection.Projection fromStream(org.elasticsearch.common.io.stream.StreamInput) throws java.io.IOException,public int hashCode() ,public Map<java.lang.String,java.lang.Object> mapRepresentation() ,public abstract List<? extends io.crate.expression.symbol.Symbol> outputs() ,public abstract io.crate.execution.dsl.projection.ProjectionType projectionType() ,public io.crate.metadata.RowGranularity requiredGranularity() ,public static void toStream(io.crate.execution.dsl.projection.Projection, org.elasticsearch.common.io.stream.StreamOutput) throws java.io.IOException,public abstract void writeTo(org.elasticsearch.common.io.stream.StreamOutput) throws java.io.IOException<variables>static final Predicate<io.crate.execution.dsl.projection.Projection> IS_NODE_PROJECTION,static final Predicate<io.crate.execution.dsl.projection.Projection> IS_SHARD_PROJECTION