/*=============================================================================#
 # Copyright (c) 2010, 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.internal.r.debug.core.breakpoints;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IBreakpointManagerListener;
import org.eclipse.debug.core.IBreakpointsListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.Immutable;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.text.IMarkerPositionResolver;
import org.eclipse.statet.ecommons.ts.core.SystemRunnable;
import org.eclipse.statet.ecommons.ts.core.Tool;
import org.eclipse.statet.ecommons.ts.core.ToolService;

import org.eclipse.statet.internal.r.debug.core.RDebugCorePlugin;
import org.eclipse.statet.ltk.core.LTK;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.nico.core.runtime.Queue;
import org.eclipse.statet.nico.core.runtime.ToolStatus;
import org.eclipse.statet.r.console.core.RDbg;
import org.eclipse.statet.r.console.core.RProcessREnvironment;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.RProjects;
import org.eclipse.statet.r.core.model.IRLangSourceElement;
import org.eclipse.statet.r.core.model.IRModelInfo;
import org.eclipse.statet.r.core.model.IRModelManager;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.IRWorkspaceSourceUnit;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.debug.core.IRDebugTarget;
import org.eclipse.statet.r.debug.core.RDebugModel;
import org.eclipse.statet.r.debug.core.breakpoints.IRBreakpoint;
import org.eclipse.statet.r.debug.core.breakpoints.IRBreakpoint.ITargetData;
import org.eclipse.statet.r.debug.core.breakpoints.IRExceptionBreakpoint;
import org.eclipse.statet.r.debug.core.breakpoints.IRLineBreakpoint;
import org.eclipse.statet.r.debug.core.breakpoints.IRMethodBreakpoint;
import org.eclipse.statet.r.debug.core.breakpoints.RLineBreakpointValidator;
import org.eclipse.statet.r.debug.core.breakpoints.RLineBreakpointValidator.ModelPosition;
import org.eclipse.statet.r.nico.AbstractRDbgController;
import org.eclipse.statet.r.nico.AbstractRDbgController.IRControllerTracepointAdapter;
import org.eclipse.statet.r.nico.IRModelSrcref;
import org.eclipse.statet.r.nico.IRSrcref;
import org.eclipse.statet.r.nico.RSrcref;
import org.eclipse.statet.rj.data.REnvironment;
import org.eclipse.statet.rj.server.dbg.DbgEnablement;
import org.eclipse.statet.rj.server.dbg.ElementTracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.ElementTracepoints;
import org.eclipse.statet.rj.server.dbg.FlagTracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.SrcfileData;
import org.eclipse.statet.rj.server.dbg.Srcref;
import org.eclipse.statet.rj.server.dbg.Tracepoint;
import org.eclipse.statet.rj.server.dbg.TracepointEvent;
import org.eclipse.statet.rj.server.dbg.TracepointPosition;
import org.eclipse.statet.rj.server.dbg.TracepointState;
import org.eclipse.statet.rj.server.dbg.TracepointStatesUpdate;


@NonNullByDefault
public class RControllerBreakpointAdapter implements IRControllerTracepointAdapter,
		IBreakpointManagerListener, IBreakpointsListener {
	
	private static class Position extends TracepointPosition {
		
		private final IRLineBreakpoint breakpoint;
		
		private @Nullable String label;
		
		public Position(final int type, final long id, final int[] exprIndex,
				final IRLineBreakpoint breakpoint) {
			super(type, id, exprIndex);
			this.breakpoint= breakpoint;
		}
		
		public IRLineBreakpoint getBreakpoint() {
			return this.breakpoint;
		}
		
		void setLabel(final @Nullable String label) {
			this.label= label;
		}
		
		public @Nullable String getElementLabel() {
			return this.label;
		}
		
	}
	
	private static class Element extends ElementTracepoints {
		
		private final IResource resource;
		
		public Element(final SrcfileData fileInfo, final IResource resource,
				final String elementId, final int @Nullable [] elementSrcref) {
			super(fileInfo, elementId, elementSrcref);
			this.resource= resource;
		}
		
		@Override
		public List<Position> getPositions() {
			return (List<Position>) super.getPositions();
		}
		
		public IResource getResource() {
			return this.resource;
		}
		
	}
	
	
	private static class UpdateData {
		
		private final IResource resource;
		private final String elementId;
		
		public UpdateData(final IResource resource, final String elementId) {
			this.resource= resource;
			this.elementId= elementId;
		}
		
	}
	
	private static class ElementInstallData {
		
		
		private final IResource resource;
		private final String elementId;
		private final @Nullable String elementLabel;
		
		
		public ElementInstallData(final IResource resource, final String elementId,
				final @Nullable String elementLabel) {
			this.resource= resource;
			this.elementId= elementId;
			this.elementLabel= elementLabel;
		}
		
		public ElementInstallData(final IResource resource, final String elementId,
				final Position position) {
			this.resource= resource;
			this.elementId= elementId;
			this.elementLabel= position.getElementLabel();
		}
		
		
		@Override
		public int hashCode() {
			return this.resource.hashCode() ^ Objects.hashCode(this.elementId);
		}
		
		@Override
		public boolean equals(final @Nullable Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj instanceof ElementInstallData) {
				final ElementInstallData other= (ElementInstallData) obj;
				return (this.resource.equals(other.resource)
						&& Objects.equals(this.elementId, other.elementId)
						&& Objects.equals(this.elementLabel, other.elementLabel) );
			}
			return false;
		}
		
		
	}
	
	private static class BreakpointTargetData implements IRBreakpoint.ITargetData, Immutable {
		
		
		private final @Nullable ElementInstallData latest;
		
		private final @Nullable ElementInstallData installed;
		
		
		public BreakpointTargetData(final @Nullable ElementInstallData latest,
				final @Nullable ElementInstallData installed) {
			this.latest= latest;
			this.installed= installed;
		}
		
		
		@Override
		public boolean isInstalled() {
			return (this.installed != null);
		}
		
		@Override
		public <T> @Nullable T getAdapter(final Class<T> adapterType) {
			return null;
		}
		
	}
	
	private static final IRBreakpoint.ITargetData INSTALLED_DATA= new IRBreakpoint.ITargetData() {
		
		@Override
		public boolean isInstalled() {
			return true;
		}
		
		@Override
		public <T> @Nullable T getAdapter(final Class<T> adapter) {
			return null;
		}
		
	};
	
	private static final IRBreakpoint.ITargetData NOT_INSTALLED_DATA= new IRBreakpoint.ITargetData() {
		
		@Override
		public boolean isInstalled() {
			return false;
		}
		
		@Override
		public <T> @Nullable T getAdapter(final Class<T> adapter) {
			return null;
		}
		
	};
	
	
	private final IRDebugTarget debugTarget;
	private final AbstractRDbgController controller;
	
	private IBreakpointManager breakpointManager;
	
	private boolean initialized;
	
	private final List<IRLineBreakpoint> positionUpdatesBreakpoints= new ArrayList<>();
	private final List<UpdateData> positionUpdatesElements= new ArrayList<>();
	private final AtomicInteger positionModCounter= new AtomicInteger();
	private final Object positionUpdatesLock= this.positionUpdatesBreakpoints;
	
	private final Object targetUpdateLock= new Object();
	
	private final Object flagUpdateLock= new Object();
	private boolean flagUpdateCheck;
	private @Nullable ITargetData exceptionBreakpointData;
	
	private final List<IRBreakpoint> stateUpdatesBreakpoints= new ArrayList<>();
	private final Object stateUpdatesLock= this.stateUpdatesBreakpoints;
	
	private final Map<IResource, List<TracepointState>> stateUpdatesMap= new HashMap<>();
	
	private final List<IResource> currentRequests= new ArrayList<>();
	
	private final SystemRunnable updateRunnable= new SystemRunnable() {
		
		private List<String> knownPackages= new ArrayList<>();
		
		@Override
		public String getTypeId() {
			return "r/dbg/breakpoint.update";
		}
		
		@Override
		public String getLabel() {
			return "Update Breakpoints";
		}
		
		@Override
		public boolean canRunIn(final Tool tool) {
			return (tool == RControllerBreakpointAdapter.this.controller.getTool());
		}
		
		@Override
		public boolean changed(final int event, final Tool tool) {
			switch (event) {
			case REMOVING_FROM:
			case MOVING_FROM:
				return false;
			}
			return true;
		}
		
		@Override
		public void run(final ToolService service,
				final IProgressMonitor monitor) throws CoreException {
			boolean checkInstalled= (RControllerBreakpointAdapter.this.controller.getHotTasksState() <= 1);
			
			synchronized (RControllerBreakpointAdapter.this.updateRunnable) {
				RControllerBreakpointAdapter.this.updateRunnableScheduled= false;
			}
			
			{	// init
				if (!RControllerBreakpointAdapter.this.initialized) {
					synchronized (RControllerBreakpointAdapter.this.flagUpdateLock) {
						RControllerBreakpointAdapter.this.flagUpdateCheck= false;
					}
					final IBreakpoint[] breakpoints= RControllerBreakpointAdapter
							.this.breakpointManager.getBreakpoints(RDebugModel.IDENTIFIER);
					try {
						boolean exceptionAvailable= false;
						synchronized (RControllerBreakpointAdapter.this.stateUpdatesLock) {
							for (int i= 0; i < breakpoints.length; i++) {
								if (breakpoints[i] instanceof IRBreakpoint) {
									final IRBreakpoint breakpoint= (IRBreakpoint) breakpoints[i];
									scheduleStateUpdate((IRBreakpoint) breakpoints[i]);
									
									final String breakpointType= breakpoint.getBreakpointType();
									if (breakpointType == RDebugModel.R_EXCEPTION_BREAKPOINT_TYPE_ID) {
										exceptionAvailable= true;
									}
								}
							}
						}
						{	final FlagTracepointInstallationRequest request= createFlagRequest(
									(exceptionAvailable) ? Boolean.TRUE : null );
							if (request != null) {
								installFlagTracepoints(request, monitor);
							}
						}
						synchronized (RControllerBreakpointAdapter.this.positionUpdatesLock) {
							for (int i= 0; i < breakpoints.length; i++) {
								if (breakpoints[i] instanceof IRLineBreakpoint) {
									schedulePositionUpdate((IRLineBreakpoint) breakpoints[i]);
								}
							}
						}
						{	final List<Element> positions= getPendingElementPositions(monitor);
							installElementTracepoints(
									new ElementTracepointInstallationRequest(positions, true),
									monitor );
						}
					}
					finally {
						RControllerBreakpointAdapter.this.initialized= true;
						checkInstalled= false;
						checkUpdates();
					}
				}
				
				// regular
				List<String> newPackages= null;
				
				final List<? extends RProcessREnvironment> environments= RControllerBreakpointAdapter
						.this.controller.getWorkspaceData().getRSearchEnvironments();
				if (environments != null) {
					final List<String> packages= new ArrayList<>(environments.size() - 1);
					for (final RProcessREnvironment environment : environments) {
						if (environment.getSpecialType() == REnvironment.ENVTYPE_PACKAGE) {
							final String pkgName= environment.getElementName().getSegmentName();
							packages.add(pkgName);
							if (this.knownPackages != null && !this.knownPackages.contains(pkgName)) {
								if (newPackages == null) {
									newPackages= new ArrayList<>(4);
								}
								newPackages.add(pkgName);
							}
						}
					}
					if (this.knownPackages == null) {
						newPackages= packages;
					}
					this.knownPackages= packages;
				}
				
				if (newPackages != null || checkInstalled) {
					final IBreakpoint[] breakpoints= RControllerBreakpointAdapter
							.this.breakpointManager.getBreakpoints(RDebugModel.IDENTIFIER);
					Map<String, RProject> rProjects= null;
					boolean exceptionAvailable= false;
					for (int i= 0; i < breakpoints.length; i++) {
						if (breakpoints[i] instanceof IRBreakpoint) {
							final IRBreakpoint breakpoint= (IRBreakpoint) breakpoints[i];
							final IMarker marker= breakpoint.getMarker();
							if (marker == null) {
								continue;
							}
							
							final String breakpointType= breakpoint.getBreakpointType();
							if (breakpointType == RDebugModel.R_EXCEPTION_BREAKPOINT_TYPE_ID) {
								exceptionAvailable= true;
							}
							else if (breakpointType == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
									|| breakpointType == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
								final IRLineBreakpoint lineBreakpoint= (IRLineBreakpoint) breakpoint;
								
								if (checkInstalled) {
									final ITargetData targetData= lineBreakpoint.getTargetData(RControllerBreakpointAdapter.this.debugTarget);
									if (targetData != null && targetData.isInstalled()) {
										schedulePositionUpdate(lineBreakpoint);
										continue;
									}
								}
								
								final IResource resource= marker.getResource();
								if (RControllerBreakpointAdapter.this.currentRequests.contains(resource)) {
									schedulePositionUpdate(lineBreakpoint);
									continue;
								}
								
								if (newPackages != null) {
									final IProject project= resource.getProject();
									if (rProjects == null) {
										rProjects= new HashMap<>();
									}
									RProject rProject= rProjects.get(project.getName());
									if (rProject == null) {
										rProject= RProjects.getRProject(project);
										if (rProject == null) {
											continue; // ?
										}
										rProjects.put(project.getName(), rProject);
									}
									
									final String pkgName= rProject.getPkgName();
									if (newPackages.contains(pkgName)) {
										schedulePositionUpdate(lineBreakpoint);
										continue;
									}
								}
							}
						}
					}
					
					{	final FlagTracepointInstallationRequest request= createFlagRequest(
								(((RControllerBreakpointAdapter.this.exceptionBreakpointData != null) ? RControllerBreakpointAdapter.this.exceptionBreakpointData.isInstalled() : false)
												!= exceptionAvailable ) ?
										Boolean.valueOf(exceptionAvailable) : null );
						if (request != null) {
							installFlagTracepoints(request, monitor);
						}
					}
				}
				
				while (true) {
					final List<Element> positions= getPendingElementPositions(monitor);
					if (!positions.isEmpty()) {
						installElementTracepoints(
								new ElementTracepointInstallationRequest(positions, false),
								monitor );
					}
					else {
						break;
					}
				}
			}
		}
		
	};
	
	private boolean updateRunnableScheduled;
	
	
	public RControllerBreakpointAdapter(final IRDebugTarget target,
			final AbstractRDbgController controller) {
		this.debugTarget= target;
		this.controller= controller;
		
		this.breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
		this.breakpointManager.addBreakpointManagerListener(this);
		this.breakpointManager.addBreakpointListener(this);
		
		breakpointManagerEnablementChanged(this.breakpointManager.isEnabled());
	}
	
	public void init() {
		final Queue queue= this.controller.getTool().getQueue();
		queue.addHot(this.updateRunnable);
		queue.addOnIdle(this.updateRunnable, 5500);
	}
	
	
	public boolean supportsBreakpoint(final IRBreakpoint breakpoint) {
		final String breakpointType= breakpoint.getBreakpointType();
		switch (breakpointType) {
		case RDebugModel.R_LINE_BREAKPOINT_TYPE_ID:
		case RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID:
		case RDebugModel.R_EXCEPTION_BREAKPOINT_TYPE_ID:
			return true;
		default:
			return false;
		}
	}
	
	private @Nullable IRBreakpoint getRBreakpoint(final TracepointEvent event) {
		if (event.getFilePath() == null) {
			return null;
		}
		try {
			final IWorkspace workspace= ResourcesPlugin.getWorkspace();
			final IMarker marker;
			if (event.getType() == Tracepoint.TYPE_EB) {
				final IResource resource= workspace.getRoot();
				final IMarker[] markers= resource.findMarkers(RExceptionBreakpoint.R_EXCEPTION_BREAKPOINT_MARKER_TYPE, false, IResource.DEPTH_ZERO);
				marker= (markers.length > 0) ? markers[0] : null;
			}
			else {
				final IResource resource= workspace.getRoot().getFile(new Path(event.getFilePath()));
				marker= resource.getMarker(event.getId());
			}
			final IBreakpoint b= this.breakpointManager.getBreakpoint(marker);
			return (b instanceof IRBreakpoint) ? (IRBreakpoint) b : null;
		}
		catch (final CoreException e) {
			return null;
		}
	}
	
	@Override
	public void handle(final TracepointEvent event) {
		switch (event.getKind()) {
		case TracepointEvent.KIND_INSTALLED:
		case TracepointEvent.KIND_UNINSTALLED:
			if (event.getType() == Tracepoint.TYPE_EB) {
				updateFlagInstallData(event);
			}
			else {
				updateElementInstallData(event);
			}
		}
	}
	
	/** Call in R thread */
	@Override
	public boolean matchScriptBreakpoint(final IRModelSrcref srcref,
			final IProgressMonitor monitor) {
		try {
			if (srcref instanceof IAdaptable) {
				final IMarker marker= ((IAdaptable) srcref).getAdapter(IMarker.class);
				final ISourceUnit su= srcref.getFile();
				if (marker != null && su instanceof IRWorkspaceSourceUnit
						&& marker.getResource() == su.getResource()) {
					return doMatchScriptBreakpoint(srcref,
							(IRWorkspaceSourceUnit) su, marker,
							monitor );
				}
			}
			return false;
		}
		catch (final Exception e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when looking for script breakpoints.", e));
			return false;
		}
	}
	
	private boolean doMatchScriptBreakpoint(final IRModelSrcref srcref,
			final IRWorkspaceSourceUnit rSourceUnit, final IMarker marker,
			final IProgressMonitor monitor) throws CoreException {
		final List<IRLineBreakpoint> breakpoints= RDebugModel.getLineBreakpoints(
				(IFile) rSourceUnit.getResource() );
		if (breakpoints.isEmpty()) {
			return false;
		}
		final IMarkerPositionResolver resolver= rSourceUnit.getMarkerPositionResolver();
		synchronized ((resolver != null && resolver.getDocument() instanceof ISynchronizable) ? ((ISynchronizable) resolver.getDocument()).getLockObject() : new Object()) {
			final int lineNumber= getLineNumber(marker, resolver);
			if (lineNumber < 0) {
				return false;
			}
			for (final IRLineBreakpoint breakpoint : breakpoints) {
				try {
					if (isScriptBreakpoint(breakpoint)
							&& ((resolver != null) ? resolver.getLine(breakpoint.getMarker()) : breakpoint.getLineNumber()) == lineNumber ) {
						return breakpoint.isEnabled();
					}
				}
				catch (final CoreException e) {
					RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
							"An error occurred when checking breakpoints.", e));
				}
				
			}
			return false;
		}
	}
	
	
	private @Nullable FlagTracepointInstallationRequest createFlagRequest(final @Nullable Boolean exception) {
		int count= 0;
		if (exception != null) {
			count++;
		}
		if (count == 0) {
			return null;
		}
		final byte[] types= new byte[count];
		final int[] flags= new int[count];
		
		int i= 0;
		if (exception != null) {
			types[i]= Tracepoint.TYPE_EB;
			flags[i]= (exception.booleanValue()) ? TracepointState.FLAG_ENABLED : 0;
			i++;
		}
		return new FlagTracepointInstallationRequest(types, flags);
	}
	
	/** Call in R thread */
	private void installFlagTracepoints(final FlagTracepointInstallationRequest request,
			final IProgressMonitor monitor) {
		try {
			this.controller.exec(request, monitor);
		}
		catch (final Exception e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when updating breakpoints in R." , e ));
		}
		finally {
			checkUpdates();
		}
	}
	
	/** Call in R thread */
	@Override
	public @Nullable ElementTracepointInstallationRequest getElementTracepoints(final SrcfileData srcfile,
			final IRModelSrcref srcref,
			final IProgressMonitor monitor) {
		try {
			final ISourceUnit su= srcref.getFile();
			if (su instanceof IRWorkspaceSourceUnit) {
				return doGetElementTracepoints(srcfile, srcref,
						(IRWorkspaceSourceUnit) su,
						monitor );
			}
			return null;
		}
		catch (final Exception e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when looking for script list.", e));
			return null;
		}
	}
	
	private @Nullable ElementTracepointInstallationRequest doGetElementTracepoints(final SrcfileData srcfile,
			final IRModelSrcref srcref,
			final IRWorkspaceSourceUnit rSourceUnit,
			final IProgressMonitor monitor) throws CoreException, BadLocationException {
		if (rSourceUnit.getResource().getType() != IResource.FILE
				|| !rSourceUnit.getResource().exists()) {
			return null;
		}
		
		List<? extends IRLangSourceElement> elements= srcref.getElements();
		if (elements.isEmpty()) {
			return null;
		}
		final int modCounter= this.positionModCounter.get();
		final List<IRLineBreakpoint> breakpoints= RDebugModel.getLineBreakpoints(
				(IFile) rSourceUnit.getResource() );
		if (breakpoints.isEmpty()) {
			return null;
		}
		
		rSourceUnit.connect(monitor);
		try {
			final AbstractDocument document= rSourceUnit.getDocument(monitor);
			synchronized ((document instanceof ISynchronizable) ? ((ISynchronizable) document).getLockObject() : new Object()) {
				final IRModelInfo modelInfo= (IRModelInfo) rSourceUnit.getModelInfo(
						RModel.R_TYPE_ID, IRModelManager.MODEL_FILE, monitor );
				if (elements.get(0).getSourceParent() != modelInfo.getSourceElement()) {
					final List<? extends IRLangSourceElement> orgElements= elements;
					elements= modelInfo.getSourceElement().getSourceChildren(new IModelElement.Filter() {
						@Override
						public boolean include(final IModelElement element) {
							return orgElements.contains(element);
//									return map.containsKey(element.getId());
						}
					});
				}
				if (elements.isEmpty()) {
					return null;
				}
				final IMarkerPositionResolver resolver= rSourceUnit.getMarkerPositionResolver();
				final int[] lines= new int[elements.size()*2];
				for (int i= 0, j= 0; i < elements.size(); i++, j+=2) {
					final IRegion region= elements.get(i).getSourceRange();
					lines[j]= document.getLineOfOffset(region.getOffset()) + 1;
					lines[j+1]= document.getLineOfOffset(region.getOffset()+region.getLength()) + 1;
				}
				HashMap<String, @Nullable Element> map= null;
				List<String> cleanup= null;
				for (final IRLineBreakpoint breakpoint : breakpoints) {
					try {
						if (isElementBreakpoint(breakpoint)) {
							final IMarker marker= breakpoint.getMarker();
							final int breakpointLineNumber= (resolver != null) ?
									resolver.getLine(breakpoint.getMarker()) :
									breakpoint.getLineNumber();
							for (int j= 0; j < lines.length; j+=2) {
								if (lines[j] <= breakpointLineNumber && lines[j+1] >= breakpointLineNumber) {
									final RLineBreakpointValidator validator= (resolver != null) ?
											new RLineBreakpointValidator(rSourceUnit,
													breakpoint.getBreakpointType(),
													resolver.getPosition(marker).getOffset(),
													monitor ) :
											new RLineBreakpointValidator(rSourceUnit,
													breakpoint, monitor );
									final String elementId;
									if (validator.getType() == breakpoint.getBreakpointType()
											&& (elementId= validator.computeElementId()) != null
											&& elements.contains(validator.getBaseElement()) ) {
										if (map == null) {
											map= new HashMap<>(elements.size());
										}
										final BreakpointTargetData breakpointData= (BreakpointTargetData) breakpoint.getTargetData(this.debugTarget);
										if (breakpointData != null && breakpointData.latest != null
												&& !elementId.equals(breakpointData.latest.elementId) ) {
											if (cleanup == null) {
												cleanup= new ArrayList<>();
											}
											if (!cleanup.contains(breakpointData.latest.elementId)) {
												cleanup.add(breakpointData.latest.elementId);
											}
										}
										addBreakpoint(map, srcfile, rSourceUnit.getResource(),
												elementId, breakpoint, validator, modCounter );
									}
									break;
								}
							}
						}
					}
					catch (final CoreException e) {
						RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
								"An error occurred when checking breakpoint.", e));
					}
				}
				if (cleanup != null) {
					cleanup.removeAll(map.keySet());
					if (!cleanup.isEmpty()) {
						synchronized (this.positionUpdatesLock) {
							for (int i= 0; i < cleanup.size(); i++) {
								this.positionUpdatesElements.add(
										new UpdateData(rSourceUnit.getResource(), cleanup.get(i)));
							}
						}
					}
				}
				if (map != null) {
					final ArrayList<Element> list= new ArrayList<>(map.size());
					addElements(list, map, false);
					if (!list.isEmpty()) {
						return new ElementTracepointInstallationRequest(list, false);
					}
				}
			}
		}
		finally {
			rSourceUnit.disconnect(monitor);
		}
		return null;
	}
	
	@Override
	public @Nullable ElementTracepointInstallationRequest prepareFileElementTracepoints(final SrcfileData srcfile,
			final IRSourceUnit su,
			final IProgressMonitor monitor) {
		try {
			if (su instanceof IRWorkspaceSourceUnit) {
				final ElementTracepointInstallationRequest request= doPrepareFileElementTracepoints(
						srcfile, (IRWorkspaceSourceUnit) su, monitor);
				if (request != null) {
					installElementTracepoints(request, monitor);
					
					for (final ElementTracepoints positions : request.getRequests()) {
						if (positions instanceof Element) {
							this.currentRequests.add(((Element) positions).getResource());
						}
					}
					
					return request;
				}
			}
			return null;
		}
		catch (final Exception e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when looking for line breakpoints.", e));
			return null;
		}
	}
	
	@Override
	public void finishFileElementTracepoints(final SrcfileData srcfile, final IRSourceUnit su,
			final ElementTracepointInstallationRequest request, final IProgressMonitor monitor) {
		for (final ElementTracepoints positions : request.getRequests()) {
			if (positions instanceof Element) {
				this.currentRequests.remove(((Element) positions).getResource());
			}
		}
		
		ElementTracepointInstallationRequest installRequest= request;
		if (srcfile != null) {
			try {
				installRequest= doPrepareFileElementTracepoints(srcfile, (IRWorkspaceSourceUnit) su,
						monitor );
			}
			catch (final CoreException e) {}
		}
		if (installRequest != null) {
			installElementTracepoints(request, monitor);
		}
	}
	
	private @Nullable ElementTracepointInstallationRequest doPrepareFileElementTracepoints(
			final SrcfileData srcfile, final IRWorkspaceSourceUnit rSourceUnit,
			final IProgressMonitor monitor) throws CoreException {
		if (rSourceUnit.getResource().getType() != IResource.FILE
				|| !rSourceUnit.getResource().exists()) {
			return null;
		}
		
		final int modeCounter= this.positionModCounter.get();
		final List<IRLineBreakpoint> breakpoints= RDebugModel.getLineBreakpoints(
				(IFile) rSourceUnit.getResource() );
		if (breakpoints.isEmpty()) {
			return null;
		}
		Map<String, @Nullable Element> map= null;
		for (final IRLineBreakpoint breakpoint : breakpoints) {
			try {
				final String breakpointType= breakpoint.getBreakpointType();
				if (breakpointType == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
						|| breakpointType == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
					rSourceUnit.getDocument(monitor).get();
					final RLineBreakpointValidator validator= new RLineBreakpointValidator(
							rSourceUnit, breakpoint, monitor );
					final String elementId;
					if (validator.getType() == breakpoint.getBreakpointType()
							&& (elementId= validator.computeElementId()) != null ) {
//									|| (((elementId= validator.computeElementId()) != null) ?
//											!elementId.equals(breakpoint.getElementId()) :
//											null != breakpoint.getElementId() )) {
						if (map == null) {
							map= new HashMap<>(breakpoints.size());
						}
						addBreakpoint(map, srcfile, rSourceUnit.getResource(), elementId,
								breakpoint, validator, modeCounter );
					}
				}
			}
			catch (final CoreException e) {
				RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
						"An error occurred when checking breakpoint.", e));
			}
		}
		if (map != null) {
			final ArrayList<Element> list= new ArrayList<>(map.size());
			addElements(list, map, false);
			if (!list.isEmpty()) {
				return new ElementTracepointInstallationRequest(list, false);
			}
		}
		return null;
	}
	
	@Override
	public void installElementTracepoints(final ElementTracepointInstallationRequest request,
			final IProgressMonitor monitor) {
		try {
			synchronized (RControllerBreakpointAdapter.this.stateUpdatesMap) {
				final List<TracepointState> states= getPendingTracepointStates();
				RControllerBreakpointAdapter.this.controller.exec(
						new TracepointStatesUpdate(states, request.getReset()),
						monitor );
			}
			
			this.controller.exec(request, monitor);
		}
		catch (final Exception e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when updating breakpoints in R." , e ));
		}
		finally {
			checkUpdates();
		}
	}
	
	/** Call in R thread */
	private List<Element> getPendingElementPositions(final IProgressMonitor monitor) {
		final IRBreakpoint[] breakpointsToUpdate;
		final UpdateData[] elementsToUpdate;
		synchronized (this.positionUpdatesLock) {
			if (this.positionUpdatesBreakpoints.isEmpty() && this.positionUpdatesElements.isEmpty()) {
				return ImCollections.emptyList();
			}
			breakpointsToUpdate= this.positionUpdatesBreakpoints.toArray(new @NonNull IRBreakpoint[this.positionUpdatesBreakpoints.size()]);
			this.positionUpdatesBreakpoints.clear();
			elementsToUpdate= this.positionUpdatesElements.toArray(new @NonNull UpdateData[this.positionUpdatesElements.size()]);
			this.positionUpdatesElements.clear();
		}
		final Map<IResource, Map<String, @Nullable Element>> resourceMap= new HashMap<>();
		// by resources
		for (int i= 0; i < breakpointsToUpdate.length; i++) {
			final IRBreakpoint rBreakpoint= breakpointsToUpdate[i];
			final String breakpointType= rBreakpoint.getBreakpointType();
			if (breakpointType == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
					|| breakpointType == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
				try {
					final BreakpointTargetData breakpointData= (BreakpointTargetData) rBreakpoint.getTargetData(this.debugTarget);
					if (breakpointData != null && breakpointData.latest != null) {
						Map<String, @Nullable Element> map= resourceMap.get(breakpointData.latest.resource);
						if (map == null) {
							map= new HashMap<>();
							resourceMap.put(breakpointData.latest.resource, map);
						}
						map.put(breakpointData.latest.elementId, null);
					}
					
					if (rBreakpoint.isRegistered()) {
						final IResource resource= rBreakpoint.getMarker().getResource();
						if (!resourceMap.containsKey(resource)) {
							resourceMap.put(resource, new HashMap<String, @Nullable Element>());
						}
					}
					else if (breakpointData != null) {
						rBreakpoint.unregisterTarget(this.debugTarget);
					}
				}
				catch (final CoreException e) {
					logPrepareError(e, rBreakpoint);
				}
			}
		}
		for (int i= 0; i < elementsToUpdate.length; i++) {
			final UpdateData updateData= elementsToUpdate[i];
			Map<String, @Nullable Element> map= resourceMap.get(updateData.resource);
			if (map == null) {
				map= new HashMap<>();
				resourceMap.put(updateData.resource, map);
			}
			map.put(updateData.elementId, null);
		}
		
		int n= 0;
		for (final Entry<IResource, Map<String, @Nullable Element>> resourceEntry : resourceMap.entrySet()) {
			final IResource resource= resourceEntry.getKey();
			final Map<String, @Nullable Element> map= resourceEntry.getValue();
			try {
				final SrcfileData srcfile= RDbg.createRJSrcfileData(resource);
				if (resource.exists() && resource.getType() == IResource.FILE) {
					final ISourceUnit su= LTK.getSourceUnitManager().getSourceUnit(
							LTK.PERSISTENCE_CONTEXT, resource, null, true, monitor );
					if (su != null) {
						try {
							if (su instanceof IRWorkspaceSourceUnit) {
								doGetPendingElementPositions(srcfile, (IRWorkspaceSourceUnit) su,
										breakpointsToUpdate, map, monitor);
								continue;
							}
						}
						finally {
							su.disconnect(monitor);
						}
					}
				}
				
				for (final String elementId : map.keySet()) {
					addClear(map, srcfile, resource, elementId);
				}
			}
			catch (final CoreException e) {
				RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, -1,
						NLS.bind("An error occurred when preparing update of R line breakpoints in ''{0}''.",
								resource.getFullPath().toString() ), e ));
			}
			n += map.size();
		}
		
		final List<Element> list= new ArrayList<>(n);
		for (final Entry<IResource, Map<String, @Nullable Element>> resourceEntry : resourceMap.entrySet()) {
			addElements(list, resourceEntry.getValue(), true);
		}
		return list;
	}
	
	private void doGetPendingElementPositions(final SrcfileData srcfile, final IRWorkspaceSourceUnit rSourceUnit,
			final IRBreakpoint[] breakpointsToUpdate, final Map<String, @Nullable Element> map,
			final IProgressMonitor monitor) throws CoreException {
		final int modCounter= this.positionModCounter.get();
		final List<IRLineBreakpoint> breakpoints= RDebugModel.getLineBreakpoints(
				(IFile) rSourceUnit.getResource() );
		for (final IRLineBreakpoint lineBreakpoint : breakpoints) {
			if (contains(breakpointsToUpdate, lineBreakpoint)) {
				try {
					if (lineBreakpoint.isEnabled()) {
						final RLineBreakpointValidator validator= new RLineBreakpointValidator(
								rSourceUnit,
								lineBreakpoint.getBreakpointType(), lineBreakpoint.getCharStart(),
								monitor );
						final String elementId;
						if (validator.getType() == lineBreakpoint.getBreakpointType()
								&& (elementId= validator.computeElementId()) != null ) {
							addBreakpoint(map, srcfile, rSourceUnit.getResource(), elementId,
									lineBreakpoint, validator, modCounter );
						}
					}
				}
				catch (final CoreException e) {
					logPrepareError(e, lineBreakpoint);
				}
			}
		}
		for (final IRLineBreakpoint lineBreakpoint : breakpoints) {
			if (!contains(breakpointsToUpdate, lineBreakpoint)) {
				try {
					if (lineBreakpoint.isEnabled()) {
						final RLineBreakpointValidator validator= new RLineBreakpointValidator(
								rSourceUnit,
								lineBreakpoint.getBreakpointType(), lineBreakpoint.getCharStart(),
								monitor );
						final String elementId;
						if (validator.getType() == lineBreakpoint.getBreakpointType()
								&& (elementId= validator.computeElementId()) != null
								&& map.containsKey(elementId) ) {
							addBreakpoint(map, srcfile, rSourceUnit.getResource(), elementId,
									lineBreakpoint, validator, modCounter );
						}
					}
				}
				catch (final CoreException e) {
					logPrepareError(e, lineBreakpoint);
				}
			}
		}
		for (final Entry<String, @Nullable Element> elementEntry : map.entrySet()) {
			if (elementEntry.getValue() == null) {
				addClear(map, srcfile, rSourceUnit.getResource(), elementEntry.getKey());
			}
		}
	}
	
	private void logPrepareError(final CoreException e, final IRBreakpoint breakpoint) {
		if (breakpoint instanceof IRLineBreakpoint) {
			String fileName= null;
			final IMarker marker= breakpoint.getMarker();
			if (marker != null) {
				final IResource resource= marker.getResource();
				if (resource != null) {
					fileName= resource.getFullPath().toString();
				}
			}
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, -1,
					NLS.bind("An error occurred when preparing update of an R line breakpoint in ''{0}''.",
							(fileName != null) ? fileName : "<missing>" ), e ));
		}
		else {
			String exceptionId= null;
			try {
				exceptionId= ((IRExceptionBreakpoint) breakpoint).getExceptionId();
			}
			catch (final CoreException ignore) {}
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, -1,
					NLS.bind("An error occurred when preparing update of an R error breakpoint ''{0}''.",
							(exceptionId != null) ? exceptionId : "<missing>" ), e ));
		}
	}
	
//	/** Call in R thread */
//	private void report(final ElementTracepointInstallationRequest request,
//			final TracepointInstallationReport report) {
//		if (request == null) {
//			throw new NullPointerException();
//		}
//		final List<? extends ElementTracepoints> elements= request.getRequests();
//		final int l= elements.size();
//		int[] results= null;
//		if (report != null && report.getInstallationResults().length == l) {
//			results= report.getInstallationResults();
//		}
//		
//		if (results == null) {
//			return; // ?
//		}
//		
//		ArrayList<Element> cleanup= null;
//		List<IRLineBreakpoint> updated= null;
//		
//		for (int i= 0; i < l; i++) {
//			if (results[i] == TracepointInstallationReport.FOUND_UNCHANGED
//					|| !(elements.get(i) instanceof Element)) {
//				continue;
//			}
//			
//			final Element current= (Element) elements.get(i);
//			final boolean installed= (results[i] == TracepointInstallationReport.FOUND_SET);
//			for (final TracepointPosition position : current.getPositions()) {
//				if (!(position instanceof Position)) {
//					continue;
//				}
//				final IRLineBreakpoint breakpoint= ((Position) position).getBreakpoint();
//				try {
//					if (breakpoint == null || !breakpoint.isRegistered()) {
//						continue;
//					}
//					final IMarker marker= breakpoint.getMarker();
//					if (marker == null || marker.getId() != position.getId()) {
//						continue;
//					}
//					final ElementTargetData newData= new ElementTargetData((installed) ? current : null);
//					final ElementTargetData oldData= (ElementTargetData) breakpoint.registerTarget(this.debugTarget, newData);
////					if (oldData != null && oldData.isInstalled()
////							&& oldData.getElementId().equals(current.getElementId())) {
////						if (cleanup == null) {
////							cleanup= new ArrayList<>(l-i);
////						}
////						if (!contains(cleanup, oldData.installed)) {
////							cleanup.add(oldData.installed);
////						}
////					}
//					if (updated == null) {
//						updated= new ArrayList<>(l - i);
//					}
//					updated.add(breakpoint);
//				}
//				catch (final CoreException e) {} // only isRegistered
//			}
//		}
//		
//		if (cleanup != null) {
//			for (int i= 0; i < cleanup.size(); i++) {
//				final Element current= cleanup.get(i);
//				for (final TracepointPosition position : current.getPositions()) {
//					if (!(position instanceof Position)) {
//						continue;
//					}
//					final IRBreakpoint breakpoint= ((Position) position).getBreakpoint();
//					try {
//						if (breakpoint == null || !breakpoint.isRegistered()) {
//							continue;
//						}
//						final ElementTargetData data= (ElementTargetData) breakpoint.getTargetData(this.debugTarget);
//						if (data != null && data.isInstalled()) {
//							breakpoint.registerTarget(this.debugTarget, new ElementTargetData(null));
//						}
//					}
//					catch (final CoreException e) {} // only isRegistered
//				}
//			}
//		}
//		
//		if (updated != null) {
//			synchronized (this.stateUpdatesLock) {
//				for (int i= 0; i < updated.size(); i++) {
//					scheduleStateUpdate(updated.get(i));
//				}
//			}
//		}
//	}
	
	private void updateFlagInstallData(final TracepointEvent event) {
		final IRBreakpoint.ITargetData newData;
		switch (event.getKind()) {
		case TracepointEvent.KIND_INSTALLED:
			newData= INSTALLED_DATA;
			break;
		case TracepointEvent.KIND_UNINSTALLED:
			newData= NOT_INSTALLED_DATA;
			break;
		default:
			return;
		}
		
		synchronized (this.flagUpdateLock) {
			this.exceptionBreakpointData= newData;
		}
		
		final IRBreakpoint breakpoint= getRBreakpoint(event);
		if (breakpoint == null) {
			return;
		}
		
		breakpoint.registerTarget(this.debugTarget, newData);
	}
	
	private void updateElementInstallData(final TracepointEvent event) {
		final IRBreakpoint breakpoint= getRBreakpoint(event);
		if (breakpoint == null) {
			return;
		}
		final IMarker marker= breakpoint.getMarker();
		if (marker == null) {
			return;
		}
		
		final ElementInstallData installData;
		switch (event.getKind()) {
		case TracepointEvent.KIND_INSTALLED:
			installData= new ElementInstallData(marker.getResource(),
					event.getElementId(), event.getLabel() );
			break;
		case TracepointEvent.KIND_UNINSTALLED:
			installData= null;
			break;
		default:
			return;
		}
		synchronized (this.targetUpdateLock) {
			final BreakpointTargetData oldData= (BreakpointTargetData) breakpoint.getTargetData(this.debugTarget);
			breakpoint.registerTarget(this.debugTarget,
					new BreakpointTargetData(
							(oldData != null) ? oldData.latest : null,
							installData ));
		}
	}
	
	
	private void addBreakpoint(final Map<String, Element> map,
			final SrcfileData srcfile, final IResource resource, final String elementId,
			final IRLineBreakpoint breakpoint, final RLineBreakpointValidator validator,
			final int modCounter) throws CoreException {
		synchronized (this.positionUpdatesLock) {
			if (this.positionModCounter.get() == modCounter) {
				this.positionUpdatesBreakpoints.remove(breakpoint);
			}
		}
		
		Element elementPositions= map.get(elementId);
		if (elementPositions == null) {
			final IRSrcref elementSrcref= validator.computeElementSrcref();
			elementPositions= new Element(srcfile, resource, elementId,
					(elementSrcref != null) ? RDbg.createRJSrcref(elementSrcref) : null );
			map.put(elementId, elementPositions);
		}
		final IMarker marker= breakpoint.getMarker();
		if (marker == null) {
			return;
		}
		int[] rExpressionIndex= validator.computeRExpressionIndex();
		if (rExpressionIndex == null) {
			rExpressionIndex= new int[0];
		}
		final int type;
		if (breakpoint.getBreakpointType() == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID) {
			if (breakpoint.getElementType() == IRLineBreakpoint.R_TOPLEVEL_COMMAND_ELEMENT_TYPE) {
				type= Tracepoint.TYPE_TB;
			}
			else {
				type= Tracepoint.TYPE_LB;
			}
		}
		else if (breakpoint.getBreakpointType() == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
			type= Tracepoint.TYPE_FB;
		}
		else {
			return;
		}
		final Position position= new Position(type, marker.getId(), rExpressionIndex,
				breakpoint );
		if (!elementPositions.getPositions().contains(position)) {
			{	final int[] elementSrcref= elementPositions.getElementSrcref();
				if (elementSrcref != null) {
					final RSrcref[] rExpressionSrcrefs= validator.computeRExpressionSrcrefs();
					if (rExpressionSrcrefs != null) {
						final int [] @Nullable [] srcrefs= position.getSrcrefs();
						for (int i= 0; i < rExpressionSrcrefs.length; i++) {
							if (rExpressionSrcrefs[i] != null) {
								srcrefs[i]= Srcref.substract(
										RDbg.createRJSrcref(rExpressionSrcrefs[i]),
										elementSrcref );
							}
						}
					}
				}
			}
			{	String label= validator.computeSubLabel();
				if (label == null) {
					label= validator.computeElementLabel();
				}
				position.setLabel(label);
			}
			elementPositions.getPositions().add(position);
		}
		
		final ElementInstallData latestData= new ElementInstallData(marker.getResource(),
				elementId, position );
		synchronized (this.targetUpdateLock) {
			final BreakpointTargetData oldData= (BreakpointTargetData) breakpoint.getTargetData(this.debugTarget);
			if (oldData != null && Objects.equals(latestData, oldData.latest)) {
				return;
			}
			breakpoint.registerTarget(this.debugTarget,
					new BreakpointTargetData(
							latestData,
							(oldData != null) ? oldData.installed : null ));
		}
		synchronized (this.stateUpdatesLock) {
			scheduleStateUpdate(breakpoint);
		}
	}
	
	private void addClear(final Map<String, Element> map,
			final SrcfileData srcfile, final IResource resource, final String elementId)
			throws CoreException {
		Element elementPositions= map.get(elementId);
		if (elementPositions != null) {
			return;
		}
		elementPositions= new Element(srcfile, resource, elementId, null);
		map.put(elementId, elementPositions);
	}
	
	private void addElements(final List<Element> list, final Map<String, @Nullable Element> map,
			final boolean delete) {
		final Collection<@Nullable Element> values= map.values();
		for (final Element elementPositions : values) {
			if (elementPositions == null) {
				continue;
			}
			if (elementPositions.getPositions().size() > 0) {
				Collections.sort(elementPositions.getPositions());
			}
			else if (!delete) {
				continue;
			}
			list.add(elementPositions);
		}
	}
	
	
	@Override
	public void breakpointManagerEnablementChanged(final boolean enabled) {
		try {
			this.controller.exec(new DbgEnablement(enabled));
		}
		catch (final CoreException e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when updating breakpoint enablement in the R engine.", e));
		}
	}
	
	@Override
	public void breakpointsAdded(final IBreakpoint[] breakpoints) {
		boolean check= false;
		try {
			for (int i= 0; i < breakpoints.length; i++) {
				if (breakpoints[i] instanceof IRBreakpoint) {
					final IRBreakpoint rBreakpoint= (IRBreakpoint) breakpoints[i];
					try {
						check= true;
						final String breakpointType= rBreakpoint.getBreakpointType();
						if (breakpointType == RDebugModel.R_EXCEPTION_BREAKPOINT_TYPE_ID) {
							final IRBreakpoint.ITargetData data;
							synchronized (this.flagUpdateLock) {
								data= this.exceptionBreakpointData;
								if (data != INSTALLED_DATA) {
									scheduleExceptionUpdate();
								}
							}
							if (data == INSTALLED_DATA) {
								rBreakpoint.registerTarget(this.debugTarget, data);
							}
						}
						else if (breakpointType == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
								|| breakpointType == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
							synchronized (this.positionUpdatesLock) {
								this.positionModCounter.incrementAndGet();
								schedulePositionUpdate((IRLineBreakpoint) rBreakpoint);
							}
						}
					}
					catch (final Exception e) {
						RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
								"An error occurred when handling creation of an R breakpoint.", e ));
					}
				}
			}
		}
		finally {
			if (check) {
				checkUpdates();
			}
		}
	}
	
	@Override
	public void breakpointsRemoved(final IBreakpoint[] breakpoints, final @Nullable IMarkerDelta[] deltas) {
		boolean check= false;
		try {
			for (int i= 0; i < breakpoints.length; i++) {
				if (breakpoints[i] instanceof IRBreakpoint) {
					final IRBreakpoint rBreakpoint= (IRBreakpoint) breakpoints[i];
					try {
						check= true;
						final String breakpointType= rBreakpoint.getBreakpointType();
						if (breakpointType == RDebugModel.R_EXCEPTION_BREAKPOINT_TYPE_ID) {
							final IRBreakpoint.ITargetData data;
							synchronized (this.flagUpdateLock) {
								data= this.exceptionBreakpointData;
								if (data == INSTALLED_DATA) {
									scheduleExceptionUpdate();
								}
							}
						}
						else if (breakpointType == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
								|| breakpointType == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
							final IMarkerDelta delta= deltas[i];
							final IMarker marker= rBreakpoint.getMarker();
							
							IResource resource= null;
							if (delta != null) {
								resource= delta.getResource();
								deactivateBreakpoint(resource, delta.getId());
							}
							else if (marker != null) {
								resource= marker.getResource();
								deactivateBreakpoint(resource, marker.getId());
							}
							
							String elementId= null;
							if (delta != null) {
								elementId= delta.getAttribute(RLineBreakpoint.ELEMENT_ID_MARKER_ATTR,
										null );
							}
							else if (marker != null) {
								elementId= marker.getAttribute(RLineBreakpoint.ELEMENT_ID_MARKER_ATTR,
										null );
							}
							
							synchronized (this.positionUpdatesLock) {
								this.positionModCounter.incrementAndGet();
								schedulePositionUpdate((IRLineBreakpoint) rBreakpoint);
								
								if (elementId != null) {
									this.positionUpdatesElements.add(new UpdateData(resource, elementId));
								}
							}
						}
					}
					catch (final Exception e) {
						RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
								"An error occurred when handling deletion of an R breakpoint.", e ));
					}
				}
			}
		}
		finally {
			if (check) {
				checkUpdates();
			}
		}
	}
	
	@Override
	public void breakpointsChanged(final IBreakpoint[] breakpoints, final @Nullable IMarkerDelta[] deltas) {
		boolean check= false;
		try {
			for (int i= 0; i < breakpoints.length; i++) {
				if (breakpoints[i] instanceof IRBreakpoint) {
					final IRBreakpoint rBreakpoint= (IRBreakpoint) breakpoints[i];
					try {
						final IMarkerDelta delta= deltas[i];
						if (delta == null) {
							continue;
						}
						
						check= true;
						final IMarker marker= rBreakpoint.getMarker();
						if (!marker.getResource().equals(delta.getResource())
								|| marker.getId() != delta.getId()) {
							deactivateBreakpoint(delta.getResource(), delta.getId());
						}
						
						synchronized (this.stateUpdatesLock) {
							scheduleStateUpdate(rBreakpoint);
						}
						
//						synchronized (fPendingPositionUpdatesLock) {
//							schedulePositionUpdate(lineBreakpoint);
//						}
					}
					catch (final Exception e) {
						RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
								"An error occurred when handling changes of an R breakpoint.", e ));
					}
				}
			}
		}
		finally {
			if (check) {
				checkUpdates();
			}
		}
	}
	
	
	protected void deactivateBreakpoint(final @Nullable IResource resource, final long id) {
		if (resource == null) {
			return;
		}
		synchronized (this.stateUpdatesMap) {
			List<TracepointState> list= this.stateUpdatesMap.get(resource);
			if (list == null) {
				list= new ArrayList<>(8);
				this.stateUpdatesMap.put(resource, list);
			}
			String filePath;
			if (list.size() > 0) {
				for (int i= 0; i < list.size(); i++) {
					final TracepointState state= list.get(i);
					if (state.getId() == id) {
						if (state.getType() == TracepointState.TYPE_DELETED) {
							return;
						}
						list.remove(i);
					}
				}
				filePath= list.get(0).getFilePath();
			}
			else {
				filePath= resource.getFullPath().toPortableString();
			}
			list.add(new TracepointState(TracepointState.TYPE_DELETED, filePath, id));
		}
	}
	
	private List<TracepointState> getPendingTracepointStates() {
		// requires lock of stateUpdatesMap
		final ImList<IRBreakpoint> breakpoints;
		synchronized (this.stateUpdatesLock) {
			if (this.stateUpdatesBreakpoints.isEmpty() && this.stateUpdatesMap.isEmpty()) {
				return ImCollections.emptyList();
			}
			breakpoints= ImCollections.toList(this.stateUpdatesBreakpoints);
			this.stateUpdatesBreakpoints.clear();
		}
		
		ITER_BREAKPOINTS: for (final IRBreakpoint breakpoint : breakpoints) {
			try {
				final IMarker marker= breakpoint.getMarker();
				if (marker == null || !marker.exists()) {
					continue ITER_BREAKPOINTS;
				}
				
				final TracepointState newState;
				if (breakpoint instanceof IRExceptionBreakpoint) {
					newState= createState((IRExceptionBreakpoint) breakpoint, marker);
				}
				else if (breakpoint instanceof IRLineBreakpoint) {
					newState= createState((IRLineBreakpoint) breakpoint, marker);
				}
				else {
					newState= null;
				}
				if (newState == null) {
					continue ITER_BREAKPOINTS;
				}
				
				List<TracepointState> list= this.stateUpdatesMap.get(marker.getResource());
				if (list == null) {
					list= new ArrayList<>(8);
					this.stateUpdatesMap.put(marker.getResource(), list);
				}
				for (int i= 0; i < list.size(); i++) {
					final TracepointState state= list.get(i);
					if (state.getId() == newState.getId()
							&& state.getType() == Tracepoint.TYPE_DELETED) {
						continue ITER_BREAKPOINTS;
					}
				}
				list.add(newState);
			}
			catch (final CoreException e) {
				logPrepareError(e, breakpoint);
			}
		}
		
		final List<TracepointState> list= new ArrayList<>();
		for (final Iterator<List<TracepointState>> iter= this.stateUpdatesMap.values().iterator();
				iter.hasNext(); ) {
			final TracepointState[] states;
			final List<TracepointState> statesList= iter.next();
			states= statesList.toArray(new @NonNull TracepointState[statesList.size()]);
			Arrays.sort(states);
			
			boolean delete= true;
			
			for (int i= 0; i < states.length; i++) {
				list.add(states[i]);
				if (states[i].getType() != Tracepoint.TYPE_DELETED) {
					delete= false;
				}
			}
			if (delete) {
				iter.remove();
			}
			else {
				statesList.clear();
			}
		}
		
		return list;
	}
	
	
	private void schedulePositionUpdate(final IRLineBreakpoint lineBreakpoint) {
		if (!contains(this.positionUpdatesBreakpoints, lineBreakpoint)) {
			this.positionUpdatesBreakpoints.add(lineBreakpoint);
		}
	}
	
	private void scheduleExceptionUpdate() {
		this.flagUpdateCheck= true;
	}
	
	private void scheduleStateUpdate(final IRBreakpoint lineBreakpoint) {
		if (!contains(this.stateUpdatesBreakpoints, lineBreakpoint)) {
			this.stateUpdatesBreakpoints.add(lineBreakpoint);
		}
	}
	
	private void checkUpdates() {
		if (!this.initialized) {
			return;
		}
		synchronized (this.stateUpdatesMap) {
			try {
				final List<TracepointState> states= getPendingTracepointStates();
				if (!states.isEmpty() && this.controller.getStatus() != ToolStatus.TERMINATED) {
					this.controller.exec(new TracepointStatesUpdate(states, false));
				}
			}
			catch (final CoreException e) {
				RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
						"An error occurred when updating breakpoint states in the R engine.", e));
			}
		}
		
		boolean scheduleInstall= false;
		synchronized (this.positionUpdatesLock) {
			scheduleInstall|= (!this.positionUpdatesBreakpoints.isEmpty());
		}
		synchronized (this.flagUpdateLock) {
			scheduleInstall|= (this.flagUpdateCheck);
		}
		if (scheduleInstall) {
			synchronized (this.updateRunnable) {
				if (!this.updateRunnableScheduled) {
					this.updateRunnableScheduled= true;
					this.controller.getTool().getQueue().addHot(this.updateRunnable);
				}
			}
		}
	}
	
	
	private boolean contains(final List<?> list, final Object object) {
		for (int i= 0; i < list.size(); i++) {
			if (list.get(i) == object) {
				return true;
			}
		}
		return false;
	}
	
	private boolean contains(final Object[] array, final Object object) {
		for (int i= 0; i < array.length; i++) {
			if (array[i] == object) {
				return true;
			}
		}
		return false;
	}
	
	private int getLineNumber(final IMarker marker, final @Nullable IMarkerPositionResolver resolver) {
		return (resolver != null) ?
				resolver.getLine(marker) :
				marker.getAttribute(IMarker.LINE_NUMBER, -1);
	}
	
	private boolean isScriptBreakpoint(final IRLineBreakpoint breakpoint) throws CoreException {
		return (breakpoint.getBreakpointType() == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
				&& breakpoint.getElementType() == IRLineBreakpoint.R_TOPLEVEL_COMMAND_ELEMENT_TYPE );
	}
	
	private boolean isElementBreakpoint(final IRLineBreakpoint breakpoint) throws CoreException {
		final int elementType;
		return ((breakpoint.getBreakpointType() == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID
					|| breakpoint.getBreakpointType() == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID )
				&& ((elementType= breakpoint.getElementType()) == IRLineBreakpoint.R_COMMON_FUNCTION_ELEMENT_TYPE
					|| elementType == IRLineBreakpoint.R_S4_METHOD_ELEMENT_TYPE ));
	}
	
	private @Nullable TracepointState createState(final IRLineBreakpoint breakpoint,
			final IMarker marker) throws CoreException {
		final int type;
		int flags= breakpoint.isEnabled() ? TracepointState.FLAG_ENABLED : 0;
		if (breakpoint.getBreakpointType() == RDebugModel.R_LINE_BREAKPOINT_TYPE_ID) {
			if (breakpoint.getElementType() == IRLineBreakpoint.R_TOPLEVEL_COMMAND_ELEMENT_TYPE) {
				type= Tracepoint.TYPE_TB;
			}
			else {
				type= Tracepoint.TYPE_LB;
			}
		}
		else if (breakpoint.getBreakpointType() == RDebugModel.R_METHOD_BREAKPOINT_TYPE_ID) {
			type= Tracepoint.TYPE_FB;
			final IRMethodBreakpoint methodBreakpoint= (IRMethodBreakpoint) breakpoint;
			if (methodBreakpoint.isEntry()) {
				flags |= TracepointState.FLAG_MB_ENTRY;
			}
			if (methodBreakpoint.isExit()) {
				flags |= TracepointState.FLAG_MB_EXIT;
			}
		}
		else {
			return null;
		}
		final String expr= (breakpoint.isConditionEnabled()) ?
				breakpoint.getConditionExpr() : null;
		
		final BreakpointTargetData breakpointData= (BreakpointTargetData) breakpoint.getTargetData(this.debugTarget);
		final ModelPosition modelPosition= RLineBreakpointValidator.getModelPosition(breakpoint);
		
		String elementId= null;
		String elementLabel= null;
		int[] index= null;
		if (breakpointData != null) {
			if (breakpointData.installed != null) {
				elementId= breakpointData.installed.elementId;
				elementLabel= breakpointData.installed.elementLabel;
			}
			if (breakpointData.latest != null
					&& elementId == null) {
				elementId= breakpointData.latest.elementId;
				elementLabel= breakpointData.latest.elementLabel;
			}
		}
		if (modelPosition != null) {
			if (elementId != null) {
				if (elementId.equals(modelPosition.getElementId())) {
					index= modelPosition.getRExpressionIndex();
				}
			}
			else {
				elementId= modelPosition.getElementId();
				index= modelPosition.getRExpressionIndex();
			}
		}
		if (elementLabel == null) {
			elementLabel= breakpoint.getSubLabel();
			if (elementLabel == null) {
				elementLabel= breakpoint.getElementLabel();
			}
		}
		
		if (elementId == null) {
			return null;
		}
		if (index == null) {
			index= new int[] { -1 };
		}
		
		return new TracepointState(type,
				marker.getResource().getFullPath().toPortableString(), marker.getId(),
				elementId, index, elementLabel, flags, expr);
	}
	
	private @Nullable TracepointState createState(final IRExceptionBreakpoint breakpoint,
			final IMarker marker) throws CoreException {
		final int type;
		final int flags= breakpoint.isEnabled() ? TracepointState.FLAG_ENABLED : 0;
		if (breakpoint.getBreakpointType() == RDebugModel.R_EXCEPTION_BREAKPOINT_TYPE_ID) {
			type= Tracepoint.TYPE_EB;
		}
		else {
			return null;
		}
		final String expr= null;
		
		final String exceptionId= breakpoint.getExceptionId();
		final String elementLabel= null;
		
		return new TracepointState(type, TracepointState.EB_FILEPATH, marker.getId(),
				exceptionId, elementLabel, flags, expr);
	}
	
	
	@Override
	public @Nullable Object toEclipseData(final TracepointEvent event) {
		try {
			final IRBreakpoint breakpoint= getRBreakpoint(event);
			String label= event.getLabel();
			if (event.getType() == Tracepoint.TYPE_EB) {
				if (label == null || label.equals("*")) {
					label= "error";
				}
			}
			else if (label == null && breakpoint instanceof IRLineBreakpoint) {
				final IRLineBreakpoint lineBreakpoint= (IRLineBreakpoint) breakpoint;
				final BreakpointTargetData breakpointData= (BreakpointTargetData) breakpoint.getTargetData(this.debugTarget);
				if (breakpointData != null && breakpointData.installed != null) {
					label= breakpointData.installed.elementLabel;
				}
				if (label == null) {
					try {
						label= lineBreakpoint.getSubLabel();
						if (label == null) {
							label= lineBreakpoint.getElementLabel();
						}
					}
					catch (final CoreException e) {}
				}
			}
			switch (event.getType()) {
			case Tracepoint.TYPE_FB:
				return new TracepointEventMethodBreakpointStatus(event, label, breakpoint);
			case Tracepoint.TYPE_EB:
				return new TracepointEventExceptionBreakpointStatus(event, label, breakpoint);
			default:
				return new TracepointEventBreakpointStatus(event, label, breakpoint);
			}
		}
		catch (final Exception e) {
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					"An error occurred when creating breakpoint status.", e ));
			return null;
		}
	}
	
	
	/** Call in R thread */
	public void dispose() {
		if (this.breakpointManager != null) {
			if (DebugPlugin.getDefault() != null) {
				this.breakpointManager.removeBreakpointManagerListener(this);
				this.breakpointManager.removeBreakpointListener(this);
				
				final IBreakpoint[] breakpoints= this.breakpointManager.getBreakpoints(
						RDebugModel.IDENTIFIER );
				for (int i= 0; i < breakpoints.length; i++) {
					if (breakpoints[i] instanceof IRBreakpoint) {
						final IRBreakpoint breakpoint= (IRBreakpoint) breakpoints[i];
						breakpoint.unregisterTarget(this.debugTarget);
					}
				}
			}
			this.breakpointManager= null;
		}
		synchronized (this.stateUpdatesLock) {
			this.stateUpdatesBreakpoints.clear();
		}
		synchronized (this.stateUpdatesMap) {
			this.stateUpdatesMap.clear();
		}
		synchronized (this.positionUpdatesLock) {
			this.positionUpdatesBreakpoints.clear();
			this.positionUpdatesElements.clear();
		}
	}
	
}
