private void processElements(
      Attribute attribute,
      CssElementType elementType,
      Map<String, Collection<FileObject>> elements2files) {
    CharSequence value = attribute.unquotedValue();
    if (value == null) {
      return;
    }

    if (value.length() == 0) {
      return; // ignore empty value
    }

    // all files containing the id declaration
    Collection<FileObject> filesWithTheId = elements2files.get(value.toString());

    // all referred files with the id declaration
    Collection<FileObject> referredFilesWithTheId = new LinkedList<FileObject>();
    if (filesWithTheId != null) {
      referredFilesWithTheId.addAll(filesWithTheId);
      referredFilesWithTheId.retainAll(referredFiles);
    }

    if (referredFilesWithTheId.isEmpty()) {
      // unknown id
      hints.add(
          new MissingCssElement(
              rule, context, getAttributeValueOffsetRange(attribute, context), filesWithTheId));
    }
  }
 private static OffsetRange getAttributeValueOffsetRange(Attribute attr, HtmlRuleContext context) {
   boolean quoted = attr.isValueQuoted();
   int from = attr.valueOffset() + (quoted ? 1 : 0);
   int to = from + attr.unquotedValue().length();
   return EmbeddingUtil.convertToDocumentOffsets(from, to, context.getSnapshot());
 }