private static boolean isContainedBy(DartNode node, DartNode containedByNode) {
   SourceInfo nodeSource = node.getSourceInfo();
   SourceInfo containedBySource = containedByNode.getSourceInfo();
   int nodeEnd = nodeSource.getOffset() + nodeSource.getLength();
   int containedByEnd = containedBySource.getOffset() + containedBySource.getLength();
   return nodeSource.getOffset() >= containedBySource.getOffset() && nodeEnd <= containedByEnd;
 }
 private final void processNode(SemanticToken token, DartNode node) {
   token.update(node);
   token.attachSource(fSourceViewer.getDocument());
   // sometimes node has wrong source range; log problem
   if (token.getSource() == null) {
     IDocument document = fSourceViewer.getDocument();
     if (node != null && document != null) {
       SourceInfo sourceInfo = node.getSourceInfo();
       if (sourceInfo != null) {
         DartToolsPlugin.log(
             "Bad node: "
                 + node.getClass().getName()
                 + " offset:"
                 + sourceInfo.getOffset()
                 + " len:"
                 + sourceInfo.getLength()
                 + " in document: "
                 + document.getLength());
       }
     }
     return;
   }
   // try SemanticHighlighting instances
   for (int i = 0, n = fJobSemanticHighlightings.length; i < n; i++) {
     if (fJobHighlightings[i].isEnabled()) {
       SemanticHighlighting semanticHighlighting = fJobSemanticHighlightings[i];
       // try multiple positions
       {
         List<SourceRange> ranges = semanticHighlighting.consumesMulti(token);
         if (ranges != null) {
           for (SourceRange range : ranges) {
             int offset = range.getOffset();
             int length = range.getLength();
             if (offset > -1 && length > 0) {
               fCollector.addPosition(offset, length, fJobHighlightings[i]);
             }
           }
           break;
         }
       }
       // try single position
       boolean consumes;
       if (node instanceof DartIdentifier) {
         consumes = semanticHighlighting.consumesIdentifier(token);
       } else {
         consumes = semanticHighlighting.consumes(token);
       }
       if (consumes) {
         int offset = node.getSourceInfo().getOffset();
         int length = node.getSourceInfo().getLength();
         if (offset > -1 && length > 0) {
           fCollector.addPosition(offset, length, fJobHighlightings[i]);
         }
         break;
       }
     }
   }
   token.clear();
 }