/*=============================================================================#
 # Copyright (c) 2009, 2018 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.rj.server.client;

import static org.eclipse.statet.rj.server.util.ServerUtils.MISSING_ANSWER_STATUS;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.OutputStream;
import java.rmi.ConnectException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;

import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.data.REnvironment;
import org.eclipse.statet.rj.data.RJIO;
import org.eclipse.statet.rj.data.RJIOExternalizable;
import org.eclipse.statet.rj.data.RList;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.server.BinExchange;
import org.eclipse.statet.rj.server.ComHandler;
import org.eclipse.statet.rj.server.ConsoleReadCmdItem;
import org.eclipse.statet.rj.server.CtrlCmdItem;
import org.eclipse.statet.rj.server.DataCmdItem;
import org.eclipse.statet.rj.server.DataCmdItem.Operation;
import org.eclipse.statet.rj.server.DbgCmdItem;
import org.eclipse.statet.rj.server.ExtClientCmdItem;
import org.eclipse.statet.rj.server.GDCmdItem;
import org.eclipse.statet.rj.server.GraOpCmdItem;
import org.eclipse.statet.rj.server.MainCmdC2SList;
import org.eclipse.statet.rj.server.MainCmdItem;
import org.eclipse.statet.rj.server.MainCtrlCmdItem;
import org.eclipse.statet.rj.server.REngine;
import org.eclipse.statet.rj.server.RjsComConfig;
import org.eclipse.statet.rj.server.RjsComObject;
import org.eclipse.statet.rj.server.RjsPing;
import org.eclipse.statet.rj.server.RjsStatus;
import org.eclipse.statet.rj.server.Server;
import org.eclipse.statet.rj.server.client.RClientGraphic.InitConfig;
import org.eclipse.statet.rj.server.dbg.CtrlReport;
import org.eclipse.statet.rj.services.RPlatform;
import org.eclipse.statet.rj.services.RService;


/**
 * Generic RJ Com protocol client for servers offering a {@link REngine}.
 * <p>
 * It offers basic implementation for most methods of the {@link RService} API,
 * including:</p>
 * <ul>
 *   <li>Expression evaluation</li>
 *   <li>Data exchange to assign or eval/read {@link RObject}</li>
 *   <li>File exchange to write/read file on the server (must be enabled at server side)</li>
 *   <li>R graphics (requires an {@link RClientGraphicFactory}, set in {@link #initGraphicFactory()},
 *       or via {@link #setGraphicFactory(RClientGraphicFactory, RClientGraphicActions)})</li>
 *   <li>Console (REPL), if connected to server slot 0</li>
 * </ul>
 * <p>
 * If offers two mechanisms allowing the usage of RService API and R thread when they are already
 * used by a regular call. So the two modes allows to "hijack" the R thread to "inject" additional
 * calls to the RService API:</p>
 * <ul>
 *   <li>Hot Mode: Enables to run code in any situation, also if R is busy. Nesting of hot modes is
 *       not possible. It can be requested asynchronous from any thread. The hot mode is appropriate
 *       for e.g. short task for the GUI.</li>
 *   <li>Extra Mode: Enables to run code at the before or after of a client-server communication.
 *       Must be requested synchronous from the R thread.</li>
 * </ul>
 */
public abstract class AbstractRJComClient implements ComHandler {
	
	
	public static final String RJ_CLIENT_ID= "org.eclipse.statet.rj.client";
	
	public static int[] version() {
		return new int[] { 4, 0, 0 };
	}
	
	public static final int EXTRA_BEFORE= 1;
	public static final int EXTRA_NESTED= 2;
	
	private static final ScheduledExecutorService RJHelper_EXECUTOR =
			Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory("RJHelper"));
	
	private static final Random RAND= new Random();
	
	
	private static class DummyFactory implements RClientGraphicFactory {
		
		@Override
		public Map<String, ? extends Object> getInitServerProperties() {
			return null;
		}
		
		@Override
		public RClientGraphic newGraphic(final int devId, final double w, final double h,
				final InitConfig config,
				final boolean active, final RClientGraphicActions actions, final int options) {
			return new RClientGraphicDummy(devId, w, h);
		}
		
		@Override
		public void closeGraphic(final RClientGraphic graphic) {
		}
		
	}
	
	private final static class RunnableList {
		
		private Runnable[] array;
		private int size;
		
		public RunnableList() {
			this.array= new Runnable[4];
			this.size= 0;
		}
		
		
		public void add(final Runnable value) {
			if (value == null) {
				throw new IllegalArgumentException();
			}
			final int oldCapacity= this.array.length;
			if (this.size < oldCapacity) {
				this.array[this.size++]= value;
				return;
			}
			final Runnable[] newArray= new Runnable[oldCapacity + 4];
			System.arraycopy(this.array, 0, newArray, 0, oldCapacity);
			newArray[this.size++]= value;
			this.array= newArray;
		}
		
		public boolean isNotEmpty() {
			return (this.size != 0);
		}
		
		public Runnable[] consume() {
			final Runnable[] oldListeners= this.array;
			this.size= 0;
			this.array= new Runnable[4];
			return oldListeners;
		}
		
	}
	
	
	private class KeepAliveRunnable implements Runnable {
		
		@Override
		public void run() {
			runAsyncPing();
		}
		
	}
	
	private class HotModeRequestRunnable implements Runnable {
		
		@Override
		public void run() {
			if (AbstractRJComClient.this.hotModeRequested.get()) {
				try {
					runAsyncCtrl(CtrlCmdItem.REQUEST_HOT_MODE);
				}
				catch (final CoreException e) {
					if (e.getStatus().getSeverity() != IStatus.CANCEL) {
						log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when requesting hot mode.", e));
					}
				}
			}
		}
	}
	
	
	private RService rService;
	private Object rHandle;
	
	private IProgressMonitor progressMonitor;
	
	private final RJIO mainIO= new RJIO();
	private MainCmdItem mainC2SFirst;
	private final MainCmdC2SList mainC2SList= new MainCmdC2SList(this.mainIO);
	private final RunnableList mainDeferredCmds= new RunnableList();
	private boolean mainRunGC;
	
	private boolean consoleReadCallbackRequired;
	private ConsoleReadCmdItem consoleReadCallback;
	
	private final Object platformLock= new Object();
	private Map<String, Object> platformData;
	private RPlatform platformObj;
	
	private final byte randomId= (byte) (0xff & RAND.nextInt(255));
	
	private int dataLevelRequest= 0;
	private int dataLevelAnswer= 0;
	private int dataLevelIgnore= 0;
	private byte dataRequestCounter= (byte) (0xff & RAND.nextInt(255));
	private final int[] dataRequestId= new int[32];
	private final MainCmdItem[] dataAnswer= new MainCmdItem[32];
	
	private boolean runFinishTask;
	
	private boolean dbgOpRequest;
	private DbgCmdItem dbgOpAnswer;
	
	private int hotModeState;
	private ConsoleReadCmdItem hotModeReadCallbackBackup;
	private MainCmdItem hotModeC2SFirstBackup;
	private final AtomicBoolean hotModeRequested= new AtomicBoolean();
	private final Runnable hotModeRunnable= new HotModeRequestRunnable();
	
	private int extraModeRequested;
	
	private RClientGraphicFactory graphicFactory;
	private RClientGraphicActions graphicActions;
	private final RClientGraphic graphicDummy= new RClientGraphicDummy(1, 0, 0);
	private RClientGraphic[] graphics= new RClientGraphic[16];
	private int currentGraphicOptions;
	private RClientGraphic lastGraphic;
	
	private REngine rjConsoleEngine;
	
	private List<Runnable> defferedRunnables;
	
	private boolean closed;
	private ScheduledFuture<?> keepAliveJob;
	private String closedMessage= "Connection to R engine is closed.";
	
	private final Lock clientWaitLock= new ReentrantLock();
	private final Condition clientWaitCondition= this.clientWaitLock.newCondition();
	private final List<Callable<Boolean>> cancelHandler= new ArrayList<>();
	
	
	protected AbstractRJComClient() {
	}
	
	
	public void initClient(final Object rHandle, final RService r,
			final Map<String, Object> properties, final int id) {
		this.rHandle= rHandle;
		this.rService= r;
		properties.put("rj.com.init", Boolean.TRUE); //$NON-NLS-1$
		properties.put(RjsComConfig.RJ_COM_S2C_ID_PROPERTY_ID, id);
		
		try {
			initGraphicFactory();
		}
		catch (final Exception e) {
			log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when initializing R client graphic factory.", e));
		}
		if (this.graphicFactory != null) {
			final Map<String, ? extends Object> additional= this.graphicFactory.getInitServerProperties();
			if (additional != null) {
				properties.putAll(additional);
			}
		}
		else {
			this.graphicFactory= new DummyFactory();
			log(new Status(IStatus.WARNING, RJ_CLIENT_ID, -1, "No R client graphic factory configured.", null));
		}
	}
	
	public final void setServer(final REngine rjServer, final int client) {
		final List<Runnable> runnables;
		synchronized (this) {
			this.rjConsoleEngine= rjServer;
			if (client == 0) {
				long t= 45 * 1000;
				try {
					final String p= System.getProperty("org.eclipse.statet.rj.client.keepaliveInterval"); //$NON-NLS-1$
					if (p != null && p.length() > 0) {
						t= Long.parseLong(p);
					}
				}
				catch (final Exception e) {}
				this.keepAliveJob= RJHelper_EXECUTOR.scheduleWithFixedDelay(
						new KeepAliveRunnable(), t, t, TimeUnit.MILLISECONDS );
			}
			runnables= this.defferedRunnables;
			this.defferedRunnables= null;
		}
		if (runnables != null) {
			for (int i= 0; i < runnables.size(); i++) {
				RJHelper_EXECUTOR.execute(runnables.get(i));
			}
		}
	}
	
	public Object getRHandle() {
		return this.rHandle;
	}
	
	public RService getRService() {
		return this.rService;
	}
	
	public final REngine getConsoleEngine() {
		return this.rjConsoleEngine;
	}
	
	protected void execAsync(final Runnable runnable) {
		synchronized (this) {
			if (this.rjConsoleEngine == null) {
				if (this.defferedRunnables == null) {
					this.defferedRunnables= new ArrayList<>(8);
				}
				this.defferedRunnables.add(runnable);
				return;
			}
		}
		RJHelper_EXECUTOR.execute(runnable);
	}
	
	protected void initGraphicFactory() {
	}
	
	
	public final void setGraphicFactory(final RClientGraphicFactory factory, final RClientGraphicActions actions) {
		if (factory == null) {
			throw new NullPointerException();
		}
		this.graphicFactory= factory;
		this.graphicActions= actions;
	}
	
	public boolean isClosed() {
		return this.closed;
	}
	
	public void setClosed(final boolean closed) {
		if (this.closed != closed) {
			this.closed= closed;
			if (closed) {
				final ScheduledFuture<?> job= this.keepAliveJob;
				if (job != null) {
					this.keepAliveJob= null;
					job.cancel(true);
				}
			}
		}
	}
	
	public void setRjsProperties(final Map<String, ? extends Object> properties) throws CoreException {
		try {
			this.rjConsoleEngine.setProperties(properties);
		}
		catch (final RemoteException e) {
			throw new CoreException(new Status(IStatus.ERROR, RJ_CLIENT_ID, "An error occurred when setting server properties.", e));
		}
	}
	
	
	@Override
	public final void processMainCmd(final ObjectInput in) throws IOException {
		boolean runGC= false;
		updateBusy(in.readBoolean());
		if (this.hotModeState == 4) {
			this.hotModeState= 0;
			this.consoleReadCallback= this.hotModeReadCallbackBackup;
			this.hotModeReadCallbackBackup= null;
			if (this.hotModeC2SFirstBackup != null) {
				addC2SCmd(this.hotModeC2SFirstBackup);
				this.hotModeC2SFirstBackup= null;
			}
		}
		
		this.mainIO.connect(in);
		final int check= this.mainIO.readCheck1();
		
		while (true) {
			final byte type= in.readByte();
			switch (type) {
			case MainCmdItem.T_NONE:
				this.mainIO.readCheck2(check);
				this.mainIO.disconnect(in);
				this.mainRunGC= runGC;
				return;
			case MainCmdItem.T_CONSOLE_READ_ITEM:
				processPrompt(new ConsoleReadCmdItem(this.mainIO));
				continue;
			case MainCmdItem.T_CONSOLE_WRITE_ITEM:
				runGC= true;
				writeConsoleOutput(this.mainIO.readByte(), this.mainIO.readString());
				continue;
			case MainCmdItem.T_MESSAGE_ITEM:
				runGC= true;
				showMessage(this.mainIO.readString());
				continue;
			case MainCmdItem.T_EXT_CLIENT_ITEM:
				runGC= true;
				processUICallback(this.mainIO);
				continue;
			case MainCmdItem.T_GRAPH_ITEM:
				runGC= true;
				processGDCmd(this.mainIO);
				continue;
			case MainCmdItem.T_MAIN_CTRL_ITEM:
				runGC= true;
				processMainCtrlCmd(this.mainIO);
				continue;
			case MainCmdItem.T_DATA_ITEM:
				runGC= true;
				processDataCmd(this.mainIO);
				continue;
			case MainCmdItem.T_GRAPHICS_OP_ITEM:
				runGC= true;
				processGraphicsOpCmd(this.mainIO);
				continue;
			case MainCmdItem.T_DBG_ITEM:
				runGC= true;
				processDbgCmd(this.mainIO);
				continue;
			default:
				this.mainIO.disconnect(in);
				throw new IOException("Unknown cmdtype id: " + type);
			}
		}
	}
	
	private final void processCmdDeferred(final Runnable runnable) {
		this.mainDeferredCmds.add(runnable);
	}
	
	
	public final boolean processUICallback(final RJIO io) throws IOException {
		final ExtClientCmdItem item= new ExtClientCmdItem(io);
		try {
			final RList answer= handleUICallback(item.getDataText(), item.getDataArgs(),
					this.progressMonitor);
			item.setAnswer(answer);
		}
		catch (final IOException e) {
			throw e;
		}
		catch (final Exception e) {
			log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when exec RJ UI command '" + item.getDataText() + "'.", e)); 
			if (item.waitForClient()) {
				item.setAnswer(new RjsStatus(RjsStatus.ERROR, 0, "Client error processing current command."));
			}
		}
		if (item.waitForClient()) {
			addC2SCmd(item);
			return true;
		}
		return false;
	}
	
	protected RList handleUICallback(final String commandId, final RList args,
			final IProgressMonitor monitor) throws Exception {
		throw new CoreException(new Status(IStatus.WARNING, RJ_CLIENT_ID, -1, "Unhandled RJ UI command '" + commandId + "'.", null)); 
	}
	
	
	public final void processGDCmd(final RJIO io) throws IOException {
		final int devId;
		final int options;
		{	final int i= io.readInt();
			options= (i & MainCmdItem.OV_WAITFORCLIENT);
			devId= (i & ~MainCmdItem.OV_WAITFORCLIENT);
		}
		byte requestId= -1;
		try {
			switch (io.readByte()) {
			case GDCmdItem.C_NEW_PAGE:
				addGraphic(devId,
						io.readDouble(),
						io.readDouble(),
						io.readInt(),
						io.readBoolean() );
				return;
			case GDCmdItem.C_CLOSE_DEVICE:
				removeGraphic(devId);
				return;
			case GDCmdItem.C_GET_SIZE:
				addC2SCmd(new GDCmdItem.DoubleAnswer(requestId= io.readByte(),
						devId, getGraphic(devId).computeSize() ));
				return;
			case GDCmdItem.C_SET_ACTIVE_OFF:
				getGraphic(devId).setActive(false);
				return;
			case GDCmdItem.C_SET_ACTIVE_ON:
				getGraphic(devId).setActive(true);
				return;
			case GDCmdItem.C_SET_MODE:
				getGraphic(devId).setMode(io.readByte());
				return;
			case GDCmdItem.C_GET_FONTMETRIC:
				addC2SCmd(new GDCmdItem.DoubleAnswer(requestId= io.readByte(),
						devId, getGraphic(devId).computeFontMetric(
								io.readInt() )));
				return;
			case GDCmdItem.C_GET_STRINGWIDTH:
				addC2SCmd(new GDCmdItem.DoubleAnswer(requestId= io.readByte(),
						devId, getGraphic(devId).computeStringWidth(
								io.readString() )));
				return;
				
			case GDCmdItem.SET_CLIP:
				getGraphic(devId).addSetClip(
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble() );
				return;
			case GDCmdItem.SET_COLOR:
				getGraphic(devId).addSetColor(
						io.readInt() );
				return;
			case GDCmdItem.SET_FILL:
				getGraphic(devId).addSetFill(
						io.readInt() );
				return;
			case GDCmdItem.SET_LINE:
				getGraphic(devId).addSetLine(
						io.readInt(),
						io.readFloat(),
						io.readByte(),
						io.readByte(),
						io.readFloat() );
				return;
			case GDCmdItem.SET_FONT:
				getGraphic(devId).addSetFont(
						io.readString(),
						io.readInt(),
						io.readFloat(),
						io.readFloat() );
				return;
				
			case GDCmdItem.DRAW_LINE:
				getGraphic(devId).addDrawLine(
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble() );
				return;
			case GDCmdItem.DRAW_RECTANGLE:
				getGraphic(devId).addDrawRect(
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble() );
				return;
			case GDCmdItem.DRAW_POLYLINE:
				getGraphic(devId).addDrawPolyline(
						io.readDoubleArray(),
						io.readDoubleArray2() );
				return;
			case GDCmdItem.DRAW_POLYGON:
				getGraphic(devId).addDrawPolygon(
						io.readDoubleArray(),
						io.readDoubleArray2() );
				return;
			case GDCmdItem.DRAW_PATH:
				getGraphic(devId).addDrawPath(
						io.readIntArray(),
						io.readDoubleArray(),
						io.readDoubleArray2(),
						io.readInt() );
				return;
			case GDCmdItem.DRAW_CIRCLE:
				getGraphic(devId).addDrawCircle(
						io.readDouble(),
						io.readDouble(),
						io.readDouble() );
				return;
			case GDCmdItem.DRAW_TEXT:
				getGraphic(devId).addDrawText(
						io.readString(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble() );
				return;
			case GDCmdItem.DRAW_RASTER:
				getGraphic(devId).addDrawRaster(
						io.readByteArray(),
						io.readBoolean(),
						io.readInt(),
						io.readInt(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readDouble(),
						io.readBoolean() );
				return;
				
			case GDCmdItem.CAPTURE:
				addC2SCmd(new GDCmdItem.Answer(requestId= io.readByte(),
						devId, getGraphic(devId).capture(
								io.readInt(),
								io.readInt() )));
				return;
				
			case GDCmdItem.U_LOCATOR: {
				final byte fid= requestId= io.readByte();
				processCmdDeferred(new Runnable() {
					@Override
					public void run() {
						addC2SCmd(new GDCmdItem.DoubleAnswer(fid,
								devId, getGraphic(devId).runRLocator(
										AbstractRJComClient.this.rService,
										AbstractRJComClient.this.progressMonitor )));
					}
				});
				return; }
				
			default:
				if ((options & MainCmdItem.OV_WAITFORCLIENT) != 0) {
					requestId= io.readByte();
				}
				throw new UnsupportedOperationException("Unknown GD command.");
			}
		}
		catch (final IOException e) {
			throw e;
		}
		catch (final Throwable e) {
			log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when processing graphic command.", e));
			if (requestId >= 0) {
				addC2SCmd(new GDCmdItem.Answer(requestId, devId, new RjsStatus(RjsStatus.ERROR, 0)));
			}
//			throw new RuntimeException(e);
		}
	}
	
	
	private final void processMainCtrlCmd(final RJIO io) throws IOException {
		try {
			final MainCtrlCmdItem item= new MainCtrlCmdItem(io);
			addDataAnswer(item);
		}
		catch (final IOException e) {
			throw e;
		}
		catch (final Exception e) {
			log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when processing control command answer.", e));
		}
	}
	
	private final void processDataCmd(final RJIO io) throws IOException {
		try {
			final DataCmdItem item= new DataCmdItem(io);
			addDataAnswer(item);
		}
		catch (final IOException e) {
			throw e;
		}
		catch (final Exception e) {
			log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when processing data command answer.", e));
		}
	}
	
	private final void processGraphicsOpCmd(final RJIO io) throws IOException {
		try {
			final GraOpCmdItem item= new GraOpCmdItem(io);
			addDataAnswer(item);
		}
		catch (final IOException e) {
			throw e;
		}
		catch (final Exception e) {
			log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when processing graphic operation answer.", e));
		}
	}
	
	private final int newDataLevel() {
		final int level= ++this.dataLevelRequest;
		if (level >= this.dataAnswer.length) {
			this.dataLevelRequest--;
			throw new UnsupportedOperationException("too much nested operations");
		}
		this.dataLevelAnswer= 0;
		
		return level;
	}
	
	private final MainCmdItem createDataRequestId(final int level, final MainCmdItem item) {
		this.dataRequestId[level]= ((((0xff) & item.getCmdType()) << 24)
				| ((0xff & item.getOp()) << 16)
				| ((0xff & this.randomId << 8))
				| ((0xff & ++this.dataRequestCounter)) ); 
		item.requestId= (((0xff & level) << 24) | (0xffffff & this.dataRequestId[level]));
		return item;
	}
	
	private final void addDataAnswer(final MainCmdItem item) throws RjException {
		final int level= (((0xff000000) & item.requestId) >>> 24);
		if (level > 0 && level <= this.dataLevelRequest
				&& this.dataRequestId[level] == (((0xff & item.getCmdType()) << 24)
						| (0xffffff & item.requestId)) ) {
			this.dataAnswer[level]= item;
			this.dataLevelAnswer= level;
			return;
		}
		if ((item.requestId & 0xff00 >>> 8) != (this.randomId & 0xff)) {
			// other client
//			System.out.println("Other client: " + item);
			return;
		}
		throw new RjException("Unexpected server answer: " + item);
	}
	
	private final void finalizeDataLevel() {
		final int level= this.dataLevelRequest--;
		this.dataAnswer[level]= null;
		this.dataLevelAnswer= (this.dataAnswer[this.dataLevelRequest] != null) ? this.dataLevelRequest : 0;
		
		this.runFinishTask= true;
	}
	
	public final int getDataLevel() {
		return this.dataLevelRequest;
	}
	
	
	protected final void processDbgCmd(final RJIO io) throws IOException {
		final DbgCmdItem item= new DbgCmdItem(io);
		if (item.getOp() > DbgCmdItem.OP_C2S_S2C) {
			handleDbgEvents(item.getOp(), item.getData());
		}
		else if (this.dbgOpRequest) {
			this.dbgOpAnswer= item;
		}
	}
	
	protected void handleDbgEvents(final byte dbgOp, final Object events) {
	}
	
	
	protected abstract void log(IStatus status);
	
	protected abstract void handleServerStatus(final RjsStatus serverStatus, final IProgressMonitor monitor) throws CoreException;
	
	protected abstract void handleStatus(Status status, IProgressMonitor monitor);
	
	protected void scheduleConnectionCheck() {
	}
	
	
	public final boolean runAsyncPing() {
		try {
			final RjsComObject answer= this.rjConsoleEngine.runAsync(RjsPing.INSTANCE);
			if (answer instanceof RjsStatus) {
				final RjsStatus status= (RjsStatus) answer;
				if (status.getSeverity() == RjsStatus.OK) {
					return true;
				}
				scheduleConnectionCheck();
			}
		}
		catch (final ConnectException e) {
			scheduleConnectionCheck();
		}
		catch (final RemoteException e) {
			// TODO if (rmiregistry is available) scheduleCheck();
			// no need to log here
		}
		catch (final Exception e) {
		}
		return false;
	}
	
	public final boolean runAsyncInterrupt() {
		final Callable<Boolean>[] handlers= getCancelHandlers();
		for (int i= handlers.length - 1; i >= 0; i--) {
			try {
				final Boolean done= handlers[i].call();
				if (done != null && done.booleanValue()) {
					return false;
				}
			}
			catch (final Exception e) {
				// handler failed
			}
		}
		final IProgressMonitor monitor= this.progressMonitor;
		if (monitor != null) {
			monitor.setCanceled(true);
		}
		try {
			runAsyncCtrl(CtrlCmdItem.REQUEST_CANCEL);
			return true;
		}
		catch (final CoreException e) {
			if (e.getStatus().getSeverity() != IStatus.CANCEL) {
				log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "An error occurred when trying to interrupt R.", e));
			}
			return false;
		}
	}
	
	public final void runAsyncCtrl(final int id) throws CoreException {
		final RjsStatus status= (RjsStatus) runAsync(new CtrlCmdItem(id));
		if (status.getSeverity() != RjsStatus.OK) {
			throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
					"Executing CTRL command failed.", null));
		}
	}
	
	public final RjsComObject runAsync(final RjsComObject com) throws CoreException {
		if (this.closed) {
			throw new CoreException(new Status(IStatus.ERROR, RJ_CLIENT_ID, 0, this.closedMessage, null));
		}
		try {
			return this.rjConsoleEngine.runAsync(com);
		}
		catch (final Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, RJ_CLIENT_ID, 0, "Communication error.", e));
		}
	}
	
	public final void runMainLoopPing(final IProgressMonitor monitor) throws CoreException {
		try {
			this.mainRunGC= false;
			final RjsStatus status= (RjsStatus) this.rjConsoleEngine.runMainLoop(RjsPing.INSTANCE);
			if (status.getSeverity() == RjsStatus.OK) {
				return;
			}
			handleServerStatus(status, monitor);
		}
		catch (final ConnectException e) {
			handleServerStatus(new RjsStatus(RjsStatus.INFO, Server.S_DISCONNECTED), monitor);
		}
		catch (final Exception e) {
			// no need to log here
			handleServerStatus(new RjsStatus(RjsStatus.INFO, Server.S_LOST), monitor);
		}
	}
	
	public final void runMainLoop(RjsComObject sendCom, MainCmdItem sendItem, final IProgressMonitor monitor) throws CoreException {
		if (this.closed) {
			throw new CoreException(new Status(IStatus.ERROR, RJ_CLIENT_ID, 0, this.closedMessage, null));
		}
		final boolean loopReadCallbackIgnore= !this.consoleReadCallbackRequired;
		final int loopDataLevelIgnore= this.dataLevelIgnore;
		try {
			if ((this.extraModeRequested & EXTRA_BEFORE) != 0 && this.hotModeState < 1) {
				this.extraModeRequested= 0;
				this.dataLevelIgnore= this.dataLevelRequest;
				processExtraMode(EXTRA_BEFORE);
			}
			while (this.hotModeRequested.get()
					&& this.hotModeState < 1 && !this.dbgOpRequest) {
				this.dataLevelIgnore= this.dataLevelRequest;
				startHotMode();
			}
			this.progressMonitor= monitor;
			int ok= 0;
			while (!this.closed) {
				try {
					RjsComObject receivedCom= null;
					if (sendItem != null) {
						if (sendItem.getCmdType() == MainCmdItem.T_CONSOLE_READ_ITEM) {
							this.consoleReadCallback= null;
						}
						this.mainC2SList.setObjects(sendItem);
						sendCom= this.mainC2SList;
						sendItem= null;
					}
	//				System.out.println("client *-> server: " + sendCom);
					this.mainRunGC= false;
					receivedCom= this.rjConsoleEngine.runMainLoop(sendCom);
					this.mainC2SList.clear();
					sendCom= null;
	//				System.out.println("client *<- server: " + receivedCom);
					switch (receivedCom.getComType()) {
					case RjsComObject.T_PING:
						ok= 0;
						sendCom= RjsStatus.OK_STATUS;
						continue;
					case RjsComObject.T_MAIN_LIST:
						if (this.mainDeferredCmds.isNotEmpty()) {
							final Runnable[] runnables= this.mainDeferredCmds.consume();
							for (int i= 0; i < runnables.length; i++) {
								if (runnables[i] != null) {
									try {
										runnables[i].run();
									}
									catch (final Exception e) {
										log(new Status(IStatus.ERROR, RJ_CLIENT_ID, 0,
												"An error occurred when running a deferred command.", e ));
									}
								}
							}
						}
						ok= 0;
						switch (this.hotModeState) {
						case 1:
							sendCom= this.mainC2SList; // repeat
							continue;
						case 2:
							this.hotModeState= 3;
							this.hotModeRequested.set(false);
							this.dataLevelIgnore= this.dataLevelRequest;
							try {
								processHotMode();
								continue;
							}
							finally {
								this.progressMonitor= monitor;
								this.hotModeState= 4;
								this.consoleReadCallback.setAnswer(RjsStatus.OK_STATUS);
								sendItem= this.consoleReadCallback;
							}
						default:
							while ((sendItem= getC2SCmds()) == null
									&& (loopReadCallbackIgnore || this.consoleReadCallback != null)
									&& (this.dataLevelRequest <= loopDataLevelIgnore
											|| this.dataLevelRequest == this.dataLevelAnswer
											|| (this.extraModeRequested & EXTRA_NESTED) != 0 )
									&& (this.dbgOpRequest == (this.dbgOpAnswer != null))) {
								if (this.mainRunGC) {
									this.mainRunGC= false;
									this.rjConsoleEngine.runMainLoop(RjsPing.INSTANCE);
								}
								if ((this.extraModeRequested & EXTRA_NESTED) != 0 && this.hotModeState < 1) {
									this.extraModeRequested= 0;
									this.dataLevelIgnore= this.dataLevelRequest;
									try {
										processExtraMode(EXTRA_NESTED);
										continue; // validate again
									}
									finally {
										this.progressMonitor= monitor;
									}
								}
								else {
									return; // finished
								}
							}
							continue;
						}
					case RjsComObject.T_STATUS:
						ok= 0;
						processStatus((RjsStatus) receivedCom, monitor);
						sendCom= this.mainC2SList;
						continue;
					}
				}
				catch (final ConnectException e) {
					handleServerStatus(new RjsStatus(RjsStatus.INFO, Server.S_DISCONNECTED), monitor);
					return;
				}
				catch (final RemoteException e) {
					log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "Communication error detail. Send:\n"+sendCom, e));
					if (!this.closed && runAsyncPing()) { // async to avoid server gc
						if (this.consoleReadCallback == null && ok == 0) {
							ok++;
							handleStatus(new Status(IStatus.ERROR, RJ_CLIENT_ID, "Communication error, see Eclipse log for detail."), monitor);
							continue;
						}
						throw new CoreException(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1, "Communication error.", e));
					}
					handleServerStatus(new RjsStatus(RjsStatus.INFO, Server.S_LOST), monitor);
					return;
				}
			}
			
			handleServerStatus(new RjsStatus(RjsStatus.INFO, Server.S_DISCONNECTED), monitor);
		}
		finally {
			this.dataLevelIgnore= loopDataLevelIgnore;
		}
	}
	
	
	protected final void addC2SCmd(final MainCmdItem item) {
		if (this.mainC2SFirst == null) {
			this.mainC2SFirst= item;
		}
		else {
			item.next= this.mainC2SFirst;
			this.mainC2SFirst= item;
			
			// TODO
			log(new Status(IStatus.INFO, RJ_CLIENT_ID, "Multiple C2S items:\\" + this.mainC2SFirst.toString() + "\n" + this.mainC2SFirst.next.toString()));
		}
	}
	
	private final MainCmdItem getC2SCmds() {
		final MainCmdItem item= this.mainC2SFirst;
		this.mainC2SFirst= null;
		return item;
	}
	
	private final void processStatus(final RjsStatus status, final IProgressMonitor monitor)
			throws CoreException {
		if ((status.getCode() & 0xffffff00) == 0) {
			handleServerStatus(status, monitor);
			return;
		}
		if (status.getSeverity() != RjsStatus.OK) {
			// TODO
//			System.out.println(status);
		}
	}
	
	private final void processPrompt(final ConsoleReadCmdItem item) {
		switch (item.getCmdOption() & 0xf) {
		case 2:
			if (this.hotModeState < 2) {
				this.hotModeState= 2;
				this.hotModeReadCallbackBackup= this.consoleReadCallback;
				this.hotModeC2SFirstBackup= this.mainC2SFirst;
				this.mainC2SFirst= null;
			}
			this.consoleReadCallback= item;
			return;
		case RjsComObject.V_TRUE:
			this.consoleReadCallback= item;
			updatePrompt(item.getDataText(), true);
			return;
		default:
			this.consoleReadCallback= item;
			updatePrompt(item.getDataText(), false);
			return;
		}
	}
	
	public void requestHotMode(final boolean async) {
		this.hotModeRequested.set(true);
		if (async) {
			RJHelper_EXECUTOR.schedule(this.hotModeRunnable, 100, TimeUnit.MILLISECONDS);
		}
	}
	
	public boolean startHotMode() {
		if (this.hotModeState == 0) {
			this.hotModeRequested.set(false);
			final boolean savedCallbackRequired= this.consoleReadCallbackRequired;
			this.consoleReadCallbackRequired= false;
			try {
				this.hotModeState= 1;
				runMainLoop(new CtrlCmdItem(CtrlCmdItem.REQUEST_HOT_MODE), null, new NullProgressMonitor());
				return true;
			}
			catch (final Throwable e) {
				this.hotModeState= 0;
				log(new Status(IStatus.ERROR, RJ_CLIENT_ID, 0,
						"An error occurred when running hot mode.", e ));
			}
			finally {
				this.consoleReadCallbackRequired= savedCallbackRequired;
			}
		}
		return false;
	}
	
	public void requestExtraMode(final int positions) {
		this.extraModeRequested= positions;
	}
	
	
	protected void updateBusy(final boolean isBusy) {
	}
	
	protected void updatePrompt(final String text, final boolean addToHistory) {
	}
	
	protected void writeConsoleOutput(final byte streamId, final String text) {
	}
	
	protected void showMessage(final String text) {
	}
	
	protected void processHotMode() {
	}
	
	protected void processExtraMode(final int i) {
	}
	
	private void addGraphic(final int devId, final double w, final double h, final int canvasColor,
			final boolean activate) throws RjException {
		if (devId >= 0) {
			if (devId >= this.graphics.length) {
				final RClientGraphic[] newArray= new RClientGraphic[devId + 10];
				System.arraycopy(this.graphics, 0, newArray, 0, this.graphics.length);
				this.graphics= newArray;
			}
			final InitConfig config= new InitConfig();
			config.canvasColor= canvasColor;
			if (this.graphics[devId] != null) {
				this.graphics[devId].reset(w, h, config);
				this.graphics[devId].setActive(activate);
			}
			else {
				this.graphics[devId]= this.lastGraphic= this.graphicFactory.newGraphic(devId,
						w, h, config,
						activate, this.graphicActions, this.currentGraphicOptions);
			}
			return;
		}
		throw new RjException("Invalid GD devId: " + devId);
	}
	
	private void removeGraphic(final int devId) {
		if (devId >= 0 && devId < this.graphics.length) {
			if (this.graphics[devId] != null) {
				try {
					this.graphicFactory.closeGraphic(this.graphics[devId]);
				}
				catch (final Exception e) {
					log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1,
							"An error occurred when closing R graphic (Device " + (devId+1) + ").", e ));
				}
				this.graphics[devId]= null;
			}
		}
	}
	
	protected RClientGraphic getGraphic(final int devId) {
		if (devId >= 0 && devId < this.graphics.length) {
			final RClientGraphic graphic= this.graphics[devId];
			if (graphic != null) {
				return graphic;
			}
		}
		return this.graphicDummy;
	}
	
	public void disposeAllGraphics() {
		for (int devId= 0; devId < this.graphics.length; devId++) {
			removeGraphic(devId);
		}
	}
	
	
	public final void activateConsole() {
		if (this.rjConsoleEngine == null) {
			throw new IllegalStateException("Missing REngine");
		}
		this.consoleReadCallbackRequired= true;
	}
	
	public final void answerConsole(final String input, final IProgressMonitor monitor) throws CoreException {
		this.consoleReadCallback.setAnswer(input);
		runMainLoop(null, this.consoleReadCallback, monitor);
		
		this.runFinishTask= false;
	}
	
	public final boolean isConsoleReady() {
		return (this.consoleReadCallback != null);
	}
	
	
	private Map<String, Object> getServerData() throws RemoteException {
		if (this.platformData != null) {
			return this.platformData;
		}
		final Map<String, Object> data= this.rjConsoleEngine.getPlatformData();
		if (data != null && data.containsKey("version.string")) { //$NON-NLS-1$
			this.platformData= data;
		}
		return data;
	}
	
	public final RPlatform getRPlatform() {
		synchronized (this.platformLock) {
			if (this.platformObj == null) {
				try {
					final Map<String, Object> data= getServerData();
					if (data != null && data.containsKey("version.string")) {
						this.platformObj= new RPlatform((String) this.platformData.get("os.type"),
								(String) this.platformData.get("file.sep"),
								(String) this.platformData.get("path.sep"),
								(String) this.platformData.get("version.string"),
								(String) this.platformData.get("os.name"),
								(String) this.platformData.get("os.arch"),
								(String) this.platformData.get("os.version") );
					}
				}
				catch (final RemoteException e) {
					log(new Status(IStatus.ERROR, RJ_CLIENT_ID,
							"An error occured when loading data for RPlatform information.", e));
				}
			}
			return this.platformObj;
		}
	}
	
	public final String getProperty(final String key) {
		synchronized (this.platformLock) {
			try {
				final Map<String, Object> data= getServerData();
				if (data != null) {
					final Object value= data.get(key);
					return (value instanceof String) ? (String) value : null;
				}
			}
			catch (final RemoteException e) {
			}
			return null;
		}
	}
	
	
	public final void finishTask(
			final IProgressMonitor monitor) throws CoreException {
		if (!this.runFinishTask) {
			return;
		}
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new MainCtrlCmdItem(MainCtrlCmdItem.OP_FINISH_TASK,
					0 )), monitor);
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return;
		}
		finally {
			finalizeDataLevel();
			this.runFinishTask= false;
		}
	}
	
	
	public boolean isValidEnvRef(final RObject envir) {
		switch (envir.getRObjectType()) {
		case RObject.TYPE_REFERENCE:
			return (((RReference) envir).getReferencedRObjectType() == RObject.TYPE_ENVIRONMENT);
		case RObject.TYPE_LANGUAGE:
			return true;
		default:
			return false;
		}
	}
	
	public final void evalVoid(final String expression, final @Nullable RObject envir,
			final IProgressMonitor monitor) throws CoreException {
		if (expression == null) {
			throw new NullPointerException("expression");
		}
		if (envir != null && !isValidEnvRef(envir)) {
			throw new IllegalArgumentException("envir");
		}
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.EVAL_EXPR_VOID,
					0, expression, null, null, envir )), monitor);
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return;
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public final void evalVoid(final String name, final RList args, final @Nullable RObject envir,
			final IProgressMonitor monitor) throws CoreException {
		if (name == null) {
			throw new NullPointerException("name");
		}
		if (args == null) {
			throw new NullPointerException("args");
		}
		if (envir != null && !isValidEnvRef(envir)) {
			throw new IllegalArgumentException("envir");
		}
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.EVAL_FCALL_VOID,
					0, name, args, null, envir )), monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return;
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public RObject evalData(final String expression, final @Nullable RObject envir,
			final @Nullable String factoryId, final int options, final int depth,
			final IProgressMonitor monitor) throws CoreException {
		if (expression == null) {
			throw new NullPointerException("expression");
		}
		if (envir != null && !isValidEnvRef(envir)) {
			throw new IllegalArgumentException("envir");
		}
		final byte checkedDepth= (depth < Byte.MAX_VALUE) ? (byte) depth : Byte.MAX_VALUE;
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.EVAL_EXPR_DATA,
					options, checkedDepth, expression, null, null, envir, factoryId )), monitor);
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return ((DataCmdItem) this.dataAnswer[level]).getData();
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public RObject evalData(final String name, final RObject args, final @Nullable RObject envir,
			final @Nullable String factoryId, final int options, final int depth,
			final IProgressMonitor monitor) throws CoreException {
		if (name == null) {
			throw new NullPointerException("name");
		}
		if (args == null) {
			throw new NullPointerException("args");
		}
		if (envir != null && !isValidEnvRef(envir)) {
			throw new IllegalArgumentException("envir");
		}
		final byte checkedDepth= (depth < Byte.MAX_VALUE) ? (byte) depth : Byte.MAX_VALUE;
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.EVAL_FCALL_DATA,
					options, checkedDepth, name, args, null, envir, factoryId )), monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return ((DataCmdItem) this.dataAnswer[level]).getData();
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public final RObject evalData(final RReference reference,
			final @Nullable String factoryId, final int options, final int depth,
			final IProgressMonitor monitor) throws CoreException {
		final byte checkedDepth= (depth < Byte.MAX_VALUE) ? (byte) depth : Byte.MAX_VALUE;
		final int level= newDataLevel();
		try {
			final long handle= reference.getHandle();
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.RESOLVE_DATA,
					options, checkedDepth, Long.toString(handle), null, null, null, factoryId )), monitor );
			
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return ((DataCmdItem) this.dataAnswer[level]).getData();
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public RObject evalData(final byte envType, final String name,
			final @Nullable String factoryId, final int options, final int depth,
			final IProgressMonitor monitor) throws CoreException {
		if (name == null) {
			throw new NullPointerException("name");
		}
		final Operation operation;
		switch (envType) {
		case REnvironment.ENVTYPE_NAMESPACE:
			operation= DataCmdItem.EVAL_NAMESPACE_DATA;
			break;
		case REnvironment.ENVTYPE_NAMESPACE_EXPORTS:
			operation= DataCmdItem.EVAL_NAMESPACE_EXPORTS_DATA;
			break;
		default:
			throw new IllegalArgumentException("envType= " + envType);
		}
		
		final byte checkedDepth= (depth < Byte.MAX_VALUE) ? (byte) depth : Byte.MAX_VALUE;
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(operation,
					options, checkedDepth,
					name, null, null, null, factoryId )), monitor );
			
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			return ((DataCmdItem) this.dataAnswer[level]).getData();
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public final void assignData(final String expression, final RObject data, final @Nullable RObject envir,
			final IProgressMonitor monitor) throws CoreException {
		if (expression == null) {
			throw new NullPointerException("expression");
		}
		if (data == null) {
			throw new NullPointerException("data");
		}
		if (envir != null && !isValidEnvRef(envir)) {
			throw new IllegalArgumentException("envir");
		}
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.ASSIGN_DATA,
					0, null, data, expression, envir )), monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Assignment failed: " + status.getMessage(), null));
				}
			}
			return;
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public final void assignData(final String name, final RObject args, final String expression,
			final @Nullable RObject envir,
			final IProgressMonitor monitor) throws CoreException {
		if (name == null) {
			throw new NullPointerException("name");
		}
		if (args == null) {
			throw new NullPointerException("args");
		}
		if (expression == null) {
			throw new NullPointerException("expression");
		}
		if (envir != null && !isValidEnvRef(envir)) {
			throw new IllegalArgumentException("envir");
		}
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.ASSIGN_FCALL,
					0, name, args, expression, envir )), monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Assignment failed: " + status.getMessage(), null));
				}
			}
			return;
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public RObject[] findData(final String symbol, final RObject env, final boolean inherits,
			final @Nullable String factoryId, final int options, final int depth,
			final IProgressMonitor monitor) throws CoreException {
		if (symbol == null) {
			throw new NullPointerException("symbol");
		}
		final byte checkedDepth= (depth < Byte.MAX_VALUE) ? (byte) depth : Byte.MAX_VALUE;
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new DataCmdItem(DataCmdItem.FIND_DATA,
					(inherits) ? (options | 0x1000) : options, checkedDepth,
					symbol, null, null, env, factoryId )), monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Evaluation failed: " + status.getMessage(), null));
				}
			}
			final DataCmdItem dataItem= (DataCmdItem) this.dataAnswer[level];
			return (dataItem.getRho() != null) ?
					new RObject[] { dataItem.getData(), dataItem.getRho() } :
					null;
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	
	public void downloadFile(final OutputStream out, final String fileName, final int options, final IProgressMonitor monitor) throws CoreException {
		final BinExchange request= new BinExchange(out, fileName, this.rjConsoleEngine, options);
		final BinExchange answer;
		try {
			answer= (BinExchange) runAsync(request);
		}
		finally {
			request.clear();
		}
		if (answer == null || !answer.isOK()) {
			final RjsStatus status= (answer != null) ? answer.getStatus() : MISSING_ANSWER_STATUS;
			if (status.getSeverity() == RjsStatus.CANCEL) {
				throw new CoreException(Status.CANCEL_STATUS);
			}
			else {
				throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
						"Downloading file failed: " + status.getMessage(), null));
			}
		}
	}
	
	public byte[] downloadFile(final String fileName, final int options, final IProgressMonitor monitor) throws CoreException {
		final BinExchange request= new BinExchange(fileName, this.rjConsoleEngine, options);
		final BinExchange answer;
		try {
			answer= (BinExchange) runAsync(request);
		}
		finally {
			request.clear();
		}
		if (answer == null || !answer.isOK()) {
			final RjsStatus status= (answer != null) ? answer.getStatus() : MISSING_ANSWER_STATUS;
			if (status.getSeverity() == RjsStatus.CANCEL) {
				throw new CoreException(Status.CANCEL_STATUS);
			}
			else {
				throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
						"Downloading file failed: " + status.getMessage(), null));
			}
		}
		return answer.getBytes();
	}
	
	public void uploadFile(final InputStream in, final long length, final String fileName, final int options, final IProgressMonitor monitor) throws CoreException {
		final BinExchange request= new BinExchange(in, length, fileName, this.rjConsoleEngine, options);
		final BinExchange answer;
		try {
			answer= (BinExchange) runAsync(request);
		}
		finally {
			request.clear();
		}
		if (answer == null || !answer.isOK()) {
			final RjsStatus status= (answer != null) ? answer.getStatus() : MISSING_ANSWER_STATUS;
			if (status.getSeverity() == RjsStatus.CANCEL) {
				throw new CoreException(Status.CANCEL_STATUS);
			}
			else {
				throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
						"Uploading file failed: " + status.getMessage(), null));
			}
		}
	}
	
	
	public Object execSyncDbgOp(final byte dbgOp, final RJIOExternalizable request,
			final IProgressMonitor monitor) throws CoreException {
		if (this.dbgOpRequest) {
			throw new IllegalStateException();
		}
		this.dbgOpRequest= true;
		try {
			runMainLoop(null, new DbgCmdItem(dbgOp, 0, request), monitor);
			if (this.dbgOpAnswer == null || !this.dbgOpAnswer.isOK()) {
				final RjsStatus status= (this.dbgOpAnswer != null) ? this.dbgOpAnswer.getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Dbg operation failed: " + status.getMessage(), null));
				}
			}
			{	final Object data= this.dbgOpAnswer.getData();
				if (data instanceof CtrlReport) {
					final CtrlReport report= (CtrlReport) data;
					if (!report.isEngineSuspended()) {
						this.consoleReadCallback= null;
					}
				}
				return data;
			}
		}
		finally {
			this.dbgOpRequest= false;
			this.dbgOpAnswer= null;
		}
	}
	
	public void execAsyncDbgOp(final byte op, final RJIOExternalizable request)
			throws CoreException {
		execAsync(new Runnable() {
			@Override
			public void run() {
				try {
					runAsync(new DbgCmdItem(op, 0, request));
					// in future check returned status if required
				}
				catch (final CoreException e) {
					log(new Status(IStatus.ERROR, RJ_CLIENT_ID, -1,
							"An error occurred when executing background dbg operation.", e));
				}
			}
		});
	}
	
	
	public int getGraphicOptions() {
		return this.currentGraphicOptions;
	}
	
	public void setGraphicOptions(final int options) {
		this.currentGraphicOptions= options;
		this.lastGraphic= null;
	}
	
	public RClientGraphic getLastGraphic() {
		return this.lastGraphic;
	}
	
	public Object execSyncGraphicOp(final int devId, final byte op,
			final IProgressMonitor monitor) throws CoreException {
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new GraOpCmdItem(devId, op)),
					monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Graphics operation failed: " + status.getMessage(), null));
				}
			}
			return ((GraOpCmdItem) this.dataAnswer[level]).getData();
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	public Object execSyncGraphicOp(final int devId, final byte op, final RJIOExternalizable data,
			final IProgressMonitor monitor) throws CoreException {
		final int level= newDataLevel();
		try {
			runMainLoop(null, createDataRequestId(level, new GraOpCmdItem(devId, op, data)),
					monitor );
			if (this.dataAnswer[level] == null || !this.dataAnswer[level].isOK()) {
				final RjsStatus status= (this.dataAnswer[level] != null) ? this.dataAnswer[level].getStatus() : MISSING_ANSWER_STATUS;
				if (status.getSeverity() == RjsStatus.CANCEL) {
					throw new CoreException(Status.CANCEL_STATUS);
				}
				else {
					throw new CoreException(new Status(status.getSeverity(), RJ_CLIENT_ID, status.getCode(),
							"Graphics operation failed: " + status.getMessage(), null));
				}
			}
			return ((GraOpCmdItem) this.dataAnswer[level]).getData();
		}
		finally {
			finalizeDataLevel();
		}
	}
	
	
	public void addCancelHandler(final Callable<Boolean> handler) {
		synchronized (this.cancelHandler) {
			this.cancelHandler.add(handler);
		}
	}
	
	public void removeCancelHandler(final Callable<Boolean> handler) {
		synchronized (this.cancelHandler) {
			final int idx= this.cancelHandler.lastIndexOf(handler);
			if (idx >= 0) {
				this.cancelHandler.remove(idx);
			}
		}
	}
	
	protected Callable<Boolean>[] getCancelHandlers() {
		synchronized (this.cancelHandler) {
			return this.cancelHandler.toArray(new Callable[this.cancelHandler.size()]);
		}
	}
	
	public Lock getWaitLock() {
		return this.clientWaitLock;
	}
	
	public void waitingForUser() {
		if (this.hotModeRequested.get()) {
			this.clientWaitLock.unlock();
			try {
				startHotMode();
			}
			finally {
				this.clientWaitLock.lock();
			}
			return;
		}
		
		try {
			this.clientWaitCondition.awaitNanos(1000 * 100);
		}
		catch (final InterruptedException e1) {
		}
	}
	
	public void resume() {
		this.clientWaitCondition.signal();
	}
	
}
