package org.spoofax.jsglr2.messages;

import org.spoofax.jsglr.client.imploder.IToken;
import org.spoofax.jsglr2.parser.Position;

public class SourceRegion {

    public final int startOffset, startRow, startColumn;
    /** Inclusive. */
    public final int endOffset, endRow, endColumn;

    public SourceRegion(int startOffset, int startRow, int startColumn, int endOffset, int endRow, int endColumn) {
        this.startOffset = startOffset;
        this.startRow = startRow;
        this.startColumn = startColumn;
        this.endOffset = endOffset;
        this.endRow = endRow;
        this.endColumn = endColumn;
    }

    public SourceRegion(Position start, Position end) {
        this.startOffset = start.offset;
        this.startRow = start.line;
        this.startColumn = start.column;
        this.endOffset = end.offset;
        this.endRow = end.line;
        this.endColumn = end.column;
    }

    public SourceRegion(Position position) {
        this(position, position);
    }

    public Position position() {
        return new Position(startOffset, startRow, startColumn);
    }

    @Override public String toString() {
        return "[" + startOffset + "," + startRow + "," + startColumn + "," + endOffset + "," + endRow + "," + endColumn
            + ']';
    }

    public static SourceRegion fromToken(IToken token) {
        return new SourceRegion(token.getStartOffset(), token.getLine(), token.getColumn(), token.getEndOffset(),
            token.getEndLine(), token.getEndColumn());
    }

}

@@ -124,16 +124,80 @@
 ition;%0A%0A
+import javax.annotation.Nullable;%0Aimport java.io.Serializable;%0A%0A
 public c
@@ -214,16 +214,40 @@
 eRegion 
+implements Serializable 
 %7B%0A%0A    p
@@ -1610,10 +1610,850 @@
 %0A    %7D%0A%0A
+    @Override public boolean equals(@Nullable Object o) %7B%0A        if(this == o) return true;%0A        if(o == null %7C%7C getClass() != o.getClass()) return false;%0A        final SourceRegion that = (SourceRegion)o;%0A        if(startOffset != that.startOffset) return false;%0A        if(startRow != that.startRow) return false;%0A        if(startColumn != that.startColumn) return false;%0A        if(endOffset != that.endOffset) return false;%0A        if(endRow != that.endRow) return false;%0A        return endColumn == that.endColumn;%0A    %7D%0A%0A    @Override public int hashCode() %7B%0A        int result = startOffset;%0A        result = 31 * result + startRow;%0A        result = 31 * result + startColumn;%0A        result = 31 * result + endOffset;%0A        result = 31 * result + endRow;%0A        result = 31 * result + endColumn;%0A        return result;%0A    %7D%0A
 %7D%0A

Make SourceRegion Serializable and implement equals/hashCode.