/*******************************************************************************
 * Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.xtext.documentation.impl;

import java.util.List;

import org.eclipse.xtext.documentation.IJavaDocTypeReferenceProvider;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.util.ReplaceRegion;

import com.google.common.collect.Lists;

/**
 * @author Holger Schill - Initial contribution and API
 * @author Jan Koehnlein
 * @since 2.4
 */
public class MultiLineJavaDocTypeReferenceProvider implements IJavaDocTypeReferenceProvider {

	protected String lineDelimiter = System.getProperty("line.separator");

	public List<ReplaceRegion> computeTypeRefRegions(INode node) {
		List<ReplaceRegion> regions = Lists.newArrayList();
		Iterable<ILeafNode> leafNodes = node.getLeafNodes();
		computeRegions(regions, leafNodes, "@link ", "#", " ", "}");
		computeRegions(regions, leafNodes, "@see ", "#" , " ", lineDelimiter);
		return regions;
	}

	public List<ReplaceRegion> computeParameterTypeRefRegions(INode node) {
		List<ReplaceRegion> regions = Lists.newArrayList();
		Iterable<ILeafNode> leafNodes = node.getLeafNodes();
		computeRegions(regions, leafNodes, "@param ", " ", "-", lineDelimiter);
		return regions;
	}

	/**
	 * Computes regions between a given string to seach and different ends searched by their precedence
	 *
	 * @param regions - List to put new regions in
	 * @param leafNodes - nodes to search in
	 * @param toSearch - String to search
	 * @param end - end with highest precedence
	 * @param optionalEnd - end with lower precedence
	 * @param optionalEnd2 - end with lowest precedence
	 */
	protected void computeRegions(List<ReplaceRegion> regions, Iterable<ILeafNode> leafNodes, String toSearch, String end, String optionalEnd, String optionalEnd2) {
		for (ILeafNode leafNode : leafNodes) {
			String text = leafNode.getText();
			int offset = leafNode.getOffset();
			int position = text.indexOf(toSearch);
			while (position != -1) {
				int beginIndex = position + toSearch.length();
				int endLink = -1;
				if(end != null && endLink == -1)
					endLink = text.indexOf(end, beginIndex);
				if(optionalEnd != null && endLink == -1)
					endLink = text.indexOf(optionalEnd, beginIndex);
				if(optionalEnd2 != null){
					int lastEndLink = text.indexOf(optionalEnd2, beginIndex);
					if(endLink != -1){
						if(endLink > lastEndLink)
							endLink = lastEndLink;
					} else {
						endLink = lastEndLink;
					}
				}
				if (endLink == -1) { 
					break;
				} else {
					String simpleName = text.substring(beginIndex, endLink).trim();
					ReplaceRegion region = new ReplaceRegion(offset + beginIndex, simpleName.length(), simpleName);
					regions.add(region);
				} 
				position = text.indexOf(toSearch, endLink);
			}
		}
	}
}

@@ -2600,32 +2600,33 @@
  endLink == -1)%0A
+%0A
 %09%09%09%09%09endLink = t
@@ -2752,24 +2752,54 @@
 eginIndex);%0A
+%09%09%09%09%09if(lastEndLink != -1) %7B%0A%09
 %09%09%09%09%09if(endL
@@ -2810,16 +2810,17 @@
 != -1)%7B%0A
+%09
 %09%09%09%09%09%09if
@@ -2843,16 +2843,17 @@
 ndLink)%0A
+%09
 %09%09%09%09%09%09%09e
@@ -2875,24 +2875,25 @@
 dLink;%0A%09%09%09%09%09
+%09
 %7D else %7B%0A%09%09%09
@@ -2885,24 +2885,25 @@
 %09%09%09%7D else %7B%0A
+%09
 %09%09%09%09%09%09endLin
@@ -2915,24 +2915,32 @@
 astEndLink;%0A
+%09%09%09%09%09%09%7D%0A
 %09%09%09%09%09%7D%0A%09%09%09%09%7D

Fix false positive when there is no linebreak