/*=============================================================================#
 # Copyright (c) 2008, 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.r.nico.impl;

import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_ADDRESS_DATA_KEY;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_CALLBACKS_DATA_KEY;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_MESSAGE_DATA_KEY;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_OK_EVENT_ID;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_REQUEST_EVENT_ID;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_USERNAME_DATA_KEY;

import java.io.InputStream;
import java.io.OutputStream;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.Lock;

import javax.security.auth.callback.Callback;
import javax.security.auth.login.LoginException;

import com.ibm.icu.text.DateFormat;

import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.SystemUtils;
import org.eclipse.statet.jcommons.rmi.RMIAddress;
import org.eclipse.statet.jcommons.status.CancelStatus;
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.Statuses;
import org.eclipse.statet.jcommons.status.eplatform.EStatusUtils;
import org.eclipse.statet.jcommons.ts.core.ToolCommandHandler;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;
import org.eclipse.statet.jcommons.ts.core.ToolService;

import org.eclipse.statet.ecommons.io.FileUtil;

import org.eclipse.statet.internal.r.console.core.RConsoleCorePlugin;
import org.eclipse.statet.internal.r.nico.RNicoMessages;
import org.eclipse.statet.internal.r.rdata.BasicCombinedRElement;
import org.eclipse.statet.internal.r.rdata.CombinedFactory;
import org.eclipse.statet.internal.r.rdata.REnvironmentVar;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.nico.core.runtime.ConsoleRunnable;
import org.eclipse.statet.nico.core.runtime.IRemoteEngineController;
import org.eclipse.statet.nico.core.runtime.SubmitType;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.core.runtime.ToolStreamProxy;
import org.eclipse.statet.nico.core.util.TrackingConfiguration;
import org.eclipse.statet.r.console.core.IRBasicAdapter;
import org.eclipse.statet.r.console.core.IRDataAdapter;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.console.core.RDbg;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.RWorkspace;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RLangSourceElement;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelManager;
import org.eclipse.statet.r.core.model.RSourceUnitModelInfo;
import org.eclipse.statet.r.core.model.RWorkspaceSourceUnit;
import org.eclipse.statet.r.core.rsource.ast.FDef;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.rsource.ast.RAsts;
import org.eclipse.statet.r.core.tool.IRConsoleService;
import org.eclipse.statet.r.nico.AbstractRDbgController;
import org.eclipse.statet.r.nico.ICombinedRDataAdapter;
import org.eclipse.statet.r.nico.IRModelSrcref;
import org.eclipse.statet.r.nico.IRSrcref;
import org.eclipse.statet.r.nico.RWorkspaceConfig;
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.data.RDataJConverter;
import org.eclipse.statet.rj.data.REnvironment;
import org.eclipse.statet.rj.data.RLanguage;
import org.eclipse.statet.rj.data.RList;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RObjectFactory;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.data.impl.DefaultRObjectFactory;
import org.eclipse.statet.rj.data.impl.RLanguageImpl;
import org.eclipse.statet.rj.eclient.graphics.comclient.ERClientGraphicActions;
import org.eclipse.statet.rj.server.ConsoleWriteCmdItem;
import org.eclipse.statet.rj.server.DbgCmdItem;
import org.eclipse.statet.rj.server.FxCallback;
import org.eclipse.statet.rj.server.REngine;
import org.eclipse.statet.rj.server.RjsComConfig;
import org.eclipse.statet.rj.server.RjsStatus;
import org.eclipse.statet.rj.server.Server;
import org.eclipse.statet.rj.server.ServerInfo;
import org.eclipse.statet.rj.server.ServerLogin;
import org.eclipse.statet.rj.server.client.AbstractRJComClient;
import org.eclipse.statet.rj.server.client.FunctionCallImpl;
import org.eclipse.statet.rj.server.client.RClientGraphicFactory;
import org.eclipse.statet.rj.server.client.RGraphicCreatorImpl;
import org.eclipse.statet.rj.server.dbg.CallStack;
import org.eclipse.statet.rj.server.dbg.CtrlReport;
import org.eclipse.statet.rj.server.dbg.DbgEnablement;
import org.eclipse.statet.rj.server.dbg.DbgFilterState;
import org.eclipse.statet.rj.server.dbg.DbgRequest;
import org.eclipse.statet.rj.server.dbg.ElementTracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.FlagTracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.FrameContext;
import org.eclipse.statet.rj.server.dbg.FrameContextDetailRequest;
import org.eclipse.statet.rj.server.dbg.SetDebugReport;
import org.eclipse.statet.rj.server.dbg.SetDebugRequest;
import org.eclipse.statet.rj.server.dbg.SrcfileData;
import org.eclipse.statet.rj.server.dbg.TracepointEvent;
import org.eclipse.statet.rj.server.dbg.TracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.TracepointStatesUpdate;
import org.eclipse.statet.rj.services.BasicFQRObject;
import org.eclipse.statet.rj.services.FQRObject;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RGraphicCreator;
import org.eclipse.statet.rj.services.RPlatform;
import org.eclipse.statet.rj.services.RServiceControlExtension;
import org.eclipse.statet.rj.ts.core.RTool;


/**
 * Controller for RJ-Server
 */
public class RjsController extends AbstractRDbgController
		implements IRemoteEngineController, IRDataAdapter, ICombinedRDataAdapter, RServiceControlExtension {
	
	
	static {
		RjsComConfig.registerRObjectFactory(CombinedFactory.FACTORY_ID, CombinedFactory.INSTANCE);
	}
	
	public static class RjsConnection {
		
		private final RMIAddress rmiAddress;
		private final Server server;
		
		
		private RjsConnection(final RMIAddress rmiAddress, final Server server) {
			this.rmiAddress= rmiAddress;
			this.server= server;
		}
		
		
		public RMIAddress getRMIAddress() {
			return this.rmiAddress;
		}
		
		public Server getServer() {
			return this.server;
		}
		
	}
	
	
	public static RjsConnection lookup(final Registry registry, final RemoteException registryException,
			final RMIAddress address) throws CoreException {
		if (address == null) {
			throw new NullPointerException();
		}
		
		final int[] clientVersion= AbstractRJComClient.version();
		clientVersion[2]= -1;
		final Server server;
		int[] version;
		try {
			if (registryException != null) {
				throw registryException;
			}
			server= (Server) registry.lookup(address.getName());
			version= server.getVersion();
		}
		catch (final NotBoundException e) {
			throw new CoreException(new org.eclipse.core.runtime.Status(IStatus.ERROR, RConsoleCorePlugin.BUNDLE_ID,
					"The specified R engine is not in the service registry (RMI).", e ));
		}
		catch (final RemoteException e) {
			throw new CoreException(new org.eclipse.core.runtime.Status(IStatus.ERROR, RConsoleCorePlugin.BUNDLE_ID,
					NLS.bind("Cannot access the host/service registry (RMI) at ''{0}''.", address.getRegistryAddress()),
					e ));
		}
		catch (final ClassCastException e) {
			throw new CoreException(new org.eclipse.core.runtime.Status(IStatus.ERROR, RConsoleCorePlugin.BUNDLE_ID,
					NLS.bind("The specified R engine ({0}) is incompatibel to this client ({1}).", RjsUtil.getVersionString(null), RjsUtil.getVersionString(clientVersion)),
					e ));
		}
		if (version.length != 3 || version[0] != clientVersion[0] || version[1] != clientVersion[1]) {
			throw new CoreException(new org.eclipse.core.runtime.Status(IStatus.ERROR, RConsoleCorePlugin.BUNDLE_ID,
					NLS.bind("The specified R engine ({0}) is incompatibel to this client ({1}).", RjsUtil.getVersionString(version), RjsUtil.getVersionString(clientVersion)),
					null ));
		}
		return new RjsConnection(address, server);
	}
	
	
	public static final int RJS_LOCAL= 1 << 0;
	public static final int RJS_SETUP_CONSOLE= 1 << 8;
	
	
	private static final LtkModelElementFilter<RLangSourceElement> TAG_ELEMENT_FILTER= new LtkModelElementFilter<>() {
		@Override
		public boolean include(final RLangSourceElement element) {
			return ((element.getElementType() & RElement.MASK_C1) == RElement.C1_METHOD);
		}
	};
	
	
	private class NicoComClient extends AbstractRJComClient {
		
		
		public NicoComClient() {
		}
		
		
		@Override
		protected void initGraphicFactory() {
			final ToolCommandHandler handler= getCommandHandler(INIT_RGRAPHIC_FACTORY_HANDLER_ID);
			final Map<String, Object> data= new HashMap<>();
			final Status status= executeHandler(INIT_RGRAPHIC_FACTORY_HANDLER_ID, handler, data, null);
			final RClientGraphicFactory factory= (RClientGraphicFactory) data.get("factory"); //$NON-NLS-1$
			if (status != null && status.getSeverity() < Status.ERROR && factory != null) {
				setGraphicFactory(factory, new ERClientGraphicActions(this, getTool()));
			}
		}
		
		@Override
		protected void updateBusy(final boolean isBusy) {
//			try {
				RjsController.this.isBusy= isBusy;
//			}
//			catch (Exception e) {
//			}
		}
		
		@Override
		protected void updatePrompt(final String text, final boolean addToHistory) {
			try {
				RjsController.this.setCurrentPromptL(text, addToHistory);
			}
			catch (final Exception e) {
			}
		}
		
		@Override
		protected void writeConsoleOutput(final byte streamId, final String text) {
			try {
				final ToolStreamProxy streams= getStreams();
				final SubmitType submitType= getCurrentSubmitType();
				
				switch (streamId) {
				case ConsoleWriteCmdItem.R_OUTPUT:
					streams.getOutputStreamMonitor().append(text, submitType, 0);
					return;
				case ConsoleWriteCmdItem.R_ERROR:
					streams.getErrorStreamMonitor().append(text, submitType, 0);
					return;
				default:
					streams.getSystemOutputMonitor().append(text, submitType, 0);
					return;
				}
			}
			catch (final Exception e) {
			}
		}
		
		@Override
		protected void showMessage(final String text) {
			try {
				final ToolStreamProxy streams= getStreams();
				final SubmitType submitType= getCurrentSubmitType();
				
				streams.getInfoStreamMonitor().append(text, submitType, 0);
			}
			catch (final Exception e) {
			}
		}
		
		
		@Override
		protected RList handleUICallback(String commandId, final RList args,
				final ProgressMonitor m) throws Exception {
			// TODO: allow handlers to use RJ data objects
			// TODO: allow handlers to return values
			// TODO: provide extension point for event handlers
			ToolCommandHandler handler= getCommandHandler(commandId);
			if (handler == null && commandId.startsWith("r/")) {
				final String s= commandId.substring(2);
				handler= getCommandHandler(s);
				if (handler != null) {
					commandId= s;
				}
			}
			if (handler != null) {
				final RDataJConverter converter= new RDataJConverter();
				converter.setKeepArray1(false);
				converter.setRObjectFactory(RjsController.this.fRObjectFactory);
				
				final Map<String, Object> javaArgs= new HashMap<>();
				if (args != null) {
					for (int i= 0; i < args.getLength(); i++) {
						javaArgs.put(args.getName(i), converter.toJava(args.get(i)));
					}
				}
				
				final Status status= handler.execute(commandId, RjsController.this, javaArgs, m);
				switch (status.getSeverity()) {
				case Status.OK:
					break;
				default:
					throw new StatusException(status);
				}
				
				Map<String, Object> javaAnswer= null;
				if (commandId.equals("common/chooseFile")) { //$NON-NLS-1$
					javaAnswer= Collections.singletonMap(
							"filename", javaArgs.get("filename") ); //$NON-NLS-1$ //$NON-NLS-2$
				}
				
				if (javaAnswer != null) {
					final RList answer= (RList) converter.toRJ(javaAnswer);
					return answer;
				}
				else {
					return null;
				}
			}
			
			return super.handleUICallback(commandId, args, m);
		}
		
		@Override
		protected void handleDbgEvents(final byte dbgOp, final Object events) {
			if (dbgOp == DbgCmdItem.OP_NOTIFY_TP_EVENTS) {
				handleTracepointEvents((List<TracepointEvent>) events);
			}
			super.handleDbgEvents(dbgOp, events);
		}
		
		@Override
		protected void log(final Status status) {
			RConsoleCorePlugin.log(status);
		}
		
		@Override
		protected void handleServerStatus(final RjsStatus serverStatus,
				final ProgressMonitor m) throws StatusException {
			String specialMessage= null;
			switch (serverStatus.getCode()) {
			case 0:
				return;
			case Server.S_DISCONNECTED:
				RjsController.this.fConnectionState= Server.S_DISCONNECTED;
				//$FALL-THROUGH$
			case Server.S_LOST:
				if (RjsController.this.fConnectionState == Server.S_DISCONNECTED) {
					specialMessage= RNicoMessages.R_Info_Disconnected_message;
					break;
				}
				else if ((RjsController.this.rjsFlags & RJS_LOCAL) == 0) {
					RjsController.this.fConnectionState= Server.S_LOST;
					specialMessage= RNicoMessages.R_Info_ConnectionLost_message;
					break;
				}
				//$FALL-THROUGH$
			case Server.S_STOPPED:
				RjsController.this.fConnectionState= Server.S_STOPPED;
				specialMessage= RNicoMessages.R_Info_Stopped_message;
				break;
			default:
				throw new IllegalStateException();
			}
			
			if (!isClosed()) {
				markAsTerminated();
				setClosed(true);
				handleStatus(new InfoStatus(RConsoleCorePlugin.BUNDLE_ID,
								addTimestampToMessage(specialMessage, System.currentTimeMillis()) ),
						m );
			}
			throw new StatusException(new CancelStatus(RConsoleCorePlugin.BUNDLE_ID, specialMessage));
		}
		
		@Override
		protected void handleStatus(final Status status, final ProgressMonitor m) {
			RjsController.this.handleStatus(status, m);
		}
		
		@Override
		protected void processHotMode() {
			runHotModeLoop();
		}
		
		@Override
		protected void processExtraMode(final int position) {
			runSuspendedLoopL(SUSPENDED_DEEPLEVEL);
		}
		
		@Override
		protected void scheduleConnectionCheck() {
			synchronized (getQueue()) {
				if (getStatusL().isWaiting()) {
					scheduleControllerRunnable(new ControllerSystemRunnable(
							"r/check", "Connection Check") { //$NON-NLS-1$
						
						@Override
						public void run(final ToolService s,
								final ProgressMonitor m) throws StatusException {
							RjsController.this.fRjs.runMainLoopPing(m);
						}
						
					});
				}
			}
		}
		
	}
	
	
	private final RMIAddress address;
	private final String[] rArgs;
	
	private boolean isBusy= true;
	
	private final RjsConnection rjsConnection;
	private final NicoComClient fRjs= new NicoComClient();
	private int fRjsId;
	
	private final int rjsFlags;
	private final Map<String, Object> rjsProperties;
	
	private int fConnectionState;
	
	private final RObjectFactory fRObjectFactory= DefaultRObjectFactory.INSTANCE;
	
	
	/**
	 * 
	 * @param process the R process the controller belongs to
	 * @param address the RMI address
	 * @param connectionInfo the initialization data
	 * @param rjsFlags controller mode flags
	 * @param startup flag to start R (otherwise connect only)
	 * @param rArgs R arguments (required only if startup is <code>true</code>)
	 * @param initialWD
	 */
	public RjsController(final RProcess process,
			final RMIAddress address, final RjsConnection connection, final Map<String, Object> connectionInfo,
			final int rjsFlags, final String[] rArgs,
			final Map<String, Object> rjsProperties, final IFileStore initialWD,
			final RWorkspaceConfig workspaceConfig,
			final List<TrackingConfiguration> trackingConfigurations) {
		super(process, connectionInfo);
		if (address == null || connection == null) {
			throw new IllegalArgumentException();
		}
		this.address= address;
		this.rjsConnection= connection;
		this.rjsFlags= rjsFlags;
		this.rArgs= rArgs;
		this.rjsProperties= (rjsProperties != null) ? rjsProperties : new HashMap<>();
		
		process.registerFeatureSet(RTool.R_SERVICE_FEATURE_ID);
		process.registerFeatureSet(RConsoleTool.R_DATA_FEATURESET_ID);
		if ((this.rjsFlags & RJS_LOCAL) == 0) {
			process.registerFeatureSet(IRemoteEngineController.FEATURE_SET_ID);
		}
		
		setTracksConfig(trackingConfigurations);
		
		setWorksapceData(new RWorkspace(this,
				((this.rjsFlags & RJS_LOCAL) != 0 || address.isLocalHost()) ? null :
						address.getHostAddress().getHostAddress(), workspaceConfig ));
		setWorkspaceDirL(initialWD);
		initRunnableAdapterL();
	}
	
	
	@Override
	public boolean supportsBusy() {
		return true;
	}
	
	@Override
	public boolean isBusy() {
		return this.isBusy;
	}
	
	@Override
	public boolean isDisconnected() {
		return (this.fConnectionState == Server.S_DISCONNECTED || this.fConnectionState == Server.S_LOST);
	}
	
	/**
	 * This is an async operation
	 * cancel is not supported by this implementation
	 * 
	 * @param m a progress monitor
	 */
	@Override
	public void disconnect(final ProgressMonitor m) throws StatusException {
		switch (getStatus()) {
		case STARTED_IDLING:
		case STARTED_SUSPENDED:
		case STARTED_PROCESSING:
		case STARTED_PAUSED:
			m.beginTask("Disconnecting from R remote engine...", 1);
			synchronized (getQueue()) {
				beginInternalTask();
			}
			try {
				this.fRjs.getConsoleEngine().disconnect();
				this.fConnectionState= Server.S_DISCONNECTED;
			}
			catch (final RemoteException e) {
				throw new StatusException(new ErrorStatus(RConsoleCorePlugin.BUNDLE_ID,
						"Disconnecting from R remote engine failed.",
						e ));
			}
			finally {
				synchronized (getQueue()) {
					scheduleControllerRunnable(new ControllerSystemRunnable(
							"common/disconnect/finish", "Disconnect") { //$NON-NLS-1$
						
						@Override
						public void run(final ToolService s,
								final ProgressMonitor m) throws StatusException {
							if (!isTerminated()) {
								RjsController.this.fRjs.runMainLoopPing(m);
								RjsController.this.fRjs.handleServerStatus(new RjsStatus(RjsStatus.INFO, Server.S_DISCONNECTED), m);
							}
						}
						
					});
					endInternalTask();
				}
			}
		}
	}
	
	
	@Override
	protected ToolRunnable createStartRunnable() {
		return new StartRunnable() {
			@Override
			public String getLabel() {
				return "Connect to and load remote R engine.";
			}
		};
	}
	
	@Override
	protected void startToolL(final ProgressMonitor m) throws StatusException {
		this.fRjsId= RjsComConfig.registerClientComHandler(this.fRjs);
		this.fRjs.initClient(getTool(), this, this.rjsProperties, this.fRjsId);
		try {
			final Map<String, Object> data= new HashMap<>();
			final ToolCommandHandler loginHandler= getCommandHandler(LOGIN_REQUEST_EVENT_ID);
			String msg= null;
			boolean connected= false;
			while (!connected) {
				final Map<String, Object> connectionInfo= getTool().getConnectionInfo();
				final ServerLogin login= this.rjsConnection.getServer().createLogin(Server.C_CONSOLE_CONNECT);
				try {
					final Callback[] callbacks= login.getCallbacks();
					if (callbacks != null) {
						final List<Callback> checked= new ArrayList<>();
						FxCallback fx= null;
						for (final Callback callback : callbacks) {
							if (callback instanceof FxCallback) {
								fx= (FxCallback) callback;
							}
							else {
								checked.add(callback);
							}
						}
						
						if (connectionInfo != null) {
							data.putAll(connectionInfo);
						}
						data.put(LOGIN_ADDRESS_DATA_KEY, (fx != null) ? this.address.getHost() : this.address.getAddress());
						data.put(LOGIN_MESSAGE_DATA_KEY, msg);
						data.put(LOGIN_CALLBACKS_DATA_KEY, checked.toArray(new Callback[checked.size()]));
						
						if (loginHandler == null) {
							throw new StatusException(new ErrorStatus(RConsoleCorePlugin.BUNDLE_ID,
									"Login requested but not supported by this configuration." ));
						}
						if (loginHandler.execute(LOGIN_REQUEST_EVENT_ID, this, data, m).getSeverity() != Status.OK) {
							throw new StatusException(Statuses.CANCEL_STATUS);
						}
						
						if (fx != null) {
							RjsUtil.handleFxCallback(
									RjsUtil.getSession(data, m.newSubMonitor(1)),
									fx, m.newSubMonitor(1) );
						}
					}
					
					msg= null;
					m.checkCanceled();
					
					final Map<String, Object> args= new HashMap<>();
					args.putAll(this.rjsProperties);
					REngine rjServer;
					if ((this.rjsFlags & RJS_SETUP_CONSOLE) != 0) {
						args.put("args", this.rArgs); //$NON-NLS-1$
						rjServer= (REngine) this.rjsConnection.getServer().execute(Server.C_CONSOLE_START, args, login.createAnswer());
					}
					else {
						rjServer= (REngine) this.rjsConnection.getServer().execute(Server.C_CONSOLE_CONNECT, args, login.createAnswer());
					}
					this.fRjs.setServer(rjServer, 0);
					connected= true;
					
					if (callbacks != null) {
						loginHandler.execute(LOGIN_OK_EVENT_ID, this, data, m);
						if (connectionInfo != null) {
							connectionInfo.put(LOGIN_USERNAME_DATA_KEY, data.get(LOGIN_USERNAME_DATA_KEY));
						}
					}
				}
				catch (final LoginException e) {
					msg= e.getLocalizedMessage();
				}
				finally {
					if (login != null) {
						login.clearData();
					}
				}
			}
			
			final ServerInfo info= this.rjsConnection.getServer().getInfo();
			if (getWorkspaceData().isRemote()) {
				try {
					final String wd= FileUtil.toString(getWorkspaceData().toFileStore(info.getDirectory()));
					if (wd != null) {
						setStartupWD(wd);
					}
				}
				catch (final CoreException e) {}
				
				try {
					String sep= this.fRjs.getProperty(SystemUtils.FILE_SEPARATOR_KEY);
					if (sep == null) {
						final String osName= this.fRjs.getProperty(SystemUtils.OS_NAME_KEY);
						if (osName != null && SystemUtils.getOs(osName) == SystemUtils.OS_WIN) {
							sep= "\\"; //$NON-NLS-1$
						}
					}
					if (sep != null && !sep.isEmpty()) {
						setFileSeparatorL(sep.charAt(0));
					}
				}
				catch (final Exception e) {}
			}
			else {
				setStartupWD(info.getDirectory());
			}
			final long timestamp= info.getTimestamp();
			if (timestamp != 0) {
				setStartupTimestamp(timestamp);
			}
			
			final List<Status> warnings= new ArrayList<>();
			
			initTracks(m.newSubMonitor(1), warnings);
			
			if ((this.rjsFlags & RJS_SETUP_CONSOLE) != 0 && !this.startupsRunnables.isEmpty()) {
				getQueue().add(this.startupsRunnables);
				this.startupsRunnables.clear();
			}
			
			if ((this.rjsFlags & RJS_SETUP_CONSOLE) == 0) {
				handleStatus(new InfoStatus(RConsoleCorePlugin.BUNDLE_ID,
						addTimestampToMessage(RNicoMessages.R_Info_Reconnected_message, getTool().getConnectionTimestamp()) ),
						m);
			}
			// fRjs.runMainLoop(null, null, monitor); must not wait at server side
			this.fRjs.activateConsole();
			class RStart2Runnable extends ControllerSystemRunnable implements ConsoleRunnable {
				RStart2Runnable() {
					super("r/rj/start2", "Finish Initialization / Read Output"); //$NON-NLS-1$
				}
				
				@Override
				public SubmitType getSubmitType() {
					return SubmitType.CONSOLE;
				}
				
				@Override
				public void run(final ToolService s,
						final ProgressMonitor m) throws StatusException {
					if (!RjsController.this.fRjs.isConsoleReady()) { // R is still working
						RjsController.this.fRjs.runMainLoop(null, null, m);
						
						briefChanged(IRConsoleService.AUTO_CHANGE);
					}
					for (final Status status : warnings) {
						handleStatus(status, m);
					}
				}
				
			}
			scheduleControllerRunnable(new RStart2Runnable());
		}
		catch (final RemoteException e) {
			throw new StatusException(new ErrorStatus(RConsoleCorePlugin.BUNDLE_ID,
					"The R engine could not be started.", e ));
		}
		catch (final RjException e) {
			throw new StatusException(new ErrorStatus(RConsoleCorePlugin.BUNDLE_ID,
					"An error occured when creating login data.", e ));
		}
	}
	
//	public void controlNotification(final RjsComObject com) throws RemoteException {
//		if (com instanceof RjsStatus) {
//			final RjsStatusImpl2 serverStatus= (RjsStatusImpl2) com;
//			if (serverStatus.getCode() == Server.S_DISCONNECTED || serverStatus.getCode() == Server.S_STOPPED) {
//				scheduleControllerRunnable(new IToolRunnable() {
//					public String getTypeId() {
//						return null;
//					}
//					public String getLabel() {
//						return "Update State";
//					}
//					public SubmitType getSubmitType() {
//						return SubmitType.OTHER;
//					}
//					public void changed(final int event, final ToolProcess process) {
//					}
//					public void run(final IToolRunnableControllerAdapter tools, final ProgressMonitor m)
//							throws InterruptedException, CoreException {
//						if (!isTerminated()) {
//							rjsHandleStatus(serverStatus, monitor);
//						}
//					}
//					
//				});
//			}
//		}
//	}
	
	
	protected String addTimestampToMessage(final String message, final long timestamp) {
		final String datetime= DateFormat.getDateTimeInstance().format(System.currentTimeMillis());
		return datetime + " - " + message; //$NON-NLS-1$
	}
	
	@Override
	protected void requestHotMode(final boolean async) {
		this.fRjs.requestHotMode(async);
	}
	
	@Override
	protected boolean initilizeHotMode() {
		return this.fRjs.startHotMode();
	}
	
	@Override
	protected void onHotModeExit(final ProgressMonitor m) {
		super.onHotModeExit(m);
		try {
			this.fRjs.finishTask(m);
		}
		catch (final Throwable e) {}
	}
	
	@Override
	protected void onTaskFinished(final RunnableData runnableData, final int event,
			final ProgressMonitor m) {
		try {
			this.fRjs.finishTask(m);
		}
		catch (final Throwable e) {}
		
		super.onTaskFinished(runnableData, event, m);
	}
	
	
	@Override
	protected int setSuspended(final int level, final int enterDetail, final Object enterData) {
		final int diff= super.setSuspended(level, enterDetail, enterData);
		if (level > 0 && diff > 0) {
			this.fRjs.requestExtraMode(
					(AbstractRJComClient.EXTRA_BEFORE | AbstractRJComClient.EXTRA_NESTED) );
		}
		return diff;
	}
	
	@Override
	protected CallStack doEvalCallStack(final ProgressMonitor m) throws StatusException {
		return (CallStack) this.fRjs.execSyncDbgOp(DbgCmdItem.OP_LOAD_FRAME_LIST,
				null, m );
	}
	
	@Override
	protected FrameContext doEvalFrameContext(final int position,
			final ProgressMonitor m) throws Exception {
		return (FrameContext) this.fRjs.execSyncDbgOp(DbgCmdItem.OP_LOAD_FRAME_CONTEXT,
				new FrameContextDetailRequest(position), m );
	}
	
	
	@Override
	protected void interruptTool() throws UnsupportedOperationException {
		this.fRjs.runAsyncInterrupt();
	}
	
	@Override
	protected void postCancelTask(final int options,
			final ProgressMonitor m) throws StatusException {
		super.postCancelTask(options, m);
		if (this.fRjs.isConsoleReady()) {
			this.fCurrentInput= ""; //$NON-NLS-1$
			doSubmitL(m);
			this.fCurrentInput= ""; //$NON-NLS-1$
			doSubmitL(m);
		}
		else {
			// reschedule?
		}
	}
	
	@Override
	protected boolean isToolAlive() {
		if (this.fConnectionState != 0 || !this.fRjs.runAsyncPing()) {
			return false;
		}
		if (Thread.currentThread() == getControllerThread() && !isInHotModeL()
				&& !this.fRjs.isConsoleReady()) {
			return false;
		}
		return true;
	}
	
	@Override
	protected void killTool(final ProgressMonitor m) {
		this.fRjs.setClosed(true);
		final ToolProcess consoleProcess= getTool();
		// TODO: kill remote command?
		final IProcess[] processes= consoleProcess.getLaunch().getProcesses();
		for (int i= 0; i < processes.length; i++) {
			if (processes[i] != consoleProcess && !processes[i].isTerminated()) {
				try {
					processes[i].terminate();
				}
				catch (final Exception e) {
				}
			}
		}
	}
	
	@Override
	protected void clear() {
		this.fRjs.setClosed(true);
		
		super.clear();
		
		if ((this.rjsFlags & RJS_LOCAL) != 0 && !isDisconnected()) {
			try {
				Naming.unbind(this.address.getAddress());
			}
			catch (final Throwable e) {
			}
		}
		this.fRjs.disposeAllGraphics();
		if (this.fRjsId > 0) {
			RjsComConfig.unregisterClientComHandler(this.fRjsId);
			this.fRjsId= 0;
		}
	}
	
	@Override
	protected int finishToolL() {
		int exitCode= 0;
		if (isDisconnected()) {
			exitCode= ToolProcess.EXITCODE_DISCONNECTED;
		}
		return exitCode;
	}
	
	@Override
	protected boolean canSuspend(final ProgressMonitor m) {
		return (this.fRjs.getDataLevel() == 0);
	}
	
	@Override
	protected void doRequestSuspend(final ProgressMonitor m) throws StatusException {
		this.fRjs.execSyncDbgOp(DbgCmdItem.OP_REQUEST_SUSPEND,
				null, m );
	}
	
	@Override
	protected SetDebugReport doExec(final SetDebugRequest request,
			final ProgressMonitor m) throws StatusException {
		return (SetDebugReport) this.fRjs.execSyncDbgOp(DbgCmdItem.OP_SET_DEBUG, request, m);
	}
	
	@Override
	protected CtrlReport doExec(final DbgRequest request,
			final ProgressMonitor m) throws StatusException {
		return (CtrlReport) this.fRjs.execSyncDbgOp(request.getOp(), request, m);
	}
	
	@Override
	protected void doPrepareSrcfile(final String srcfile, final String statetPath,
			final ProgressMonitor m) throws StatusException {
		final FunctionCall prepare= createFunctionCall("rj:::.statet.prepareSrcfile");
		prepare.addChar("filename", srcfile);
		prepare.addChar("path", statetPath);
		prepare.evalVoid(m);
	}
	
	@Override
	public void exec(final TracepointInstallationRequest request,
			final ProgressMonitor m) throws StatusException {
		if (request instanceof FlagTracepointInstallationRequest) {
			this.fRjs.execSyncDbgOp(DbgCmdItem.OP_INSTALL_TP_FLAGS, request, m);
		}
		else if (request instanceof ElementTracepointInstallationRequest) {
			this.fRjs.execSyncDbgOp(DbgCmdItem.OP_INSTALL_TP_POSITIONS, request, m);
		}
		else {
			throw new IllegalArgumentException("request type not supported");
		}
	}
	
	@Override
	public void exec(final DbgEnablement request) throws StatusException {
		this.fRjs.execAsyncDbgOp(DbgCmdItem.OP_SET_ENABLEMENT, request);
	}
	
	@Override
	public void exec(final DbgFilterState request) throws StatusException {
		this.fRjs.execAsyncDbgOp(DbgCmdItem.OP_RESET_FILTER_STATE, request);
	}
	
	@Override
	public void exec(final TracepointStatesUpdate request) throws StatusException {
		this.fRjs.execAsyncDbgOp(DbgCmdItem.OP_UPDATE_TP_STATES, request);
	}
	
	@Override
	public void exec(final TracepointStatesUpdate request,
			final ProgressMonitor m) throws StatusException {
		this.fRjs.execSyncDbgOp(DbgCmdItem.OP_UPDATE_TP_STATES, request, m);
	}
	
	
	@Override
	protected void doSubmitCommandL(final String[] lines, final SrcfileData srcfile,
			final IRSrcref srcref,
			final ProgressMonitor m) throws StatusException {
		if ((this.fCurrentPrompt.meta & (IRBasicAdapter.META_PROMPT_DEFAULT | IRBasicAdapter.META_PROMPT_SUSPENDED)) == 0) {
			super.doSubmitCommandL(lines, srcfile, srcref, m);
			return;
		}
		
		final FunctionCall prepare= createFunctionCall("rj:::.statet.prepareCommand");
		prepare.add("lines", this.fRObjectFactory.createVector(this.fRObjectFactory.createCharData(lines)));
		
		if (srcfile != null && srcref != null && srcref.getFirstLine() >= 0) {
			final List<String> attributeNames= new ArrayList<>();
			final List<RObject> attributeValues= new ArrayList<>();
			
			if (srcfile.getName() != null) {
				prepare.addChar("filename", srcfile.getName());
			}
//			if (srcfile.workspacePath != null) {
//				attributeNames.add("statet.Path");
//				attributeValues.add(fRObjectFactory.createVector(fRObjectFactory.createCharData(
//						new String[] { srcfile.workspacePath } )));
//			}
			if (srcfile.getTimestamp() != 0) {
				attributeNames.add("timestamp");
				attributeValues.add(this.fRObjectFactory.createVector(this.fRObjectFactory.createNumData(
						new double[] { srcfile.getTimestamp() } )));
			}
			attributeNames.add("linesSrcref");
			attributeValues.add(this.fRObjectFactory.createVector(this.fRObjectFactory.createIntData(
					RDbg.createRJSrcref(srcref) )));
			
			if (attributeNames.size() > 0) {
				prepare.add("srcfileAttributes", this.fRObjectFactory.createList(
						attributeValues.toArray(new RObject[attributeValues.size()]),
						attributeNames.toArray(new String[attributeNames.size()]) ));
			}
			
			if (srcref instanceof IRModelSrcref) {
				// Move to abstract controller or breakpoint adapter?
				final IRModelSrcref modelSrcref= (IRModelSrcref) srcref;
				final List<RLangSourceElement> elements= modelSrcref.getElements();
				if (elements.size() > 0) {
					final List<String> elementIds= new ArrayList<>(elements.size());
					final List<RObject> elementIndexes= new ArrayList<>(elements.size());
					for (final RLangSourceElement element : elements) {
						if (RjsController.TAG_ELEMENT_FILTER.include(element)) {
							final FDef fdef= element.getAdapter(FDef.class);
							if (fdef != null) {
								final String elementId= RDbg.getElementId(element);
								final RAstNode cont= fdef.getContChild();
								final int[] path= RAsts.computeRExpressionIndex(cont,
										RAsts.getRRootNode(cont, modelSrcref) );
								if (elementId != null && path != null) {
									final int[] fullPath= new int[path.length+1];
									fullPath[0]= 1;
									System.arraycopy(path, 0, fullPath, 1, path.length);
									elementIds.add(elementId);
									elementIndexes.add(this.fRObjectFactory.createVector(
											this.fRObjectFactory.createIntData(fullPath)));
								}
							}
						}
					}
					if (elementIds.size() > 0) {
						prepare.add("elementIds", this.fRObjectFactory.createList(
								elementIndexes.toArray(new RObject[elementIndexes.size()]),
								elementIds.toArray(new String[elementIds.size()]) ));
					}
				}
			}
		}
		
		prepare.evalVoid(m);
		
		final boolean addToHistory= (this.fCurrentPrompt.meta & IRBasicAdapter.META_HISTORY_DONTADD) == 0;
		this.fCurrentInput= lines[0];
		doBeforeSubmitL();
		for (int i= 1; i < lines.length; i++) {
			setCurrentPromptL(this.continuePromptText, addToHistory);
			this.fCurrentInput= lines[i];
			doBeforeSubmitL();
		}
		this.fCurrentInput= "rj:::.statet.evalCommand()";
		doSubmitL(m);
	}
	
	@Override
	public void doSubmitFileCommandToConsole(final String[] lines,
			final SrcfileData srcfile, final SourceUnit su,
			final ProgressMonitor m) throws StatusException {
		if (srcfile != null && su instanceof RWorkspaceSourceUnit
				&& su.getModelTypeId() == RModel.R_TYPE_ID) {
			try {
				final RSourceUnitModelInfo modelInfo= (RSourceUnitModelInfo) su.getModelInfo(RModel.R_TYPE_ID,
						RModelManager.MODEL_FILE, EStatusUtils.convert(m.newSubMonitor(0)) );
				if (modelInfo != null) {
					final RLangSourceElement fileElement= modelInfo.getSourceElement();
					final RAstNode rootNode= (RAstNode) fileElement.getAdapter(AstNode.class);
					final List<? extends RLangSourceElement> elements= modelInfo.getSourceElement()
							.getSourceChildren(RjsController.TAG_ELEMENT_FILTER);
					
					final List<String> elementIds= new ArrayList<>(elements.size());
					final List<RObject> elementIndexes= new ArrayList<>(elements.size());
					
					for (final RLangSourceElement element : elements) {
						final FDef fdef= element.getAdapter(FDef.class);
						if (fdef != null) {
							final String elementId= RDbg.getElementId(element);
							final RAstNode cont= fdef.getContChild();
							final int[] path= RAsts.computeRExpressionIndex(cont, rootNode);
							if (elementId != null && path != null) {
								elementIds.add(elementId);
								elementIndexes.add(this.fRObjectFactory.createVector(
										this.fRObjectFactory.createIntData(path)));
							}
						}
					}
					
					final FunctionCall prepare= createFunctionCall("rj:::.statet.prepareSource"); //$NON-NLS-1$
					prepare.add(this.fRObjectFactory.createList(new RObject[] {
							this.fRObjectFactory.createVector(this.fRObjectFactory.createCharData(
									new String[] { srcfile.getPath() })),
							this.fRObjectFactory.createVector(this.fRObjectFactory.createNumData(
									new double[] { srcfile.getTimestamp() })),
							this.fRObjectFactory.createVector(this.fRObjectFactory.createIntData(
									new int[] { rootNode.getChildCount() })),
							this.fRObjectFactory.createList(
									elementIndexes.toArray(new RObject[elementIndexes.size()]),
									elementIds.toArray(new String[elementIds.size()]) ),
					}, new String[] { "path", "timestamp", "exprsLength", "elementIds" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
					prepare.evalVoid(m);
				}
			}
			catch (final StatusException e) {
				RConsoleCorePlugin.logError(NLS.bind(
								"An error occurred when preparing element tagging for file ''{0}''.",
								srcfile.getPath() ),
						e );
			}
		}
		super.doSubmitFileCommandToConsole(lines, srcfile, su, m);
	}
	
	@Override
	protected void doSubmitL(final ProgressMonitor m) throws StatusException {
		this.fRjs.answerConsole(this.fCurrentInput + this.fLineSeparator, m);
	}
	
	
	@Override
	public String getProperty(final String key) {
		return this.fRjs.getProperty(key);
	}
	
	@Override
	public RPlatform getPlatform() {
		return this.fRjs.getRPlatform();
	}
	
	@Override
	public void evalVoid(final String command,
			final ProgressMonitor m) throws StatusException {
		this.fRjs.evalVoid(command, null,
				m );
	}
	
	@Override
	public void evalVoid(final String command, final @Nullable RObject envir,
			final ProgressMonitor m) throws StatusException {
		this.fRjs.evalVoid(command, envir,
				m );
	}
	
	@Override
	public RObject evalData(final String command,
			final ProgressMonitor m) throws StatusException {
		return this.fRjs.evalData(command, null,
				null, 0, -1, m );
	}
	
	@Override
	public RObject evalData(final String command, final @Nullable String factoryId,
			final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		return this.fRjs.evalData(command, null,
				factoryId, options, depth, m );
	}
	
	@Override
	public RObject evalData(final String command, final @Nullable RObject envir,
			final @Nullable String factoryId, final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		return this.fRjs.evalData(command, envir,
				factoryId, options, depth, m );
	}
	
	@Override
	public RObject evalData(final RReference reference,
			final ProgressMonitor m) throws StatusException {
		return this.fRjs.evalData(reference, null, 0, -1,
				m );
	}
	
	@Override
	public RObject evalData(final RReference reference,
			final @Nullable String factoryId, final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		return this.fRjs.evalData(reference,
				factoryId, options, depth, m );
	}
	
	@Override
	public FQRObject<RProcess> findData(final String symbol, final @Nullable RObject env, final boolean inherits,
			final @Nullable String factoryId, final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		final RObject[] data= this.fRjs.findData(symbol, env, inherits,
				factoryId, options, depth, m );
		if (data != null) {
			return new BasicFQRObject<>(getTool(), (REnvironment) data[1], symbol, data[0]);
		}
		return null;
	}
	
	
	private BasicCombinedRElement checkCombinedRElement(final @Nullable RObject data,
			final int options, final @Nullable RElementName name) {
		if (data instanceof BasicCombinedRElement) {
			final BasicCombinedRElement e= (BasicCombinedRElement) data;
			if (e.getRObjectType() == RObject.TYPE_ENVIRONMENT) {
				((REnvironmentVar) e).setSource(getTool(), getChangeStamp(), options);
			}
			if (name != null) {
				e.setElementName(name);
			}
			return e;
		}
		return null;
	}
	
	@Override
	public CombinedRElement evalCombinedStruct(final String command,
			final int options, final int depth, final @Nullable RElementName name,
			final ProgressMonitor m) throws StatusException {
		final RObject data= this.fRjs.evalData(command, null,
				CombinedFactory.FACTORY_ID, (options | RObjectFactory.F_ONLY_STRUCT), depth,
				m );
		return checkCombinedRElement(data, options, name);
	}
	
	@Override
	public CombinedRElement evalCombinedStruct(final String command, final @Nullable RObject envir,
			final int options, final int depth, final @Nullable RElementName name,
			final ProgressMonitor m) throws StatusException {
		final RObject data= this.fRjs.evalData(command, envir,
				CombinedFactory.FACTORY_ID, (options | RObjectFactory.F_ONLY_STRUCT), depth,
				m );
		return checkCombinedRElement(data, options, name);
	}
	
	private CombinedRElement evalCombinedStructSpecialEnv(final RElementName name,
			final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		final byte envType;
		switch (name.getType()) {
		case RElementName.SCOPE_NS:
			envType= REnvironment.ENVTYPE_NAMESPACE_EXPORTS;
			break;
		case RElementName.SCOPE_NS_INT:
			envType= REnvironment.ENVTYPE_NAMESPACE;
			break;
		default:
			throw new IllegalArgumentException();
		}
		final RObject data= this.fRjs.evalData(envType, name.getSegmentName(),
				CombinedFactory.FACTORY_ID, (options | RObjectFactory.F_ONLY_STRUCT), depth,
				m );
		return checkCombinedRElement(data, options, name);
	}
	
	@Override
	public CombinedRElement evalCombinedStruct(final RElementName name,
			final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		switch (name.getType()) {
		case RElementName.SCOPE_NS:
		case RElementName.SCOPE_NS_INT:
			if (name.getNextSegment() == null) {
				return evalCombinedStructSpecialEnv(name, options, depth, m);
			}
			break;
		default:
			break;
		}
		
		final String command= name.getDisplayName(RElementName.DISPLAY_FQN | RElementName.DISPLAY_EXACT);
		if (command == null) {
			throw new StatusException(new ErrorStatus(RConsoleCorePlugin.BUNDLE_ID, "Illegal R element name."));
		}
		return evalCombinedStruct(command, options, depth, name, m);
	}
	
	@Override
	public CombinedRElement evalCombinedStruct(final RReference reference,
			final int options, final int depth, final @Nullable RElementName name,
			final ProgressMonitor m) throws StatusException {
		final RObject data= evalData(reference,
				CombinedFactory.FACTORY_ID, (options | RObjectFactory.F_ONLY_STRUCT), depth,
				m );
		return checkCombinedRElement(data, options, name);
	}
	
	private boolean isValidSymbol(final RElementName name) {
		return (name.getType() == RElementName.MAIN_DEFAULT && name.getSegmentName() != null
				&& name.getNextSegment() == null );
	}
	
	private RLanguage createLangObject(final RElementName name, final String arg) {
		final String expr= name.getDisplayName(RElementName.DISPLAY_FQN | RElementName.DISPLAY_EXACT);
		if (expr == null) {
			throw new IllegalArgumentException(arg);
		}
		return new RLanguageImpl(RLanguage.CALL, expr, null);
	}
	
	@Override
	public @Nullable CombinedRElement findCombinedStruct(final RElementName symbol,
			final @Nullable RObject env, final boolean inherits,
			final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		if (!isValidSymbol(symbol)) {
			throw new IllegalArgumentException("symbol"); //$NON-NLS-1$
		}
		final RObject[] data= this.fRjs.findData(symbol.getSegmentName(), env, inherits,
				CombinedFactory.FACTORY_ID, (options | RObjectFactory.F_ONLY_STRUCT), depth,
				m );
		if (data != null) {
			final BasicCombinedRElement element= checkCombinedRElement(data[0], options, symbol);
			if (element != null) {
				element.setParent(checkCombinedRElement(data[1], options,
						(env instanceof CombinedRElement) ? ((CombinedRElement) env).getElementName() : null ));
				return element;
			}
		}
		return null;
	}
	
	@Override
	public @Nullable CombinedRElement findCombinedStruct(final RElementName symbol,
			final @Nullable RElementName envName, final boolean inherits,
			final int options, final int depth,
			final ProgressMonitor m) throws StatusException {
		if (!isValidSymbol(symbol)) {
			throw new IllegalArgumentException("symbol"); //$NON-NLS-1$
		}
		final RLanguage env= (envName != null) ? createLangObject(envName, "envName") : null;
		final RObject[] data= this.fRjs.findData(symbol.getSegmentName(), env, inherits,
				CombinedFactory.FACTORY_ID, (options | RObjectFactory.F_ONLY_STRUCT), depth,
				m );
		if (data != null) {
			final BasicCombinedRElement element= checkCombinedRElement(data[0], options, symbol);
			if (element != null) {
				element.setParent(checkCombinedRElement(data[1], options, envName));
				return element;
			}
		}
		return null;
	}
	
	@Override
	public void assignData(final String expression, final RObject data,
			final ProgressMonitor m) throws StatusException {
		this.fRjs.assignData(expression, data, null, m);
	}
	
	@Override
	public void downloadFile(final OutputStream out, final String fileName, final int options,
			final ProgressMonitor m) throws StatusException {
		this.fRjs.downloadFile(out, fileName, options, m);
	}
	
	@Override
	public byte[] downloadFile(final String fileName, final int options,
			final ProgressMonitor m) throws StatusException {
		return this.fRjs.downloadFile(fileName, options, m);
	}
	
	@Override
	public void uploadFile(final InputStream in, final long length, final String fileName, final int options,
			final ProgressMonitor m) throws StatusException {
		this.fRjs.uploadFile(in, length, fileName, options, m);
	}
	
	@Override
	public FunctionCall createFunctionCall(final String name) throws StatusException {
		return new FunctionCallImpl(this.fRjs, name, this.fRObjectFactory);
	}
	
	@Override
	public RGraphicCreator createRGraphicCreator(final int options) throws StatusException {
		return new RGraphicCreatorImpl(this, this.fRjs, options);
	}
	
	
	@Override
	public void addCancelHandler(final Callable<Boolean> handler) {
		this.fRjs.addCancelHandler(handler);
	}
	
	@Override
	public void removeCancelHandler(final Callable<Boolean> handler) {
		this.fRjs.removeCancelHandler(handler);
	}
	
	@Override
	public Lock getWaitLock() {
		return this.fRjs.getWaitLock();
	}
	
	@Override
	public void waitingForUser(final ProgressMonitor m) {
		this.fRjs.waitingForUser();
	}
	
	@Override
	public void resume() {
		this.fRjs.resume();
	}
	
}
