class TagEntry implements Comparable<TagEntry> {

    private static final String DATE_NULL_ASSERT = "date == null";

    /**
     * If repo uses linear revision numbering.
     */
    protected final int revision;
    /**
     * If repo does not use linear numbering.
     */
    protected final Date date;
    /**
     * Tag of the revision.
     */
    protected String tags;
    /**
     * Sentinel value for a repo that does not use linear numbering.
     */
    protected static final int NOREV = -1;

    /**
     * Initializes an instance for a repo where revision number is present.
     *
     * @param revision revision number
     * @param tags string representing tags
     */
    protected TagEntry(int revision, String tags) {
        this.revision = revision;
        this.date = null;
        this.tags = tags;
    }

    /**
     * Initializes an instance for a repo where revision number is not present
     * and {@code date} is used instead.
     *
     * @param date revision date
     * @param tags string representing tags
     * @throws IllegalArgumentException if {@code date} is null
     */
    protected TagEntry(Date date, String tags) {
        if (date == null) {
            throw new IllegalArgumentException("`date' is null");
        }
        this.revision = NOREV;
        this.date = date;
        this.tags = tags;
    }

    public String getTags() {
        return this.tags;
    }

    public void setTags(String tag) {
        this.tags = tag;
    }

    public Date getDate() {
        return date;
    }

    /**
     * Necessary Comparable method, used for sorting of TagEntries.
     *
     * @param that Compare to.
     * @return 1 for greater, 0 for equal and -1 for smaller objects.
     */
    @Override
    public int compareTo(TagEntry that) {<FILL_FUNCTION_BODY>}

    @Override
    public boolean equals(Object aThat) {
        if (this == aThat) {
            return true;
        }
        if (!(aThat instanceof TagEntry)) {
            return false;
        }
        TagEntry that = (TagEntry) aThat;
        if (this.revision != NOREV) {
            return this.revision == that.revision;
        }
        assert this.date != null : DATE_NULL_ASSERT;
        return this.date.equals(that.date);
    }

    @Override
    public int hashCode() {
        if (this.revision != NOREV) {
            return this.revision;
        }
        assert this.date != null : DATE_NULL_ASSERT;
        return this.date.hashCode();
    }

    /**
     * Compares to given HistoryEntry, needed for history parsing. Depends on
     * specific repository revision format, therefore abstract.
     *
     * @param aThat HistoryEntry we compare to.
     * @return 1 for greater, 0 for equal and -1 for smaller objects.
     */
    public abstract int compareTo(HistoryEntry aThat);
}

        if (this == that) {
            return 0;
        }

        if (this.revision != NOREV) {
            return Integer.compare(this.revision, that.revision);
        }
        assert this.date != null : DATE_NULL_ASSERT;
        return this.date.compareTo(that.date);
    
<no_super_class>