/** Loads the buffer via SourceMapper, and maps it in SourceMapper */
  private IBuffer mapSource(SourceMapper mapper, IBinaryType info, IClassFile bufferOwner) {
    char[] contents = mapper.findSource(getType(), info);
    if (contents != null) {
      // create buffer
      IBuffer buffer = BufferManager.createBuffer(bufferOwner);
      if (buffer == null) return null;
      BufferManager bufManager = getBufferManager();
      bufManager.addBuffer(buffer);

      // set the buffer source
      if (buffer.getCharacters() == null) {
        buffer.setContents(contents);
      }

      // listen to buffer changes
      buffer.addBufferChangedListener(this);

      // do the source mapping
      mapper.mapSource(getOuterMostEnclosingType(), contents, info);

      return buffer;
    } else {
      // create buffer
      IBuffer buffer = BufferManager.createNullBuffer(bufferOwner);
      if (buffer == null) return null;
      BufferManager bufManager = getBufferManager();
      bufManager.addBuffer(buffer);

      // listen to buffer changes
      buffer.addBufferChangedListener(this);
      return buffer;
    }
  }
  public IJavaElement getElementAtConsideringSibling(int position) throws JavaModelException {
    IPackageFragment fragment = (IPackageFragment) getParent();
    PackageFragmentRoot root =
        (PackageFragmentRoot) fragment.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
    SourceMapper mapper = root.getSourceMapper();
    if (mapper == null) {
      return null;
    } else {
      int index = this.name.indexOf('$');
      int prefixLength = index < 0 ? this.name.length() : index;

      IType type = null;
      int start = -1;
      int end = Integer.MAX_VALUE;
      IJavaElement[] children = fragment.getChildren();
      for (int i = 0; i < children.length; i++) {
        String childName = children[i].getElementName();

        int childIndex = childName.indexOf('$');
        int childPrefixLength = childIndex < 0 ? childName.indexOf('.') : childIndex;
        if (prefixLength == childPrefixLength
            && this.name.regionMatches(0, childName, 0, prefixLength)) {
          IClassFile classFile = (IClassFile) children[i];

          // ensure this class file's buffer is open so that source ranges are computed
          classFile.getBuffer();

          SourceRange range = mapper.getSourceRange(classFile.getType());
          if (range == SourceMapper.UNKNOWN_RANGE) continue;
          int newStart = range.getOffset();
          int newEnd = newStart + range.getLength() - 1;
          if (newStart > start && newEnd < end && newStart <= position && newEnd >= position) {
            type = classFile.getType();
            start = newStart;
            end = newEnd;
          }
        }
      }
      if (type != null) {
        return findElement(type, position, mapper);
      }
      return null;
    }
  }
 /**
  * Finds the deepest <code>IJavaElement</code> in the hierarchy of
  * <code>elt</elt>'s children (including <code>elt</code> itself)
  * which has a source range that encloses <code>position</code>
  * according to <code>mapper</code>.
  */
 protected IJavaElement findElement(IJavaElement elt, int position, SourceMapper mapper) {
   SourceRange range = mapper.getSourceRange(elt);
   if (range == null
       || position < range.getOffset()
       || range.getOffset() + range.getLength() - 1 < position) {
     return null;
   }
   if (elt instanceof IParent) {
     try {
       IJavaElement[] children = ((IParent) elt).getChildren();
       for (int i = 0; i < children.length; i++) {
         IJavaElement match = findElement(children[i], position, mapper);
         if (match != null) {
           return match;
         }
       }
     } catch (JavaModelException npe) {
       // elt doesn't exist: return the element
     }
   }
   return elt;
 }