### Eclipse Workspace Patch 1.0
#P org.jboss.tools.vpe
Index: src/org/jboss/tools/vpe/editor/VpeController.java
===================================================================
--- src/org/jboss/tools/vpe/editor/VpeController.java	(revision 37261)
+++ src/org/jboss/tools/vpe/editor/VpeController.java	(working copy)
@@ -14,6 +14,7 @@
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -85,7 +86,6 @@
 import org.jboss.tools.common.model.event.XModelTreeEvent;
 import org.jboss.tools.common.model.event.XModelTreeListener;
 import org.jboss.tools.common.model.project.IModelNature;
-import org.jboss.tools.common.model.ui.dnd.ModelTransfer;
 import org.jboss.tools.common.model.ui.util.ModelUtilities;
 import org.jboss.tools.common.model.util.EclipseResourceUtil;
 import org.jboss.tools.common.model.util.XModelTreeListenerSWTSync;
@@ -105,7 +105,6 @@
 import org.jboss.tools.vpe.dnd.VpeDnD;
 import org.jboss.tools.vpe.editor.context.VpePageContext;
 import org.jboss.tools.vpe.editor.mapping.VpeDomMapping;
-import org.jboss.tools.vpe.editor.mapping.VpeElementMapping;
 import org.jboss.tools.vpe.editor.mapping.VpeNodeMapping;
 import org.jboss.tools.vpe.editor.menu.VpeMenuCreator;
 import org.jboss.tools.vpe.editor.mozilla.MozillaEditor;
@@ -133,16 +132,6 @@
 import org.jboss.tools.vpe.editor.util.DocTypeUtil;
 import org.jboss.tools.vpe.editor.util.SelectionUtil;
 import org.jboss.tools.vpe.editor.util.VisualDomUtil;
-import org.jboss.tools.vpe.editor.util.VpeDebugUtil;
-import org.jboss.tools.vpe.editor.util.VpeNodesManagingUtil;
-import org.jboss.tools.vpe.handlers.PageDesignOptionsHandler;
-import org.jboss.tools.vpe.handlers.PreferencesHandler;
-import org.jboss.tools.vpe.handlers.RefreshHandler;
-import org.jboss.tools.vpe.handlers.RotateEditorsHandler;
-import org.jboss.tools.vpe.handlers.ShowBorderHandler;
-import org.jboss.tools.vpe.handlers.ShowBundleAsELHandler;
-import org.jboss.tools.vpe.handlers.ShowNonVisualTagsHandler;
-import org.jboss.tools.vpe.handlers.ShowTextFormattingHandler;
 import org.jboss.tools.vpe.handlers.VisualPartAbstractHandler;
 import org.jboss.tools.vpe.messages.VpeUIMessages;
 import org.jboss.tools.vpe.resref.core.AbsoluteFolderReferenceList;
@@ -165,6 +154,7 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
+@SuppressWarnings({ "restriction", "deprecation" })
 public class VpeController implements INodeAdapter,
 		IModelLifecycleListener, INodeSelectionListener,
 		ITextSelectionListener, SelectionListener,
@@ -175,7 +165,6 @@
 		MozillaContextMenuListener, MozillaResizeListener,
 		MozillaAfterPaintListener, MozillaScrollListener {
 
-	public static final int DEFAULT_UPDATE_DELAY_TIME = 400;
 	private boolean visualEditorVisible = true;
 	private boolean synced = true;
 	StructuredTextEditor sourceEditor;
@@ -190,7 +179,7 @@
 	private VpeVisualDomBuilder visualBuilder;
 	private VpeDnD vpeDnD;
 	// private VpeVisualKeyHandler visualKeyHandler;
-	private ActiveEditorSwitcher switcher = new ActiveEditorSwitcher();
+	private ActiveEditorSwitcher switcher;
 	private Attr lastRemovedAttr;
 	private String lastRemovedAttrName;
 	private boolean mouseUpSelectionReasonFlag;
@@ -213,7 +202,7 @@
 	private XModelTreeListenerSWTSync optionsListener;
 	// Added by Max Areshkau Fix for JBIDE-1479
 	private UIJob job = null;
-	private UIJob uiJob;
+	private VpeUpdateJob uiJob;
 	// JBIDE-675, visual refresh job
 	private UIJob visualRefreshJob;
 	private UIJob reinitJob;
@@ -225,7 +214,7 @@
 	 * Added by Max Areshkau JBIDE-675, stores information about modification
 	 * events
 	 */
-	private LinkedList<VpeEventBean> changeEvents;
+	private List<VpeEventBean> changeEvents;
 
 	Shell tip;
 
@@ -239,14 +228,12 @@
 	 */
 	private IKeyEventHandler keyEventHandler;
 
-	// contains vpe update delau time in miliseconds
-	private int vpeUpdateDelayTime;
-
 	private ListenerList updateListeners = new ListenerList();
 	
 	public VpeController(VpeEditorPart editPart) {
 
 		this.editPart = editPart;
+		this.switcher = new ActiveEditorSwitcher(this, editPart);
 		dropWindow = new VpeDropWindow(editPart.getSite().getShell());
 	}
 
@@ -370,9 +357,6 @@
 		elReferenceListListener = ELReferenceList.getInstance();
 		elReferenceListListener.addChangeListener(this);
 
-		// initialization of vpe update delay time
-		vpeUpdateDelayTime = DEFAULT_UPDATE_DELAY_TIME;
-
 		// pageContext.fireTaglibsChanged();
 
 		// yradtsevich: we have to refresh VPE selection on init (fix of
@@ -530,23 +514,13 @@
 			display = PlatformUI.getWorkbench().getDisplay();
 
 		if (display != null && (Thread.currentThread() == display.getThread())) {
-			getChangeEvents().addLast(
-					new VpeEventBean(notifier, eventType, feature, oldValue,
-							newValue, pos));
+			getChangeEvents().add(new VpeEventBean(notifier, eventType, feature, oldValue, newValue, pos));
 			if (uiJob == null) {
-				uiJob = new VPEUpdateJob(VpeUIMessages.VPE_UPDATE_JOB_TITLE);
-			}
-
-			if (uiJob.getState() != Job.RUNNING) {
+				uiJob = new VpeUpdateJob(this, switcher);
 				uiJob.setPriority(Job.LONG);
-				// Fix of JBIDE-1900
-				uiJob.schedule(getVpeUpdateDelayTime());
-			} else {
-				uiJob.cancel();
-				uiJob.schedule(getVpeUpdateDelayTime());
-				setVpeUpdateDelayTime(400);
 			}
-
+			uiJob.interrupt();
+			uiJob.execute();
 			return;
 		}
 		// start job when we modify file in non ui thread
@@ -571,6 +545,11 @@
 		job.schedule(1000L);
 	}
 
+	public void notifyChangedInUiThread(VpeEventBean eventBean) {
+		notifyChangedInUiThread(eventBean.getNotifier(), eventBean.getEventType(), eventBean.getFeature(),
+			eventBean.getOldValue(), eventBean.getNewValue(), eventBean.getPos());
+	}
+
 	public void notifyChangedInUiThread(INodeNotifier notifier, int eventType,
 			Object feature, Object oldValue, Object newValue, int pos) {
 		if (switcher == null
@@ -587,6 +566,8 @@
 				return;
 			}
 			// visualBuilder.rebuildFlag = false;
+			boolean rebuildWholeDocumentFlag = false;
+			final int oldSize = getChangeEvents().size();
 			switch (eventType) {
 			case INodeNotifier.CHANGE:
 				sourceChangeFlag = true;
@@ -599,12 +580,13 @@
 					boolean update = visualBuilder.setText((Node) notifier);
 					visualEditor.showResizer();
 					// Added by Max Areshkau JBIDE-1554
-					if (!update)
-						visualBuilder.updateNode((Node) notifier);
+					if (!update) {
+						rebuildWholeDocumentFlag = visualBuilder.updateNode((Node) notifier);
+					}
 				} else if (type == Node.COMMENT_NODE) {
 					if ("yes".equals(VpePreference.SHOW_COMMENTS.getValue())) { //$NON-NLS-1$
 						visualBuilder.clearSelectionRectangle();
-						visualBuilder.updateNode((Node) notifier);
+						rebuildWholeDocumentFlag = visualBuilder.updateNode((Node) notifier);
 					}
 				} else if (feature != null
 						&& ((Node) feature).getNodeType() == Node.ATTRIBUTE_NODE) {
@@ -613,7 +595,7 @@
 						if ((Attr) feature == lastRemovedAttr
 								&& !attrName.equals(lastRemovedAttrName)) {
 							lastRemovedAttr = null;
-							visualBuilder.removeAttribute((Element) notifier,
+							rebuildWholeDocumentFlag = visualBuilder.removeAttribute((Element) notifier,
 									lastRemovedAttrName);
 						}
 						visualBuilder.setAttribute((Element) notifier,
@@ -621,7 +603,7 @@
 					} else {
 						lastRemovedAttr = (Attr) feature;
 						lastRemovedAttrName = ((Attr) feature).getName();
-						visualBuilder.removeAttribute((Element) notifier,
+						rebuildWholeDocumentFlag = visualBuilder.removeAttribute((Element) notifier,
 								lastRemovedAttrName);
 					}
 				}
@@ -653,7 +635,7 @@
 				 */
 				if (Node.COMMENT_NODE == ((Node) feature).getNodeType()) {
 					commentRemoveCount++;
-					visualBuilder.updateNode((Node) feature);
+					rebuildWholeDocumentFlag = visualBuilder.updateNode((Node) feature);
 					commentNodeChanged = true;
 				} else {
 					commentRemoveCount--;
@@ -675,7 +657,7 @@
 				if (!commentNodeChanged ||(commentNodeChanged && (commentAddCount != 1 || commentRemoveCount != 1))) {
 					visualEditor.hideResizer();
 					visualBuilder.clearSelectionRectangle();
-					visualBuilder.updateNode((Node) notifier);
+					rebuildWholeDocumentFlag = visualBuilder.updateNode((Node) notifier);
 				} else {
 					commentNodeChanged = false;
 				}
@@ -701,6 +683,12 @@
 				}
 				break;
 			}
+			if (rebuildWholeDocumentFlag) {
+				// whole document rebuild occur -> so cleanup change events queue
+				if (oldSize == getChangeEvents().size()) {
+					getChangeEvents().clear();
+				}
+			}
 		} finally {
 			// fix for jbide-675, swithcer is null when vpecontroller is
 			// disposed
@@ -1204,11 +1192,11 @@
 	public void keyPress(nsIDOMKeyEvent keyEvent) {
 		if (VpeDebug.PRINT_VISUAL_KEY_EVENT) {
 			System.out.println("<<< keyPress  type: " + keyEvent.getType() + //$NON-NLS-1$
-					"  Ctrl: "
+					"  Ctrl: " //$NON-NLS-1$
 					+ keyEvent.getCtrlKey()
-					+ "  Shift: " + keyEvent.getShiftKey() + //$NON-NLS-1$ //$NON-NLS-2$
-					"  CharCode: " + keyEvent.getCharCode()
-					+ "  KeyCode: " + keyEvent.getKeyCode()); //$NON-NLS-1$ //$NON-NLS-2$
+					+ "  Shift: " + keyEvent.getShiftKey() + //$NON-NLS-1$
+					"  CharCode: " + keyEvent.getCharCode()  //$NON-NLS-1$
+					+ "  KeyCode: " + keyEvent.getKeyCode()); //$NON-NLS-1$
 		}
 		if (!switcher
 				.startActiveEditor(ActiveEditorSwitcher.ACTIVE_EDITOR_VISUAL)) {
@@ -1220,7 +1208,6 @@
 		} finally {
 			switcher.stopActiveEditor();
 		}
-		setVpeUpdateDelayTime(0);
 		/*
 		 * adding calls of core event handlers, for example' CTR+H' or 'CTRL+M'
 		 * event handler dialog
@@ -1519,128 +1506,6 @@
 		System.out.println();
 	}
 
-	private class VPEUpdateJob extends UIJob {
-		private boolean cancelled = false;
-		
-		final static int MAX_EVENTS_TILL_REFRESH = 30;
-		
-		private VPEUpdateJob(String name) {
-			super(name);
-		}
-
-		@Override
-		public IStatus runInUIThread(IProgressMonitor monitor) {
-			cancelled=false;
-			monitor.beginTask(VpeUIMessages.VPE_UPDATE_JOB_TITLE,
-					100);
-			while (getChangeEvents().size() > 0) {
-				if (monitor.isCanceled() || cancelled) {
-					return Status.CANCEL_STATUS;
-				}
-				
-				if (changeEvents.size() > MAX_EVENTS_TILL_REFRESH) {
-					monitor.worked((int) (10000 / 2));
-					System.out.println("full refresh is started");
-					reinitImpl();
-					System.out.println("full refresh is finished");
-					monitor.worked(10000);
-					changeEvents.clear();
-					return Status.OK_STATUS;
-				}
-				
-				monitor.worked((int) (100 / getChangeEvents().size()));
-				VpeEventBean eventBean = getChangeEvents().getFirst();
-				try {
-					notifyChangedInUiThread(
-							eventBean.getNotifier(), eventBean
-									.getEventType(), eventBean
-									.getFeature(), eventBean
-									.getOldValue(), eventBean
-									.getNewValue(), eventBean
-									.getPos());
-				} catch (VpeDisposeException ex) {
-					// JBIDE-675 we will get this exception if user
-					// close editor,
-					// when update visual editor job is running, we
-					// shoud ignore this
-					// exception
-					break;
-				} catch (NullPointerException ex) {
-					if (switcher != null) {
-						throw ex;
-					} else {
-						// class was disposed and exception result
-						// of that we can't stop
-						// refresh job in time, so we just ignore
-						// this exception
-					}
-				} catch(RuntimeException ex) {
-					VpePlugin.getPluginLog().logError(ex);
-				} finally {
-					getChangeEvents().remove(eventBean);
-				}
-			}
-			// cause is to lock calls others events
-			if (switcher != null && switcher.startActiveEditor(ActiveEditorSwitcher.ACTIVE_EDITOR_SOURCE))
-				try {
-					sourceSelectionChanged();
-					/*
-					 * https://jira.jboss.org/jira/browse/JBIDE-3619
-					 * VpeViewUpdateJob takes place after toolbar
-					 * selection have been updated. New nodes
-					 * haven't been put into dom mapping thus
-					 * toolbar becomes desabled. Updating toolbar
-					 * state here takes into account updated vpe
-					 * nodes.
-					 */
-					if (toolbarFormatControllerManager != null) {
-						toolbarFormatControllerManager.selectionChanged();
-					}
-				} finally {
-					switcher.stopActiveEditor();
-				}
-			monitor.done();
-			notifyVpeUpdateListeners();
-			return Status.OK_STATUS;
-		}
-
-		protected void canceling() {
-			this.cancelled  = true;
-		}
-	}
-
-	public class ActiveEditorSwitcher {
-		public static final int ACTIVE_EDITOR_CANNOT = 0;
-		public static final int ACTIVE_EDITOR_NONE = 1;
-		public static final int ACTIVE_EDITOR_SOURCE = 2;
-		public static final int ACTIVE_EDITOR_VISUAL = 3;
-
-		private int type = ACTIVE_EDITOR_CANNOT;
-
-		private void initActiveEditor() {
-			type = ACTIVE_EDITOR_NONE;
-		}
-
-		private void destroyActiveEditor() {
-			type = ACTIVE_EDITOR_CANNOT;
-		}
-
-		public boolean startActiveEditor(int newType) {
-			if (type != ACTIVE_EDITOR_NONE || type == ACTIVE_EDITOR_NONE && newType == ACTIVE_EDITOR_SOURCE
-				&& editPart.getVisualMode() == VpeEditorPart.SOURCE_MODE) {
-				return false;
-			} else {
-				type = newType;
-				return true;
-			}
-		}
-
-		public void stopActiveEditor() {
-			onRefresh();
-			type = ACTIVE_EDITOR_NONE;
-		}
-	}
-
 	void refreshTemplates() {
 		if (includeList.includesRefresh()) {
 			visualRefresh();
@@ -2079,11 +1944,9 @@
 	/**
 	 * @return the changeEvents
 	 */
-	public LinkedList<VpeEventBean> getChangeEvents() {
-
+	public List<VpeEventBean> getChangeEvents() {
 		if (changeEvents == null) {
-
-			changeEvents = new LinkedList<VpeEventBean>();
+			changeEvents = Collections.synchronizedList(new LinkedList<VpeEventBean>());
 		}
 		return changeEvents;
 	}
@@ -2099,6 +1962,7 @@
 				if (monitor.isCanceled()) {
 					return Status.CANCEL_STATUS;
 				}
+				getChangeEvents().clear();
 				reinitImpl();
 				return Status.OK_STATUS;
 			}
@@ -2106,7 +1970,7 @@
 		reinitJob.schedule();
 	}
 
-	private void reinitImpl() {
+	void reinitImpl() {
 		try {
 			if (switcher == null
 					|| !switcher
@@ -2217,21 +2081,6 @@
 	}
 
 	/**
-	 * @return the vpeUpdateDelayTime
-	 */
-	private int getVpeUpdateDelayTime() {
-		return vpeUpdateDelayTime;
-	}
-
-	/**
-	 * @param vpeUpdateDelayTime
-	 *            the vpeUpdateDelayTime to set
-	 */
-	private void setVpeUpdateDelayTime(int vpeUpdateDelayTime) {
-		this.vpeUpdateDelayTime = vpeUpdateDelayTime;
-	}
-
-	/**
 	 * @return the selectionManager
 	 */
 	public ISelectionManager getSelectionManager() {
@@ -2270,7 +2119,7 @@
 		updateListeners.remove(listener);
 	}
 
-	private void notifyVpeUpdateListeners() {
+	void notifyVpeUpdateListeners() {
 		for (Object listener : updateListeners.getListeners()) {
 			((IVpeUpdateListener) listener).vpeUpdated();
 		}
Index: src/org/jboss/tools/vpe/editor/ActiveEditorSwitcher.java
===================================================================
--- src/org/jboss/tools/vpe/editor/ActiveEditorSwitcher.java	(revision 0)
+++ src/org/jboss/tools/vpe/editor/ActiveEditorSwitcher.java	(working copy)
@@ -0,0 +1,40 @@
+package org.jboss.tools.vpe.editor;
+
+public class ActiveEditorSwitcher {
+	public static final int ACTIVE_EDITOR_CANNOT = 0;
+	public static final int ACTIVE_EDITOR_NONE = 1;
+	public static final int ACTIVE_EDITOR_SOURCE = 2;
+	public static final int ACTIVE_EDITOR_VISUAL = 3;
+
+	private int type = ACTIVE_EDITOR_CANNOT;
+	private VpeController vpeController;
+	private VpeEditorPart editPart;
+	
+	public ActiveEditorSwitcher(VpeController vpeController, VpeEditorPart editPart) {
+		this.vpeController = vpeController;
+		this.editPart = editPart;
+	}
+
+	public void initActiveEditor() {
+		type = ACTIVE_EDITOR_NONE;
+	}
+
+	public void destroyActiveEditor() {
+		type = ACTIVE_EDITOR_CANNOT;
+	}
+
+	public boolean startActiveEditor(int newType) {
+		if (type != ACTIVE_EDITOR_NONE || type == ACTIVE_EDITOR_NONE && newType == ACTIVE_EDITOR_SOURCE
+			&& editPart.getVisualMode() == VpeEditorPart.SOURCE_MODE) {
+			return false;
+		} else {
+			type = newType;
+			return true;
+		}
+	}
+
+	public void stopActiveEditor() {
+		vpeController.onRefresh();
+		type = ACTIVE_EDITOR_NONE;
+	}
+}
Index: src/org/jboss/tools/vpe/editor/VpeVisualDomBuilder.java
===================================================================
--- src/org/jboss/tools/vpe/editor/VpeVisualDomBuilder.java	(revision 37460)
+++ src/org/jboss/tools/vpe/editor/VpeVisualDomBuilder.java	(working copy)
@@ -81,6 +81,7 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
+@SuppressWarnings("restriction")
 public class VpeVisualDomBuilder extends VpeDomBuilder {
     public static final String VPE_USER_TOGGLE_ID = "vpe-user-toggle-id"; //$NON-NLS-1$
 	public static final String VPE_USER_TOGGLE_LOOKUP_PARENT = "vpe-user-toggle-lookup-parent"; //$NON-NLS-1$
@@ -776,21 +777,26 @@
 
 	// ==========================================================
 
-	public void updateNode(Node sourceNode) {
+	// return true in case if rebuild whole document occur
+	public boolean updateNode(Node sourceNode) {
+		boolean res = false;
 		if (sourceNode == null) {
-			return;
+			return res;
 		}
 
 		switch (sourceNode.getNodeType()) {
 		case Node.DOCUMENT_NODE:
 			rebuildDom((Document) sourceNode);
+			res = true;
 			break;
 		default:
-			updateElement(sourceNode);
+			res = updateElement(sourceNode);
 		}
+		return res;
 	}
 
-	private void updateElement(Node sourceNode) {
+	// return true in case if rebuild whole document occur
+	private boolean updateElement(Node sourceNode) {
 		VpeElementMapping elementMapping = null;
 		VpeNodeMapping nodeMapping = domMapping.getNodeMapping(sourceNode);
 		if (nodeMapping instanceof VpeElementMapping) {
@@ -804,7 +810,7 @@
 				 */
 				if (HTML.TAG_STYLE.equalsIgnoreCase(sourceNode.getNodeName())) {
 					VpeStyleUtil.refreshStyleElement(this, elementMapping);
-					return;
+					return false;
 				}
 				Node updateNode = elementMapping.getTemplate()
 						.getNodeForUpdate(pageContext,
@@ -812,11 +818,11 @@
 								elementMapping.getVisualNode(),
 								elementMapping.getData());
 				if ((updateNode != null) && (updateNode != sourceNode)) {
-					updateNode(updateNode);
-					return;
+					return updateNode(updateNode);
 				}
 			}
 		}
+		boolean res = false;
 		/*
 		 * 1) Remove source node from mappings and lists.
 		 */
@@ -843,11 +849,12 @@
 			// node?
 			// looks like we haven't need do it.
 			if (sourceNode.getNodeType() == Node.TEXT_NODE) {
-				updateNode(sourceNode.getParentNode());
-			}else if(HTML.TAG_LINK.equalsIgnoreCase(sourceNode.getNodeName())) {
+				res = updateNode(sourceNode.getParentNode());
+			} else if(HTML.TAG_LINK.equalsIgnoreCase(sourceNode.getNodeName())) {
 				addNode(sourceNode, null, getHeadNode());
 			}
 		}
+		return res;
 	}
 
 	public void removeNode(Node sourceNode) {
@@ -902,16 +909,19 @@
 		return false;
 	}
 
-	public void setAttribute(Element sourceElement, String name, String value) {
+	// return true in case if rebuild whole document occur
+	public boolean setAttribute(Element sourceElement, String name, String value) {
 		VpeElementMapping elementMapping = (VpeElementMapping) domMapping
 				.getNodeMapping(sourceElement);
 		/*
 		 * https://jira.jboss.org/jira/browse/JBIDE-4110
 		 * Update any template automatically on attribute adding.
 		 */
+		boolean res = false;
 		if (elementMapping != null) {
-		    updateElement(sourceElement);
+			res = updateElement(sourceElement);
 		}
+		return res;
 	}
 
 	public void stopToggle(Node sourceNode) {
@@ -1034,16 +1044,19 @@
 		return null;
 	}
 
-	public void removeAttribute(Element sourceElement, String name) {
+	// return true in case if rebuild whole document occur
+	public boolean removeAttribute(Element sourceElement, String name) {
 		VpeElementMapping elementMapping = (VpeElementMapping) domMapping
 				.getNodeMapping(sourceElement);
 		/*
 		 * https://jira.jboss.org/jira/browse/JBIDE-4110
 		 * Update any template automatically on attribute deleting.
 		 */
+		boolean res = false;
 		if (elementMapping != null) {
-		    updateElement(sourceElement);
+			res = updateElement(sourceElement);
 		}
+		return res;
 	}
 
 	public void refreshBundleValues(Element sourceElement) {
Index: src/org/jboss/tools/vpe/editor/VpeUpdateJob.java
===================================================================
--- src/org/jboss/tools/vpe/editor/VpeUpdateJob.java	(revision 0)
+++ src/org/jboss/tools/vpe/editor/VpeUpdateJob.java	(working copy)
@@ -0,0 +1,116 @@
+package org.jboss.tools.vpe.editor;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.progress.UIJob;
+import org.jboss.tools.vpe.VpePlugin;
+import org.jboss.tools.vpe.editor.toolbar.format.FormatControllerManager;
+import org.jboss.tools.vpe.messages.VpeUIMessages;
+
+public class VpeUpdateJob extends UIJob {
+	
+	protected boolean execState = false;
+	
+	protected VpeController vpeController;
+	protected ActiveEditorSwitcher switcher;
+
+	public VpeUpdateJob(VpeController vpeController, ActiveEditorSwitcher switcher) {
+		super(VpeUIMessages.VPE_UPDATE_JOB_TITLE);
+		this.vpeController = vpeController;
+		this.switcher = switcher;
+	}
+
+	protected synchronized void setExecState(boolean execState) {
+		this.execState = execState;
+	}
+
+	protected synchronized boolean isExecState() {
+		return execState;
+	}
+	
+	public void interrupt() {
+		setExecState(false);
+	}
+	
+	public void execute() {
+		setExecState(true);
+		schedule();
+	}
+
+	@Override
+	public IStatus runInUIThread(IProgressMonitor monitor) {
+		IStatus res = Status.OK_STATUS;
+		/**/
+		final int totalWork = 10000;
+		final int maxQueue4WholeRefresh = 30;
+		monitor.beginTask(VpeUIMessages.VPE_UPDATE_JOB_TITLE, totalWork);
+		final List<VpeEventBean> changeEvents = vpeController.getChangeEvents();
+		while (changeEvents.size() > 0) {
+			if (!isExecState()) {
+				break;
+			}
+			if (changeEvents.size() > maxQueue4WholeRefresh) {
+				changeEvents.clear();
+				monitor.worked((int) (totalWork / 2));
+				vpeController.reinitImpl();
+				monitor.worked(totalWork);
+				break;
+			}
+			monitor.worked((int) (totalWork / changeEvents.size()));
+			VpeEventBean eventBean = changeEvents.remove(0);
+			if (monitor.isCanceled()) {
+				// Yahor Radtsevich: the following line is commented as fix of JBIDE-3758: VPE autorefresh is broken in
+				// some cases. Now if the change events queue should be cleared, the user have to do it explicitly.
+				// getChangeEvents().clear();
+				res = Status.CANCEL_STATUS;
+				break;
+			}
+			try {
+				vpeController.notifyChangedInUiThread(eventBean);
+			} catch (VpeDisposeException ex) {
+				// JBIDE-675 we will get this exception if user
+				// close editor,
+				// when update visual editor job is running, we
+				// shoud ignore this
+				// exception
+				break;
+			} catch (NullPointerException ex) {
+				if (switcher != null) {
+					throw ex;
+				} else {
+					// class was disposed and exception result
+					// of that we can't stop
+					// refresh job in time, so we just ignore
+					// this exception
+				}
+			} catch (RuntimeException ex) {
+				VpePlugin.getPluginLog().logError(ex);
+			}
+		}
+		if (isExecState() && res == Status.OK_STATUS) {
+			// cause is to lock calls others events
+			if (switcher != null && switcher.startActiveEditor(ActiveEditorSwitcher.ACTIVE_EDITOR_SOURCE)) {
+				try {
+					vpeController.sourceSelectionChanged();
+					// https://jira.jboss.org/jira/browse/JBIDE-3619 VpeViewUpdateJob takes place after toolbar selection
+					// have been updated. New nodes haven't been put into dom mapping thus toolbar becomes desabled.
+					// Updating toolbar state here takes into account updated vpe nodes.
+					final FormatControllerManager tfcm = vpeController.getToolbarFormatControllerManager();
+					if (tfcm != null) {
+						tfcm.selectionChanged();
+					}
+				} finally {
+					switcher.stopActiveEditor();
+				}
+			}
+		}
+		/**/
+		monitor.done();
+		vpeController.notifyVpeUpdateListeners();
+		return res;
+	}
+
+}
