/**
     * Checks whether adding the resource section to map is possible.
     *
     * @return {@link RangeAdder} object that can be used to perform "add" operation; not null
     * @throws CannotAddException if resource section overlaps with already registered section
     */
    private RangeAdder checkCanAddRange(ResourceSection section) throws CannotAddException {
      final VmResourceId resourceId = section.getResourceId();
      final ResourceData data = resourceIdToData.get(resourceId);
      final Range range = Range.create(section);

      if (data != null) {
        data.checkCanAddRange(range);
      }
      return new RangeAdder() {
        /** Commits 'add' operation. No conflicts are expected at this stage. */
        public RangeDeleter commit(TextSectionMapping mapTable, VmResourceId destinationResource) {
          ResourceData commitData = resourceIdToData.get(resourceId);
          if (commitData == null) {
            commitData = new ResourceData();
            resourceIdToData.put(resourceId, commitData);
          }

          final ResourceData commitDataFinal = commitData;
          commitDataFinal.addRange(range, mapTable, destinationResource);

          return new RangeDeleter() {
            public void delete() {
              commitDataFinal.removeRange(range);
              if (commitDataFinal.isEmpty()) {
                resourceIdToData.remove(resourceId);
              }
            }
          };
        }
      };
    }
 SourcePosition transformImpl(VmResourceId id, int line, int column) {
   ResourceData resourceData = resourceIdToData.get(id);
   if (resourceData != null) {
     TextPoint originalPoint = new TextPoint(line, column);
     SourcePosition resultPosition = resourceData.transform(originalPoint, direction);
     if (resultPosition != null) {
       return resultPosition;
     }
   }
   return new SourcePosition(id, line, column);
 }