/*******************************************************************************
 * Copyright (c) 2022 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.text.javadoc;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTextElement;
import org.eclipse.jdt.core.dom.JavaDocRegion;
import org.eclipse.jdt.core.dom.MemberRef;
import org.eclipse.jdt.core.dom.MethodRef;
import org.eclipse.jdt.core.dom.MethodRefParameter;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TagProperty;

import org.eclipse.jdt.internal.corext.dom.ASTNodes;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks;

public class JavaDocSnippetStringEvaluator {

	/**
	 * Either an IMember or an IPackageFragment.
	 */
	private final IJavaElement fElement;

	public enum ReplacementStringIntervalStatus {
		/**
		 * replacement interval occurs before the given ActionElement interval
		 */
		BEFORE,
		/**
		 * replacement interval occurs after the given ActionElement interval
		 */
		AFTER,
		/**
		 * replacement interval occurs within the given ActionElement interval
		 */
		WITHIN,
		/**
		 * replacement interval contains the given ActionElement interval
		 */
		ENCOMPASS,
		/**
		 * replacement interval starts before the given ActionElement interval and ends within the ActionElement interval
		 */
		PREV_OVERLAP,
		/**
		 * replacement interval starts within the given ActionElement interval and ends after the ActionElement interval
		 */
		POST_OVERLAP,
		/**
		 * Default Value, do nothing
		 */
		DEFAULT
	}

	public class ActionElement{
		public int start;
		public int end;
		public String startTag;
		public String endTag;

		public ActionElement(int start, int end, String startTag, String endTag) {
			this.start= start;
			this.end= end;
			this.startTag= startTag;
			this.endTag= endTag;
		}

		public ReplacementStringIntervalStatus getIntervalStatus(int replacementIntervalStart, int replacementIntervalEnd) {
			ReplacementStringIntervalStatus intervalStatus= ReplacementStringIntervalStatus.DEFAULT;
			int startDiff = replacementIntervalStart - this.start;
			int endDiff = replacementIntervalEnd - this.end;

			if (this.end <= replacementIntervalStart) {
				intervalStatus= ReplacementStringIntervalStatus.AFTER;
			} else if (this.start >= replacementIntervalEnd) {
				intervalStatus= ReplacementStringIntervalStatus.BEFORE;
			} else if (startDiff <= 0 && endDiff >= 0) {
				intervalStatus= ReplacementStringIntervalStatus.ENCOMPASS;
			} else if (startDiff > 0 && endDiff < 0) {
				intervalStatus= ReplacementStringIntervalStatus.WITHIN;
			} else if (startDiff > 0) {
				intervalStatus= ReplacementStringIntervalStatus.POST_OVERLAP;
			} else if (endDiff < 0) {
				intervalStatus= ReplacementStringIntervalStatus.PREV_OVERLAP;
			}

			return intervalStatus;
		}

	}

	public class StringItem{
		public int index;
		public String tag;
		public StringItem(int index, String tag) {
			this.index= index;
			this.tag= tag;
		}
	}

	public JavaDocSnippetStringEvaluator(IJavaElement element) {
		this.fElement= element;
	}

	public void AddTagElementString(TagElement snippetTag, StringBuffer buffer) {
		if (snippetTag != null) {
			List<Object> fragments = snippetTag.fragments();
			for( Object fragment : fragments) {
				String str= ""; //$NON-NLS-1$
				if (fragment instanceof AbstractTextElement) {
					AbstractTextElement textElement= (AbstractTextElement) fragment;
					List<TagElement> tagElements= getTagElementsForTextElement(snippetTag, textElement);
					str = getModifiedString(textElement, tagElements);
				} else if (fragment instanceof JavaDocRegion) {
					JavaDocRegion region = (JavaDocRegion) fragment;
					if (region.isDummyRegion()) {
						List<TagElement> tagElements= getTagElementsForDummyJavaDocRegion(snippetTag, region);
						str = getModifiedString(region, tagElements);
					}
				} else if (fragment instanceof TagElement) {
					TagElement tagElement= (TagElement) fragment;
					List<TagElement> tagElements= getTagElementsForTagElement(snippetTag, tagElement);
					str = getModifiedString(tagElement, tagElements);
				}
				buffer.append(str);
			}
		}
	}

	private String getModifiedString(AbstractTextElement textElement, List<TagElement> tags) {
		return getModifiedString(textElement.getText(), tags);
	}

	private String getModifiedString(TagElement tagElement, List<TagElement> tags) {
		return getModifiedString(((AbstractTextElement)tagElement.fragments().get(0)).getText(), tags);
	}

	private String getModifiedString(JavaDocRegion region, List<TagElement> tags) {
		return getModifiedString(((AbstractTextElement)region.fragments().get(0)).getText(), tags);
	}

	private String getModifiedString(String str, List<TagElement> tags) {
		List<ActionElement> actionElements= new ArrayList<>();
		String modifiedStr= str;
		for (TagElement tag : tags) {
			String name= tag.getTagName();
			if (TagElement.TAG_HIGHLIGHT.equals(name)) {
				handleSnippetHighlight(modifiedStr, tag, actionElements);
			} else if (TagElement.TAG_REPLACE.equals(name)) {
				modifiedStr= handleSnippetReplace(modifiedStr, tag, actionElements);
			} else if (TagElement.TAG_LINK.equals(name)) {
				handleSnippetLink(modifiedStr, tag, actionElements);
			}
		}
		return getString( modifiedStr, actionElements);
	}

	private String getString(String str, List<ActionElement> actionElements) {
		String modifiedStr = str;
		List<StringItem> items= new ArrayList<>();
		for (ActionElement actElem : actionElements) {
			StringItem startItem = new StringItem(actElem.start, actElem.startTag);
			StringItem endItem = new StringItem(actElem.end, actElem.endTag);
			ListIterator<StringItem> iterator = items.listIterator();
			boolean endIndexAdded = false;
			boolean startIndexAdded = false;
			while (iterator.hasNext()) {
				StringItem elem= iterator.next();
				if (!endIndexAdded && elem.index < endItem.index) {
					iterator.previous();
					iterator.add(endItem);
					endIndexAdded = true;
					iterator.next();
				}
				if (!startIndexAdded && elem.index < startItem.index) {
					iterator.previous();
					iterator.add(startItem);
					startIndexAdded = true;
					iterator.next();
				}
				if (startIndexAdded && endIndexAdded) {
					break;
				}
			}
			if (!endIndexAdded) {
				items.add(endItem);
			}
			if (!startIndexAdded) {
				items.add(startItem);
			}
		}
		for (StringItem item : items) {
			modifiedStr = modifiedStr.substring(0, item.index) + item.tag + modifiedStr.substring(item.index);
		}
		return modifiedStr;
	}

	private void modifyPrevActionItemsReplacement(int replacementIntervalStart, int relacementIntervalEnd, int replacementStrNewLength, List<ActionElement> actionElements) {
		ListIterator<ActionElement> iterator = actionElements.listIterator();
		int oldLength = relacementIntervalEnd - replacementIntervalStart;
		int diff = replacementStrNewLength - oldLength;
		while (iterator.hasNext()) {
			ActionElement elem= iterator.next();
			ReplacementStringIntervalStatus intervalStatus= elem.getIntervalStatus(replacementIntervalStart, relacementIntervalEnd);
			switch(intervalStatus) {
				case AFTER:
					//do nothing., nothing needs to be done here
					break;
				case BEFORE:
					if (diff != 0) {
						elem.start+= diff;
						elem.end+= diff;
					}
					break;
				case ENCOMPASS:
					iterator.remove();
					break;
				case POST_OVERLAP:
					elem.end= replacementIntervalStart;
					break;
				case PREV_OVERLAP:
					elem.end += diff;
					elem.start = relacementIntervalEnd + diff;
					break;
				case WITHIN:
					// modify the old ActionElement to end before the replacement string start
					// Create a new Element element to start from the replacement string end
					int newEnd = elem.end + diff;
					elem.end= replacementIntervalStart;
					int newStart = relacementIntervalEnd + diff;
					ActionElement newElem= new  ActionElement(newStart, newEnd, elem.startTag, elem.endTag);
					iterator.add(newElem);
					break;
				case DEFAULT:
				default:
					break;
			}
		}
	}

	private List<TagElement> getTagElementsForTextElement(TagElement snippetTag, AbstractTextElement textElement) {
		List<TagElement> tagElements= new ArrayList<>();
		List<JavaDocRegion> regions= snippetTag.tagRegionsStartingAtTextElement(textElement);
		List<JavaDocRegion> masterList= snippetTag.tagRegionsContainingTextElement(textElement);
		masterList.removeAll(regions);
		for (JavaDocRegion region : masterList) {
			for (Object tagObj : region.tags()) {
				tagElements.add((TagElement) tagObj);
			}
		}
		for (JavaDocRegion region : regions) {
			for (Object tagObj : region.tags()) {
				if (tagObj instanceof TagElement) {
					TagElement tagElem= (TagElement) tagObj;
					Object prop= tagElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
					if (prop instanceof Integer) {
						int val = ((Integer)prop).intValue();
						ListIterator<TagElement> listIterator= tagElements.listIterator();
						TagElement addBefore= null;
						while (listIterator.hasNext()) {
				           TagElement tElem=  listIterator.next();
				           Object prop2= tElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
				           if (prop2 instanceof Integer) {
				        	   int val2 = ((Integer)prop2).intValue();
				        	   if (val2 > val) {
				        		   addBefore= tElem;
				        		   break;
				        	   }
				           }
				        }
						if (addBefore == null) {
							tagElements.add(tagElem);
						} else {
							tagElements.add(tagElements.indexOf(addBefore), tagElem);
						}
					}
				}
			}
		}
		return tagElements;
	}

	private List<TagElement> getTagElementsForDummyJavaDocRegion(TagElement snippetTag, JavaDocRegion javaDocRegion) {
		List<TagElement> tagElements= new ArrayList<>();
		AbstractTextElement textElement= (AbstractTextElement) javaDocRegion.fragments().get(0);
		List<JavaDocRegion> regions= snippetTag.tagRegionsStartingAtTextElement(textElement);
		List<JavaDocRegion> masterList= snippetTag.tagRegionsContainingTextElement(textElement);
		masterList.removeAll(regions);
		for (JavaDocRegion region : masterList) {
			for (Object tagObj : region.tags()) {
				tagElements.add((TagElement) tagObj);
			}
		}
		regions.add(javaDocRegion);
		for (JavaDocRegion region : regions) {
			for (Object tagObj : region.tags()) {
				if (tagObj instanceof TagElement) {
					TagElement tagElem= (TagElement) tagObj;
					Object prop= tagElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
					if (prop instanceof Integer) {
						int val = ((Integer)prop).intValue();
						ListIterator<TagElement> listIterator= tagElements.listIterator();
						TagElement addBefore= null;
						while (listIterator.hasNext()) {
				           TagElement tElem=  listIterator.next();
				           Object prop2= tElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
				           if (prop2 instanceof Integer) {
				        	   int val2 = ((Integer)prop2).intValue();
				        	   if (val2 > val) {
				        		   addBefore= tElem;
				        		   break;
				        	   }
				           }
				        }
						if (addBefore == null) {
							tagElements.add(tagElem);
						} else {
							tagElements.add(tagElements.indexOf(addBefore), tagElem);
						}
					}
				}
			}
		}

		return tagElements;
	}

	private List<TagElement> getTagElementsForTagElement(TagElement snippetTag, TagElement tag) {
		List<TagElement> tagElements= new ArrayList<>();
		AbstractTextElement textElement= (AbstractTextElement) tag.fragments().get(0);
		List<JavaDocRegion> regions= snippetTag.tagRegionsStartingAtTextElement(textElement);
		List<JavaDocRegion> masterList= snippetTag.tagRegionsContainingTextElement(textElement);
		masterList.removeAll(regions);
		for (JavaDocRegion region : masterList) {
			for (Object tagObj : region.tags()) {
				tagElements.add((TagElement) tagObj);
			}
		}
		for (JavaDocRegion region : regions) {
			for (Object tagObj : region.tags()) {
				if (tagObj instanceof TagElement) {
					TagElement tagElem= (TagElement) tagObj;
					Object prop= tagElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
					if (prop instanceof Integer) {
						int val = ((Integer)prop).intValue();
						ListIterator<TagElement> listIterator= tagElements.listIterator();
						TagElement addBefore= null;
						while (listIterator.hasNext()) {
				           TagElement tElem=  listIterator.next();
				           Object prop2= tElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
				           if (prop2 instanceof Integer) {
				        	   int val2 = ((Integer)prop).intValue();
				        	   if (val2 > val) {
				        		   addBefore= tElem;
				        		   break;
				        	   }
				           }
				        }
						if (addBefore == null) {
							tagElements.add(tagElem);
						} else {
							tagElements.add(tagElements.indexOf(addBefore), tagElem);
						}
					}
				}
			}
		}
		Object prop3= tag.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
		if (prop3 instanceof Integer) {
			int val = ((Integer)prop3).intValue();
			ListIterator<TagElement> listIterator= tagElements.listIterator();
			TagElement addBefore= null;
			while (listIterator.hasNext()) {
		          TagElement tElem=  listIterator.next();
		          Object prop2= tElem.getProperty(TagProperty.TAG_PROPERTY_SNIPPET_INLINE_TAG_COUNT);
		          if (prop2 instanceof Integer) {
		       	   int val2 = ((Integer)prop2).intValue();
		       	   if (val2 > val) {
		       		   addBefore= tElem;
		       		   break;
		       	   }
		          }
		       }
			if (addBefore == null) {
				tagElements.add(tag);
			} else {
				tagElements.add(tagElements.indexOf(addBefore), tag);
			}
		}
		return tagElements;
	}

	private void handleSnippetHighlight(String text, TagElement tagElement, List<ActionElement> actionElements) {
		try {
			List<? extends TagProperty> tagProperties= tagElement.tagProperties();
			String defHighlight= getHighlightHtmlTag(tagProperties);
			String startDefHighlight = '<' + defHighlight + '>';
			String endDefHighlight = "</" + defHighlight + '>'; //$NON-NLS-1$
			String regExValue = getPropertyValue("regex", tagProperties); //$NON-NLS-1$
			String subStringValue = getPropertyValue("substring", tagProperties); //$NON-NLS-1$
			Pattern regexPattern = null;
			if (regExValue != null) {
				regexPattern = Pattern.compile(regExValue);
			}
			if (regexPattern != null) {
				Matcher matcher = regexPattern.matcher(text);
				while (matcher.find()) {
					actionElements.add(new ActionElement(matcher.start(), matcher.end(), startDefHighlight, endDefHighlight));
				}
			} else if (subStringValue != null) {
				int startIndex = 0;
				while ((startIndex = text.indexOf(subStringValue, startIndex)) != -1) {
					actionElements.add(new ActionElement(startIndex, startIndex + subStringValue.length(), startDefHighlight, endDefHighlight));
					startIndex += subStringValue.length();
				}
			} else {
				actionElements.add(new ActionElement(0, text.length(), startDefHighlight, endDefHighlight));
			}
			return;
		} catch (PatternSyntaxException e) {
			// do nothing
		}
		return;
	}

	private String handleSnippetReplace(String text, TagElement tagElement, List<ActionElement> actionElements) {
		try {
			List<? extends TagProperty> tagProperties= tagElement.tagProperties();
			String regExValue = getPropertyValue("regex", tagProperties); //$NON-NLS-1$
			String subStringValue = getPropertyValue("substring", tagProperties); //$NON-NLS-1$
			String substitution = getPropertyValue("replacement", tagProperties); //$NON-NLS-1$
			Pattern regexPattern = null;
			if (regExValue != null) {
				regexPattern = Pattern.compile(regExValue);
			}
			String modifiedText = text;
			if (regexPattern != null) {
				Matcher matcher = regexPattern.matcher(modifiedText);
				StringBuilder strBuild= new StringBuilder();
				int finalMatchIndex = 0;
				while (matcher.find()) {
					finalMatchIndex = matcher.end();
					modifyPrevActionItemsReplacement(matcher.start(), matcher.end(), substitution.length(), actionElements);
					matcher.appendReplacement(strBuild, substitution);
				}
				modifiedText = strBuild.toString() + modifiedText.substring(finalMatchIndex);
			} else if (subStringValue != null) {
				int startIndex = 0;
				while ((startIndex = modifiedText.indexOf(subStringValue, startIndex)) != -1) {
					modifyPrevActionItemsReplacement(startIndex, startIndex+ subStringValue.length(), substitution.length(), actionElements);
					modifiedText = modifiedText.substring(0, startIndex) + substitution + modifiedText.substring(startIndex + subStringValue.length());
					startIndex += substitution.length() ;
				}
			} else {
				actionElements.clear();
				modifiedText = substitution;
			}
			return modifiedText;
		} catch (PatternSyntaxException e) {
			// do nothing
		}
		return text;
	}


	private void handleSnippetLink(String text, TagElement tagElement, List<ActionElement> actionElements) {
		try {
			List<? extends TagProperty> tagProperties= tagElement.tagProperties();
			String regExValue = getPropertyValue("regex", tagProperties); //$NON-NLS-1$
			String subStringValue = getPropertyValue("substring", tagProperties); //$NON-NLS-1$
			String additionalStartTag= getLinkHtmlTag(tagProperties);
			String additionalEndTag= ""; //$NON-NLS-1$
			if (additionalStartTag.length() > 0) {
				additionalEndTag= "</" + additionalStartTag + '>'; //$NON-NLS-1$
				additionalStartTag= '<' + additionalStartTag + '>';
			}
			ASTNode target = getPropertyNodeValue("target", tagProperties); //$NON-NLS-1$
			String linkRefTxt = getLinkRef(target);
			String startDefLink = linkRefTxt + additionalStartTag;
			String endDefLink = additionalEndTag+"</a>"; //$NON-NLS-1$
			Pattern regexPattern = null;
			if (regExValue != null) {
				regexPattern = Pattern.compile(regExValue);
			}
			String modifiedText = text;
			if (regexPattern != null) {
				Matcher matcher = regexPattern.matcher(modifiedText);
				while (matcher.find()) {
					actionElements.add(new ActionElement(matcher.start(), matcher.end(), startDefLink, endDefLink));
				}
			} else if (subStringValue != null) {
				int startIndex = 0;
				while ((startIndex = modifiedText.indexOf(subStringValue, startIndex)) != -1) {
					actionElements.add(new ActionElement(startIndex, startIndex+ subStringValue.length(), startDefLink, endDefLink));
					startIndex = startIndex+ subStringValue.length() ;
				}
			} else {
				String subText = modifiedText.trim();
				if (subText.length() < text.length()) {
					int startIndex = text.indexOf(subText);
					actionElements.add(new ActionElement(startIndex, startIndex + subText.length(), startDefLink, endDefLink));
				}
			}
			return;
		} catch (PatternSyntaxException e) {
			// do nothing
		}
		return;
	}

	private String getLinkRef(ASTNode node) {
		String str= ""; //$NON-NLS-1$
		String refTypeName= null;
		String refMemberName= null;
		String[] refMethodParamTypes= null;
		String[] refMethodParamNames= null;
		if (node instanceof Name) {
			Name name = (Name) node;
			refTypeName= name.getFullyQualifiedName();
		} else if (node instanceof MemberRef) {
			MemberRef memberRef= (MemberRef) node;
			Name qualifier= memberRef.getQualifier();
			refTypeName= qualifier == null ? "" : qualifier.getFullyQualifiedName(); //$NON-NLS-1$
			refMemberName= memberRef.getName().getIdentifier();
		} else if (node instanceof MethodRef) {
			MethodRef methodRef= (MethodRef) node;
			Name qualifier= methodRef.getQualifier();
			refTypeName= qualifier == null ? "" : qualifier.getFullyQualifiedName(); //$NON-NLS-1$
			refMemberName= methodRef.getName().getIdentifier();
			List<MethodRefParameter> params= methodRef.parameters();
			int ps= params.size();
			refMethodParamTypes= new String[ps];
			refMethodParamNames= new String[ps];
			for (int i= 0; i < ps; i++) {
				MethodRefParameter param= params.get(i);
				refMethodParamTypes[i]= ASTNodes.asString(param.getType());
				SimpleName paramName= param.getName();
				if (paramName != null)
					refMethodParamNames[i]= paramName.getIdentifier();
			}
		}

		if (refTypeName != null) {
			str +="<a href='"; //$NON-NLS-1$
			try {
				String scheme= JavaElementLinks.JAVADOC_SCHEME;
				String uri= JavaElementLinks.createURI(scheme, fElement, refTypeName, refMemberName, refMethodParamTypes);
				str += uri;
			} catch (URISyntaxException e) {
				JavaPlugin.log(e);
			}
			str += "'>"; //$NON-NLS-1$
		}
		return str;
	}

	private String getLinkHtmlTag(List<? extends ASTNode> tagProperties) {
		String defaultTag= "code"; //$NON-NLS-1$
		if (tagProperties != null) {
			for (ASTNode node : tagProperties) {
				if (node instanceof TagProperty) {
					TagProperty tagProp = (TagProperty) node;
					if ("type".equals(tagProp.getName())) { //$NON-NLS-1$
						String tagValue = tagProp.getStringValue();
						switch (tagValue) {
							case "linkplain" :  //$NON-NLS-1$
								defaultTag= ""; //$NON-NLS-1$
								break;
							default:
								break;
						}
						break;
					}
				}
			}
		}
		return defaultTag;
	}

	private String getPropertyValue(String property, List<? extends ASTNode> tagProperties) {
		String defaultTag= null;
		if (tagProperties != null && property!= null) {
			for (ASTNode node : tagProperties) {
				if (node instanceof TagProperty) {
					TagProperty tagProp = (TagProperty) node;
					if (property.equals(tagProp.getName())) {
						defaultTag= tagProp.getStringValue();
						break;
					}
				}
			}
		}
		return defaultTag;
	}
	private ASTNode getPropertyNodeValue(String property, List<? extends ASTNode> tagProperties) {
		ASTNode defaultTag= null;
		if (tagProperties != null && property!= null) {
			for (ASTNode node : tagProperties) {
				if (node instanceof TagProperty) {
					TagProperty tagProp = (TagProperty) node;
					if (property.equals(tagProp.getName())) {
						defaultTag= tagProp.getNodeValue();
						break;
					}
				}
			}
		}
		return defaultTag;
	}

	private String getHighlightHtmlTag(List<? extends ASTNode> tagProperties) {
		String defaultTag= "b"; //$NON-NLS-1$
		if (tagProperties != null) {
			for (ASTNode node : tagProperties) {
				if (node instanceof TagProperty) {
					TagProperty tagProp = (TagProperty) node;
					if ("type".equals(tagProp.getName())) { //$NON-NLS-1$
						String tagValue = tagProp.getStringValue();
						switch (tagValue) {
							case "bold" :  //$NON-NLS-1$
								defaultTag= "b"; //$NON-NLS-1$
								break;
							case "italic" :  //$NON-NLS-1$
								defaultTag= "i"; //$NON-NLS-1$
								break;
							case "highlighted" :  //$NON-NLS-1$
								defaultTag= "mark"; //$NON-NLS-1$
								break;
							default :
								defaultTag= ""; //$NON-NLS-1$
								break;
						}
						break;
					}
				}
			}
		}
		return defaultTag;
	}

}
