/*=============================================================================#
 # Copyright (c) 2010, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rhelp.core.update;

import static org.eclipse.statet.internal.rhelp.core.RHelpCoreInternals.DEBUG;
import static org.eclipse.statet.internal.rhelp.core.index.RHelpHtmlUtils.HR_LINE_PATTERN;
import static org.eclipse.statet.internal.rhelp.core.index.RHelpHtmlUtils.HR_PREFIX;
import static org.eclipse.statet.rhelp.core.RHelpCore.BUNDLE_ID;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.InfoStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.WarningStatus;

import org.eclipse.statet.internal.rhelp.core.RHelpWebapp;
import org.eclipse.statet.internal.rhelp.core.index.AbortIndexOperationException;
import org.eclipse.statet.internal.rhelp.core.index.RDocResource;
import org.eclipse.statet.internal.rhelp.core.index.REnvIndexWriter;
import org.eclipse.statet.internal.rhelp.core.index.REnvIndexWriter.RdItem;
import org.eclipse.statet.rhelp.core.REnvHelpConfiguration;
import org.eclipse.statet.rhelp.core.RHelpManager;
import org.eclipse.statet.rj.data.RCharacterStore;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RList;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;
import org.eclipse.statet.rj.data.RVector;
import org.eclipse.statet.rj.renv.core.BasicRPkgDescription;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RNumVersion;
import org.eclipse.statet.rj.renv.core.RPkgBuilt;
import org.eclipse.statet.rj.renv.core.RPkgCompilation;
import org.eclipse.statet.rj.renv.core.RPkgDescription;
import org.eclipse.statet.rj.renv.runtime.RLibLocationInfo;
import org.eclipse.statet.rj.renv.runtime.RPkgManager;
import org.eclipse.statet.rj.renv.runtime.RPkgManagerDataset;
import org.eclipse.statet.rj.renv.runtime.RuntimeRLibPaths;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RService;


/**
 * Updates the R environment (R help keywords, R help index).
 * Uses the RService interface to read the data.
 */
@NonNullByDefault
public abstract class REnvIndexUpdater {
	
	
	private static final String PKG_DESCR_FNAME= "rj:::rhelp.loadPkgDescr"; //$NON-NLS-1$
	private static final int PKG_DESCR_LENGTH= 7;
	private static final int PKG_DESCR_IDX_VERSION= 0;
	private static final int PKG_DESCR_IDX_TITLE= 1;
	private static final int PKG_DESCR_IDX_DESCRIPTION= 2;
	private static final int PKG_DESCR_IDX_AUTHOR= 3;
	private static final int PKG_DESCR_IDX_MAINTAINER= 4;
	private static final int PKG_DESCR_IDX_URL= 5;
	private static final int PKG_DESCR_IDX_BUILT= 6;
	
	private static final String PKG_RD_FNAME= "rj:::rhelp.loadPkgRd"; //$NON-NLS-1$
	
	
	private static String checkNA2Null(final String s) {
		return (s != null && !s.equals("NA") && s.length() > 0) ? s : null; //$NON-NLS-1$
	}
	
	
	private static class PkgTask {
		
		
		final String name;
		final @Nullable RNumVersion version;
		final @Nullable String built;
		final RLibLocation libLocation;
		final RLibLocationInfo libLocationInfo; // for error messages
		
		RVector<RCharacterStore> rDescr;
		
		RList rRd;
		
		
		public PkgTask(final String name, final RNumVersion version, final String built,
				final RLibLocation libLocation, final RLibLocationInfo libLocationInfo) {
			this.name= name.intern();
			this.version= version;
			this.built= built;
			this.libLocation= libLocation;
			this.libLocationInfo= libLocationInfo;
		}
		
		@SuppressWarnings("null")
		private PkgTask(final String signal) {
			this.name= signal;
			this.version= null;
			this.built= null;
			this.libLocation= null;
			this.libLocationInfo= null;
		}
		
		
		@Override
		public String toString() {
			final StringBuilder sb= new StringBuilder(this.name);
			sb.append(" " + "(version= ").append((this.version != null) ? this.version : "<unknown>");
			sb.append(')');
			if (this.libLocationInfo != null) {
				sb.append(" in lib= '").append(this.libLocationInfo.getDirectoryRPath()).append('\'');
			}
			return sb.toString();
		}
		
	}
	
	private static final PkgTask STOP_OK= new PkgTask("STOP_OK");
	private static final PkgTask STOP_CANCEL= new PkgTask("STOP_CANCEL");
	
	
	protected abstract class IndexJob {
		
		
		private final BlockingQueue<PkgTask> queue= new ArrayBlockingQueue<>(4);
		
		private volatile @Nullable Exception exception;
		
		private int count;
		private int queueCumCount;
		
		
		public IndexJob() {
		}
		
		
		protected abstract void cancel();
		protected abstract void join();
		
		
		private void add(final PkgTask task, final ProgressMonitor m) throws Exception {
			while (true) {
				try {
					if (this.exception != null) {
						throw this.exception;
					}
					
					this.count++;
					this.queueCumCount+= this.queue.size();
					
					this.queue.put(task);
					break;
				}
				catch (final InterruptedException e) {
					if (m.isCanceled()) {
						cancel();
						throw new StatusException(Status.CANCEL_STATUS);
					}
				}
			}
		}
		
		private void finish(final ProgressMonitor m) throws StatusException {
			while (true) {
				try {
					this.queue.put(STOP_OK);
					break;
				}
				catch (final InterruptedException e) {}
			}
			join();
		}
		
		private void cancel(final ProgressMonitor m) {
			cancel();
			while (true) {
				try {
					this.queue.put(STOP_CANCEL);
					break;
				}
				catch (final InterruptedException e) {}
			}
			join();
		}
		
		public Status run(final ProgressMonitor monitor) {
			try {
				PkgTask task= null;
				while (true) {
					try {
						task= this.queue.take();
						if (task == STOP_OK) {
							if (DEBUG) {
								REnvIndexUpdater.this.index.log(new InfoStatus(BUNDLE_ID,
										String.format("Fill level of queue: mean= %1.2f.",
												(double) this.queueCumCount / this.count )));
							}
							return Status.OK_STATUS;
						}
						if (task == STOP_CANCEL) {
							return Status.CANCEL_STATUS;
						}
						
						final RPkgDescription pkgDescription= createDescription(task);
						REnvIndexUpdater.this.index.beginPackage(pkgDescription);
						processRdData(pkgDescription.getName(), task.rRd);
					}
					catch (final InterruptedException e) {
						// continue, monitor is checked
					}
					catch (final AbortIndexOperationException e) {
						this.exception= e;
						this.queue.clear();
						return Status.CANCEL_STATUS;
					}
					catch (final Exception e) {
						REnvIndexUpdater.this.index.log(new ErrorStatus(BUNDLE_ID,
								String.format("An error occurred when indexing data for package: %1$s",
										task ),
								e ));
					}
					finally {
						try {
							REnvIndexUpdater.this.index.endPackage();
						}
						catch (final Exception e) {
							this.exception= e;
							this.queue.clear();
							return Status.CANCEL_STATUS;
						}
					}
					
					if (monitor.isCanceled()) {
						return Status.CANCEL_STATUS;
					}
				}
			}
			catch (final Exception e) {
				this.exception= e;
				this.queue.clear();
				return Status.CANCEL_STATUS;
			}
		}
		
	}
	
	
	private final REnvHelpConfiguration rEnvConfig;
	
	private final StringBuilder tempBuilder1= new StringBuilder(65536);
	private final StringBuilder tempBuilder2= new StringBuilder(1024);
	
	private final REnvIndexWriter index;
	
	private final RPkgManager rPkgManager;
	
	
	public REnvIndexUpdater(final REnvHelpConfiguration rEnvConfig,
			final RHelpManager rHelpManager, final RPkgManager rPkgManager) {
		this.rEnvConfig= rEnvConfig;
		this.index= new REnvIndexWriter(rEnvConfig, rHelpManager);
		this.rPkgManager= rPkgManager;
	}
	
	
	protected RPkgManager getRPkgManager() {
		return this.rPkgManager;
	}
	
	
	public Status update(final RService r, final boolean reset,
			final @Nullable Map<String, String> rEnvSharedProperties,
			final ProgressMonitor m) {
		m.setWorkRemaining(1 + 8 + 1);
		try {
			this.index.beginBatch(reset);
			
			final String docDir= checkNA2Null(RDataUtils.checkSingleChar(
					r.evalData("R.home(\"doc\")", m) )); //$NON-NLS-1$
			this.index.setDocDir(docDir, (docDir != null) ? toLocalPath(docDir, r, m) : null);
			this.index.addManuals(RDocResource.R_MANUALS);
			this.index.addMiscResources(RDocResource.R_MISCS);
			
			this.index.setREnvSharedProperties(rEnvSharedProperties);
			
			long tKeywords= System.nanoTime();
			loadKeywords(r, m.newSubMonitor(1));
			tKeywords= System.nanoTime() - tKeywords;
			
			m.checkCanceled();
			
			long tPackages= System.nanoTime();
			loadPackages(r, m.newSubMonitor(8));
			tPackages= System.nanoTime() - tPackages;
			
			if (DEBUG) {
				this.index.log(new InfoStatus(BUNDLE_ID,
						String.format("Required time for update: keywords= %1$sms, packages= %2$sms.",
								tKeywords / 1_000_000, tPackages / 1_000_000 )));
			}
			
			final Status status= this.index.endBatch();
			if (status != null && status.getSeverity() >= Status.ERROR) {
				return new WarningStatus(BUNDLE_ID,
						"The R environment index could not be completely updated.",
						new StatusException(status) );
			}
			return new InfoStatus(BUNDLE_ID,
					"The R environment index was updated successfully." );
		}
		catch (final StatusException e) {
			if (e.getStatus().getSeverity() == Status.CANCEL) {
				this.index.cancel();
				return e.getStatus();
			}
			this.index.log(new ErrorStatus(BUNDLE_ID,
					"An error occurred when updating the R environment.",
					e ));
			final Status status= this.index.cancel();
			return new ErrorStatus(BUNDLE_ID,
					"The R environment could not be updated.",
					(status != null) ? new StatusException(status) : null );
		}
		catch (final Exception e) {
			this.index.log(new ErrorStatus(BUNDLE_ID,
					"An error occurred when updating the R environment.",
					e ));
			final Status status= this.index.cancel();
			return new ErrorStatus(BUNDLE_ID,
					"The R environment could not be updated.",
					(status != null) ? new StatusException(status) : null );
		}
	}
	
	private void loadKeywords(final RService r, final ProgressMonitor m) throws StatusException {
		final String docDir= this.index.getDocDir();
		if (docDir == null) {
			return;
		}
		m.beginTask("Loading R help keywords...", 10 + 10);
		Exception errorCause= null;
		try {
			final byte[] bytes= r.downloadFile(docDir + "/KEYWORDS.db", 0, m.newSubMonitor(10));
			final BufferedReader reader= new BufferedReader(new InputStreamReader(
					new ByteArrayInputStream(bytes), "UTF-8")); //$NON-NLS-1$
			String line;
			
			this.tempBuilder1.setLength(0);
			while ((line= reader.readLine()) != null) {
				if (DEBUG) {
					this.tempBuilder1.append(line);
					this.tempBuilder1.append('\n');
				}
				int idx= line.indexOf('#');
				if (idx >= 0) {
					line= line.substring(0, idx);
				}
				idx= line.indexOf(':');
				if (idx < 0) {
					continue;
				}
				final String descr= new String(line.substring(idx + 1).trim());
				line= line.substring(0, idx);
				this.index.addDefaultKeyword(line.split("\\|"), descr); //$NON-NLS-1$
			}
			m.addWorked(10);
			
			return;
		}
		catch (final StatusException e) {
			if (e.getStatus().getSeverity() == Status.CANCEL) {
				throw e;
			}
			errorCause= e;
		}
		catch (final Exception e) {
			errorCause= e;
		}
		finally {
			if (DEBUG) {
				this.tempBuilder1.insert(0, "Read KEYWORDS.db file:\n<FILE>\n");
				this.tempBuilder1.append("</FILE>\n");
				this.index.log(new InfoStatus(BUNDLE_ID, this.tempBuilder1.toString()));
			}
		}
		this.index.log(new ErrorStatus(BUNDLE_ID,
				"An error occurred when loading the keyword list.",
				errorCause ));
	}
	
	private void loadPackages(final RService r, final ProgressMonitor m) throws StatusException {
		m.beginTask("Loading R package help.", 8 + 1);
		Exception errorCause= null;
		IndexJob job= null;
		try {
			final RPkgManagerDataset rPkgDataset= this.rPkgManager.getDataset(RPkgManager.INSTALLED,
					r, m );
			
			job= scheduleIndexJob(
					String.format("Update R help index for '%1$s'", this.rEnvConfig.getName()));
			
			final RuntimeRLibPaths rLibPaths= (RuntimeRLibPaths) rPkgDataset.getRLibPaths();
			final RPkgCompilation<? extends RPkgBuilt> installed= rPkgDataset.getInstalled();
			
			final ProgressMonitor mPkgs= m.newSubMonitor(8);
			final List<String> names= installed.getNames();
			for (int i= 0; i < names.size(); i++) {
				mPkgs.setWorkRemaining(2 * (names.size() - i));
				
				final RPkgBuilt pkgInfo= installed.getFirst(names.get(i));
				
				if (this.index.checkPackage(pkgInfo.getName(),
						pkgInfo.getVersion(), pkgInfo.getBuilt(),
						pkgInfo.getLibLocation() )) {
					continue;
				}
				
				mPkgs.checkCanceled();
				
				mPkgs.beginSubTask(String.format("Loading data for package '%1$s'...", pkgInfo.getName()));
				
				try {
					final RLibLocationInfo libLocationInfo= rLibPaths.getInfo(pkgInfo.getLibLocation());
					if (libLocationInfo == null) {
						throw new StatusException(new ErrorStatus(BUNDLE_ID,
								String.format("Failed to resolve library location '%1$s'.",
										pkgInfo.getLibLocation() )));
					}
					final PkgTask task= new PkgTask(pkgInfo.getName(), pkgInfo.getVersion(), pkgInfo.getBuilt(),
							pkgInfo.getLibLocation(), libLocationInfo );
					{	final FunctionCall call= r.createFunctionCall(PKG_DESCR_FNAME);
						call.addChar("lib", libLocationInfo.getDirectoryRPath()); //$NON-NLS-1$
						call.addChar("name", pkgInfo.getName()); //$NON-NLS-1$
						task.rDescr= RDataUtils.checkRCharVector(call.evalData(mPkgs.newSubMonitor(1)));
					}
					{	final FunctionCall call= r.createFunctionCall(PKG_RD_FNAME);
						call.addChar("lib", libLocationInfo.getDirectoryRPath()); //$NON-NLS-1$
						call.addChar("name", pkgInfo.getName()); //$NON-NLS-1$
						task.rRd= RDataUtils.checkRList(call.evalData(mPkgs.newSubMonitor(1)));
					}
					job.add(task, mPkgs);
				}
				catch (final StatusException e) { // only core exceptions!
					if (e.getStatus().getSeverity() == Status.CANCEL) {
						throw e;
					}
					this.index.log(new ErrorStatus(BUNDLE_ID,
							String.format("An error occurred when loading data for package '%1$s' in '%2$s'.",
									pkgInfo.getName(), pkgInfo.getLibLocation() ),
							e ));
				}
			}
			
			m.beginSubTask("Finishing index of help...");
			job.finish(m.newSubMonitor(2));
			job= null;
			
			
			return;
		}
		catch (final StatusException e) {
			if (e.getStatus().getSeverity() == Status.CANCEL) {
				throw e;
			}
			errorCause= e;
		}
		catch (final Exception e) {
			errorCause= e;
		}
		finally {
			if (job != null) {
				job.cancel(m);
			}
		}
		throw new StatusException(new ErrorStatus(BUNDLE_ID,
				"An error occurred when loading the package data.",
				errorCause ));
	}
	
	protected abstract IndexJob scheduleIndexJob(final String name);
	
	
	private static final Pattern URL_SPLIT_PATTERN= Pattern.compile("(?:,|\\s)+"); //$NON-NLS-1$
	
	private RPkgDescription createDescription(final PkgTask task) throws Exception {
		final RCharacterStore data= RDataUtils.checkLengthEqual(task.rDescr.getData(), PKG_DESCR_LENGTH);
		
		final RNumVersion version;
		{	final String versionString= RDataUtils.checkValue(data, PKG_DESCR_IDX_VERSION);
			final RNumVersion taskVersion= task.version;
			if (taskVersion != null) {
				if (!taskVersion.toString().equals(versionString)) {
					throw new Exception(
							String.format("Unexpected package version: expected=%1$s, found=%2$s",
									taskVersion, versionString ));
				}
				version= taskVersion;
			}
			else {
				version= RNumVersion.create(versionString);
			}
		}
		final String built;
		{	final String builtString= RDataUtils.checkValue(data, PKG_DESCR_IDX_BUILT);
			final String taskBuilt= task.built;
			if (taskBuilt != null) {
				if (!taskBuilt.equals(builtString)) {
					throw new Exception(
							String.format("Unexpected package built: expected=%1$s, found=%2$s",
									taskBuilt, builtString ));
				}
				built= taskBuilt;
			}
			else {
				built= builtString;
			}
		}
		final ImList<String> urls;
		{	String urlString= data.get(PKG_DESCR_IDX_URL);
			if (urlString != null && !(urlString= urlString.strip()).isEmpty()) {
				urls= ImCollections.newList(URL_SPLIT_PATTERN.split(urlString));
			}
			else {
				urls= ImCollections.emptyList();
			}
		}
		return new BasicRPkgDescription(task.name,
				version,
				RDataUtils.getValue(data, PKG_DESCR_IDX_TITLE, ""), //$NON-NLS-1$
				RDataUtils.getValue(data, PKG_DESCR_IDX_DESCRIPTION, ""), //$NON-NLS-1$
				data.get(PKG_DESCR_IDX_AUTHOR),
				data.get(PKG_DESCR_IDX_MAINTAINER),
				urls,
				built, task.libLocation );
	}
	
	private void processRdData(final String pkgName, final RList pkgList) throws Exception {
		for (int j= 0; j < pkgList.getLength(); j++) {
			final RObject rdObj= pkgList.get(j);
			if (rdObj.getRClassName().equals("RdData")) { //$NON-NLS-1$
				final RList rdData= (RList) rdObj;
				final RdItem rdItem= new RdItem(pkgName, pkgList.getName(j));
				{	final RStore<?> store= rdData.get("title").getData(); //$NON-NLS-1$
					if (!store.isNA(0)) {
						rdItem.setTitle(store.getChar(0));
					}
				}
				{	final RStore<?> store= rdData.get("topics").getData(); //$NON-NLS-1$
					for (int k= 0; k < store.getLength(); k++) {
						if (!store.isNA(k)) {
							final String alias= store.getChar(k).trim();
							if (alias.length() > 0) {
								rdItem.addTopic(alias);
							}
						}
					}
				}
				{	final RStore<?> store= rdData.get("keywords").getData(); //$NON-NLS-1$
					for (int k= 0; k < store.getLength(); k++) {
						if (!store.isNA(k)) {
							final String keyword= store.getChar(k).trim();
							if (keyword.length() > 0) {
								rdItem.addKeyword(keyword);
							}
						}
					}
				}
				{	final RStore<?> store= rdData.get("concepts").getData(); //$NON-NLS-1$
					for (int k= 0; k < store.getLength(); k++) {
						if (!store.isNA(k)) {
							final String concept= store.getChar(k).trim();
							if (concept.length() > 0) {
								rdItem.addConcept(concept);
							}
						}
					}
				}
				{	final RStore<?> store= rdData.get("HTML").getData(); //$NON-NLS-1$
					if (store != null && store.getStoreType() == RStore.CHARACTER) {
						rdItem.setHtml(processHtml((RCharacterStore) store));
					}
				}
				this.index.add(rdItem);
			}
		}
	}
	
	@SuppressWarnings("nls")
	private String processHtml(final RCharacterStore store) {
		this.tempBuilder1.setLength(0);
		this.tempBuilder2.setLength(0);
		int length= 0;
		for (int i= 0; i < store.getLength(); i++) {
			if (!store.isNA(i)) {
				length+= store.getChar(i).length() + 2;
			}
		}
		length+= 300;
		this.tempBuilder2.ensureCapacity(length);
		
		int topIndex= -1;
		boolean inExamples= false;
		this.tempBuilder2.append("<div class=\"toc\"><ul>");
		for (int i= 0; i < store.getLength(); i++) {
			Matcher matcher;
			if (!store.isNA(i)) {
				String line= store.getChar(i);
				if (topIndex == -1) {
					if (line.startsWith("<table ")) {
						this.tempBuilder1.append("<table class=\"header\" ");
						line= line.substring(7);
					}
					else if (line.startsWith("<h2>")) {
						topIndex= this.tempBuilder1.length();
						this.tempBuilder1.append("<h2 id=\"top\">");
						line= line.substring(4);
					}
				}
				else if (topIndex >= 0 && line.length() > 10) {
					if (line.startsWith("<h3>")) {
						if (inExamples) {
							this.tempBuilder1.append(RHelpWebapp.HTML_END_EXAMPLES);
							inExamples= false;
						}
						switch (line.charAt(4) - line.charAt(6)) {
						case ('D' - 's'):
							if (line.equals("<h3>Description</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#description\"><span class=\"mnemonic\">D</span>escription</a></li>"); //$NON-NLS-1$
								line= "<h3 id=\"description\">Description</h3>";
								break;
							}
							break;
						case ('U' - 'a'):
							if (line.equals("<h3>Usage</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#usage\"><span class=\"mnemonic\">U</span>sage</a></li>"); //$NON-NLS-1$
								line= "<h3 id=\"usage\">Usage</h3>";
								break;
							}
							break;
						case ('A' - 'g'):
							if (line.equals("<h3>Arguments</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#arguments\"><span class=\"mnemonic\">A</span>rguments</a></li>"); //$NON-NLS-1$
								line= "<h3 id=\"arguments\">Arguments</h3>";
								break;
							}
							break;
						case ('D' - 't'):
							if (line.equals("<h3>Details</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#details\">Deta<span class=\"mnemonic\">i</span>ls</a></li>");
								line= "<h3 id=\"details\">Details</h3>";
								break;
							}
							break;
						case ('V' - 'l'):
							if (line.equals("<h3>Value</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#value\"><span class=\"mnemonic\">V</span>alue</a></li>");
								line= "<h3 id=\"value\">Value</h3>";
								break;
							}
							break;
						case ('A' - 't'):
							if (line.equals("<h3>Author(s)</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#authors\">Auth<span class=\"mnemonic\">o</span>r(s)</a></li>");
								line= "<h3 id=\"authors\">Author(s)</h3>";
								break;
							}
							break;
						case ('R' - 'f'):
							if (line.equals("<h3>References</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#references\"><span class=\"mnemonic\">R</span>eferences</a></li>");
								line= "<h3 id=\"references\">References</h3>";
								break;
							}
							break;
						case ('E' - 'a'):
							if (line.equals("<h3>Examples</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#examples\"><span class=\"mnemonic\">E</span>xamples</a></li>");
								line= "<h3 id=\"examples\">Examples</h3>" + RHelpWebapp.HTML_BEGIN_EXAMPLES;
								inExamples= true;
								break;
							}
							break;
						case ('S' - 'e'):
							if (line.equals("<h3>See Also</h3>")) {
								this.tempBuilder2.append("<li><a href=\"#seealso\"><span class=\"mnemonic\">S</span>ee Also</a></li>");
								line= "<h3 id=\"seealso\">See Also</h3>";
								break;
							}
							break;
						}
					}
					else if (line.startsWith(HR_PREFIX)
							&& (matcher= HR_LINE_PATTERN.matcher(line)).find() ) {
						if (inExamples) {
							this.tempBuilder1.append(RHelpWebapp.HTML_END_EXAMPLES);
							inExamples= false;
						}
//						if (line.startsWith("<hr><div align=\"center\">[Package <em>")) {
//							this.tempBuilder1.append("<hr/><div class=\"toc\"><ul><li><a href=\"#top\">Top</a></li></ul></div>");
//						}
						this.tempBuilder1.append("<hr/>");
						line= line.substring(matcher.end() - matcher.start());
					}
				}
				this.tempBuilder1.append(line);
				this.tempBuilder1.append('\r');
				this.tempBuilder1.append('\n');
			}
		}
		if (topIndex >= 0) {
			this.tempBuilder2.append("</ul></div>");
			this.tempBuilder1.insert(topIndex, this.tempBuilder2);
		}
		return this.tempBuilder1.toString();
	}
	
	protected Path toLocalPath(final String rPath,
			final RService r, final ProgressMonitor m) throws StatusException {
		return Path.of(rPath);
	}
	
}
