/**
   * Initializes a new SourceNodeRangeReader.
   *
   * @param sourceLocation the source location
   * @param start the start (inclusive) of the range to read
   * @param end the end (exclusive) of the range to read
   * @param skipHandler an object that will determine characters to skip while reading a source
   *     node. Specify <code>null</code> to skip no characters.
   */
  public SourceNodeRangeReader(
      @Nonnull SourceLocation sourceLocation,
      int start,
      int end,
      @CheckForNull SkipHandler skipHandler) {
    if (sourceLocation == null) {
      throw new NullPointerException("sourceLocation");
    }

    this.sourceLocation = sourceLocation;
    start = restrictStartBound(start, sourceLocation);
    end = restrictEndBound(start, end, sourceLocation);
    final int sourceLocationTextPosition = sourceLocation.getTextPosition();
    this.reader = new DocumentReader(sourceLocation.getFile().getText());
    this.rangedReader =
        new RangedCharSequenceReader(
            this.reader, start + sourceLocationTextPosition, end + sourceLocationTextPosition);
    if (skipHandler == null) {
      skipHandler = new SkipHandler();
    }

    this.skipHandler = skipHandler;
    skipHandler.setReader(this);
    this.checkForCodePointsToSkip();
  }
  private static int restrictEndBound(int start, int end, @Nonnull SourceLocation sourceLocation) {
    if (end < start) {
      return start;
    }

    if (end > sourceLocation.getSourceNode().getLength()) {
      return sourceLocation.getSourceNode().getLength();
    }

    return end;
  }
  private static int restrictStartBound(int start, @Nonnull SourceLocation sourceLocation) {
    if (start < 0) {
      return 0;
    }

    if (start > sourceLocation.getSourceNode().getLength()) {
      return sourceLocation.getSourceNode().getLength();
    }

    return start;
  }
  public void store(final IEclipsePreferences root) throws BackingStoreException {
    CodePathLocation.clearAll(root);
    root.put(ProjectPreferencesConstants.OUTPUT, output.toPortableString());
    if (requiredRuntimeVersion != null) {
      root.put(
          ProjectPreferencesConstants.REQUIRED_BACKEND_VERSION, requiredRuntimeVersion.toString());
    }
    root.put(ProjectPreferencesConstants.INCLUDES, PathSerializer.packList(includes));
    final Preferences srcNode = root.node(ProjectPreferencesConstants.SOURCES);
    for (final SourceLocation loc : sources) {
      loc.store((IEclipsePreferences) srcNode.node(Integer.toString(loc.getId())));
    }

    root.flush();
  }
 public ModelRuleDescriptor toDescriptor(SourceLocation sourceLocation, ModelPath modelPath) {
   return sourceLocation.asDescriptor("model." + modelPath);
 }