class CountPhase implements UpstreamPhase {

    private final int executionPhaseId;
    private final Routing routing;
    private final Symbol where;
    private DistributionInfo distributionInfo;

    public CountPhase(int executionPhaseId,
                      Routing routing,
                      Symbol where,
                      DistributionInfo distributionInfo) {
        this.executionPhaseId = executionPhaseId;
        this.routing = routing;
        this.where = where;
        this.distributionInfo = distributionInfo;
    }

    @Override
    public Type type() {
        return Type.COUNT;
    }

    @Override
    public String name() {
        return "count";
    }

    public Routing routing() {
        return routing;
    }

    public Symbol where() {
        return where;
    }

    @Override
    public int phaseId() {
        return executionPhaseId;
    }

    @Override
    public Set<String> nodeIds() {
        return routing.nodes();
    }

    @Override
    public DistributionInfo distributionInfo() {
        return distributionInfo;
    }

    @Override
    public void distributionInfo(DistributionInfo distributionInfo) {
        this.distributionInfo = distributionInfo;
    }

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

    public CountPhase(StreamInput in) throws IOException {
        executionPhaseId = in.readVInt();
        routing = new Routing(in);
        where = Symbols.fromStream(in);
        distributionInfo = new DistributionInfo(in);
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeVInt(executionPhaseId);
        routing.writeTo(out);
        Symbols.toStream(where, out);
        distributionInfo.writeTo(out);
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(executionPhaseId, routing, where, distributionInfo);
    }
}

        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        CountPhase that = (CountPhase) o;
        return executionPhaseId == that.executionPhaseId &&
               Objects.equals(routing, that.routing) &&
               Objects.equals(where, that.where) &&
               Objects.equals(distributionInfo, that.distributionInfo);
    
<no_super_class>