public ContentNode parse(JSDocCharScanner scanner,TagDictionary<AbstractInlineTagDefinition> inlineTagsDictinary){
  ComposedContent description=DomFactory.eINSTANCE.createComposedContent();
  if (!scanner.hasNext()) {
    return null;
  }
  if (nextIsTagTitle(scanner)) {
    return null;
  }
  int start=scanner.nextOffset();
  int end=start;
  StringBuilder strb=new StringBuilder();
  while (scanner.hasNext()) {
    char c=scanner.peek();
    if (regionStart(c)) {
      ScannerState st=scanner.saveState();
      InlineTag tag=(InlineTag)parseRegion(scanner,inlineTagsDictinary);
      if (tag != null) {
        saveTextTokens(description,start,end,strb);
        strb=new StringBuilder();
        start=end;
        description.getContents().add(tag);
        continue;
      }
 else {
        scanner.restoreState(st);
        if (start == end) {
          assert false;
        }
      }
    }
    scanner.next();
    if (JSDocCharScanner.isNL(c)) {
      if (scanner.hasNext() && !nextIsTagTitle(scanner)) {
        end=scanner.offset();
      }
 else {
        break;
      }
    }
    strb.append(c);
    end=scanner.offset();
  }
  String pendingData=strb.toString();
  if (pendingData.isEmpty() == false) {
    saveTextTokens(description,start,end,strb);
  }
switch (description.getContents().size()) {
case 0:
    return null;
case 1:
  return description.getContents().get(0);
default :
return description;
}
}

public ContentNode parse ( JSDocCharScanner scanner , TagDictionary < AbstractInlineTagDefinition > inlineTagsDictinary ) { ComposedContent description = DomFactory . eINSTANCE . createComposedContent ( ) ; if ( ! scanner . hasNext ( ) ) { return null ; } if ( nextIsTagTitle ( scanner ) ) { return null ; } int start = scanner . nextOffset ( ) ; int end = start ; StringBuilder strb = new StringBuilder ( ) ; while ( scanner . hasNext ( ) ) { char c = scanner . peek ( ) ; if ( regionStart ( c ) ) { ScannerState st = scanner . saveState ( ) ; InlineTag tag = ( InlineTag ) parseRegion ( scanner , inlineTagsDictinary ) ; if ( tag != null ) { saveTextTokens ( description , start , end , strb ) ; strb = new StringBuilder ( ) ; start = end ; description . getContents ( ) . add ( tag ) ; continue ; } else { scanner . restoreState ( st ) ; if ( start == end ) { assert false ; } } } scanner . next ( ) ; if ( JSDocCharScanner . isNL ( c ) ) { if ( scanner . hasNext ( ) && ! nextIsTagTitle ( scanner ) ) { end = scanner . offset ( ) ; } else { break ; } } strb . append ( c ) ; end = scanner . offset ( ) ; } String pendingData = strb . toString ( ) ; if ( pendingData . isEmpty ( ) == false ) { saveTextTokens ( description , start , end , strb ) ; } switch ( description . getContents ( ) . size ( ) ) { case 0 : return null ; case 1 : return description . getContents ( ) . get ( 0 ) ; default : return description ; } }
returns text if descriptions contains only text . if it contains any inline tags , than returned composedcontent will contain multiple nodes , one for each inline tag and one for each text before / after / in between inline tags . order of data is preserved . stops scanning for text when reaches end of comment or linetag . inlinetags are identified based on dictionary provided with method call .
