class PointAlongLineDecoder implements LocationReferenceDecoder {

    @Override
    public RawLocationReference decode(String id, LocationReferenceData data) throws OpenLRProtoException {
        if (!data.hasPointAlongLineLocationReference()) {
            throw new OpenLRProtoException(OpenLRProtoStatusCode.MISSING_LOCATION_REFERENCE);
        }

        PointAlongLineLocationReference pointAlongLineLocationReference = data.getPointAlongLineLocationReference();

        if (!pointAlongLineLocationReference.hasFirst()) {
            throw new OpenLRProtoException(OpenLRProtoStatusCode.INVALID_LOCATION_REFERENCE);
        }

        LocationReferencePoint first = locationReferencePointDecoder.decode(
                pointAlongLineLocationReference.getFirst(), 1, false);

        if (!pointAlongLineLocationReference.hasLast()) {
            throw new OpenLRProtoException(OpenLRProtoStatusCode.INVALID_LOCATION_REFERENCE);
        }

        LocationReferencePoint last = locationReferencePointDecoder.decode(
                pointAlongLineLocationReference.getLast(), 2, true);

        Offsets offsets = new OffsetsProtoImpl(pointAlongLineLocationReference.getPositiveOffset());

        SideOfRoad sideOfRoad = map(pointAlongLineLocationReference.getSideOfRoad());
        Orientation orientation = map(pointAlongLineLocationReference.getOrientation());

        return new RawPointAlongLocRef(id, first, last, offsets, sideOfRoad, orientation);
    }

      PointAlongLineDecoder(LocationReferencePointDecoder locationReferencePointDecoder);

}