/*******************************************************************************
 *  Copyright (c) 2006, 2015 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *     Teodor Madan (Freescale) -  Bug 292360 -  [Memory View] platform renderings do not implement correctly IMemoryRendering#getControl
 *     Teodor Madan (Freescale) -  Bug 292426 -  [Memory View] platform renderings cannot be repositioned from non-UI thread through calls to IRepositionableMemoryRendering#goToAddress
 *     Teodor Madan (Freescale) & Jeremiah Swan (IBM) - Bug 300036 -  [Memory View] NPE in AbstractAsyncTableRendering#getSelectedAddress on rendering creation
 *******************************************************************************/

package org.eclipse.debug.internal.ui.memory.provisional;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.core.model.MemoryByte;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugUIMessages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.memory.IPersistableDebugElement;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IStatusMonitor;
import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractBaseTableRendering;
import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractVirtualContentTableModel;
import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncCopyTableRenderingAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncPrintTableRenderingAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncTableRenderingCellModifier;
import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncTableRenderingViewer;
import org.eclipse.debug.internal.ui.views.memory.renderings.CopyTableRenderingToClipboardAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.FormatTableRenderingAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.FormatTableRenderingDialog;
import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite;
import org.eclipse.debug.internal.ui.views.memory.renderings.IPresentationErrorListener;
import org.eclipse.debug.internal.ui.views.memory.renderings.IVirtualContentListener;
import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment;
import org.eclipse.debug.internal.ui.views.memory.renderings.PendingPropertyChanges;
import org.eclipse.debug.internal.ui.views.memory.renderings.PrintTableRenderingAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.ReformatAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.ResetToBaseAddressAction;
import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingContentDescriptor;
import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingLine;

import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.memory.AbstractTableRendering;
import org.eclipse.debug.ui.memory.IMemoryBlockTablePresentation;
import org.eclipse.debug.ui.memory.IMemoryRendering;
import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
import org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService;
import org.eclipse.debug.ui.memory.IMemoryRenderingType;
import org.eclipse.debug.ui.memory.IResettableMemoryRendering;
import org.eclipse.debug.ui.memory.MemoryRenderingElement;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.TextViewer;

import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.IBasicPropertyConstants;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TextCellEditor;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.progress.UIJob;

/**
 * Abstract implementation of a table rendering.
 * <p>
 * Clients should subclass from this class if they wish to provide a table
 * rendering.
 * </p>
 * <p>
 *
 * The label of the rendering is constructed by retrieving the expression from
 * <code>IMemoryBlockExtension</code>. For IMemoryBlock, the label is
 * constructed using the memory block's start address.
 *
 * This rendering manages the change states of its memory bytes if the memory
 * block does not opt to manage the change states. For IMemoryBlockExtension, if
 * the memory block returns false when #supportsChangeManagement() is called,
 * this rendering will calculate the change state for each byte when its content
 * is updated. Clients may manages the change states of its memory block by
 * returning true when #supportsChangeManagement() is called. This will cause
 * this rendering to stop calculating the change states of the memory block.
 * Instead it would rely on the attributes returned in the MemoryByte array to
 * determine if a byte has changed. For IMemoryBlock, this rendering will manage
 * the change states its content.
 *
 * When firing change event, be aware of the following: - whenever a change
 * event is fired, the content provider for Memory View view checks to see if
 * memory has actually changed. - If memory has actually changed, a refresh will
 * commence. Changes to the memory block will be computed and will be shown with
 * the delta icons. - If memory has not changed, content will not be refreshed.
 * However, previous delta information will be erased. The screen will be
 * refreshed to show that no memory has been changed. (All delta icons will be
 * removed.)
 *
 * Please note that these APIs will be called multiple times by the Memory View.
 * To improve performance, debug adapters need to cache the content of its
 * memory block and only retrieve updated data when necessary.
 * </p>
 *
 * @since 3.2
 */
public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRendering implements IPropertyChangeListener, IResettableMemoryRendering {

	/**
	 * Property identifier for the selected address in a table rendering This
	 * property is used for synchronization between renderings.
	 */
	public static final String PROPERTY_SELECTED_ADDRESS = AbstractTableRendering.PROPERTY_SELECTED_ADDRESS;

	/**
	 * Property identifier for the column size in a table rendering This
	 * property is used for synchronization between renderings.
	 */
	public static final String PROPERTY_COL_SIZE = AbstractTableRendering.PROPERTY_COL_SIZE;

	/**
	 * Property identifier for the top row address in a table rendering. This
	 * property is used for synchronization between renderings.
	 */
	public static final String PROPERTY_TOP_ADDRESS = AbstractTableRendering.PROPERTY_TOP_ADDRESS;

	private static final String ID_ASYNC_TABLE_RENDERING_CONTEXT = "org.eclipse.debug.ui.memory.abstractasynctablerendering"; //$NON-NLS-1$
	private static final String ID_GO_TO_ADDRESS_COMMAND = "org.eclipse.debug.ui.command.gotoaddress"; //$NON-NLS-1$
	private static final String ID_NEXT_PAGE_COMMAND = "org.eclipse.debug.ui.command.nextpage"; //$NON-NLS-1$
	private static final String ID_PREV_PAGE_COMMAND = "org.eclipse.debug.ui.command.prevpage"; //$NON-NLS-1$

	/**
	 * Property identifier for the row size in a table rendering This property
	 * is used for synchronization between renderings.
	 */
	public static final String PROPERTY_ROW_SIZE = AbstractTableRendering.PROPERTY_ROW_SIZE;

	private static final int DEFAULT_BUFFER_THRESHOLD = 1;

	private boolean fActivated = false;

	// TODO: review use of MemorySegment, need to be careful to ensure flexible
	// hierarchy

	private class ToggleAddressColumnAction extends Action {

		public ToggleAddressColumnAction() {
			super();
			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".ShowAddressColumnAction_context"); //$NON-NLS-1$
			updateActionLabel();
		}

		/*
		 * (non-Javadoc)
		 * @see org.eclipse.jface.action.IAction#run()
		 */
		@Override
		public void run() {
			fIsShowAddressColumn = !fIsShowAddressColumn;
			if (!fIsShowAddressColumn) {
				fTableViewer.getTable().getColumn(0).setWidth(0);
			} else {
				fTableViewer.getTable().getColumn(0).pack();
			}
			updateActionLabel();
		}

		/**
		 *
		 */
		private void updateActionLabel() {
			if (fIsShowAddressColumn) {
				setText(DebugUIMessages.ShowAddressColumnAction_0);
			} else {
				setText(DebugUIMessages.ShowAddressColumnAction_1);
			}
		}
	}

	private class NextPageAction extends Action {
		private NextPageAction() {
			super();
			setText(DebugUIMessages.AbstractTableRendering_4);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".NextPageAction_context"); //$NON-NLS-1$
		}

		@Override
		public void run() {
			BigInteger address = fContentDescriptor.getLoadAddress();
			address = address.add(BigInteger.valueOf(getPageSizeInUnits()));
			handlePageStartAddressChanged(address);
		}
	}

	private class PrevPageAction extends Action {
		private PrevPageAction() {
			super();
			setText(DebugUIMessages.AbstractTableRendering_6);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".PrevPageAction_context"); //$NON-NLS-1$
		}

		@Override
		public void run() {
			BigInteger address = fContentDescriptor.getLoadAddress();
			address = address.subtract(BigInteger.valueOf(getPageSizeInUnits()));
			handlePageStartAddressChanged(address);
		}
	}

	private class RenderingGoToAddressAction extends GoToAddressAction {
		public RenderingGoToAddressAction(IMemoryRenderingContainer container, AbstractBaseTableRendering rendering) {
			super(container, rendering);
		}

		@Override
		public void run() {
			showGoToAddressComposite();
		}
	}

	private class SwitchPageJob extends UIJob {
		private Object fLock = new Object();
		private boolean fShowMessagePage = false;
		private String fMessage = IInternalDebugCoreConstants.EMPTY_STRING;

		private SwitchPageJob() {
			super("SwitchPageJob");//$NON-NLS-1$
			setSystem(true);
		}

		private void setShowMessagePage(boolean showMsg) {
			synchronized (fLock) {
				fShowMessagePage = showMsg;
			}
		}

		private void setMessage(String message) {
			synchronized (fLock) {
				fMessage = message;
			}
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {

			if (fPageBook.isDisposed()) {
				return Status.OK_STATUS;
			}

			String msgToShow = null;
			boolean showMsgPage = false;
			synchronized (fLock) {
				msgToShow = fMessage;
				showMsgPage = fShowMessagePage;
			}

			if (showMsgPage) {
				StyledText styleText = null;
				fShowMessage = true;

				styleText = fTextViewer.getTextWidget();

				if (styleText != null) {
					styleText.setText(msgToShow);
				}
				fPageBook.showPage(fTextViewer.getControl());
			} else {
				fShowMessage = false;
				fPageBook.showPage(fTableViewer.getControl().getParent());
			}
			return Status.OK_STATUS;
		}
	}

	private class SerialByObjectRule implements ISchedulingRule {
		private Object fObject = null;

		public SerialByObjectRule(Object lock) {
			fObject = lock;
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse
		 * .core.runtime.jobs.ISchedulingRule)
		 */
		@Override
		public boolean contains(ISchedulingRule rule) {
			return rule == this;
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse
		 * .core.runtime.jobs.ISchedulingRule)
		 */
		@Override
		public boolean isConflicting(ISchedulingRule rule) {
			if (rule instanceof SerialByObjectRule) {
				SerialByObjectRule rRule = (SerialByObjectRule) rule;
				return fObject == rRule.fObject;
			}
			return false;
		}
	}

	private PageBook fPageBook;
	private AsyncTableRenderingViewer fTableViewer;
	private TextViewer fTextViewer;
	private Shell fToolTipShell;
	private MemoryViewPresentationContext fPresentationContext;
	private int fAddressableSize;
	private TableRenderingContentDescriptor fContentDescriptor;
	private int fBytePerLine;
	private int fColumnSize;
	private boolean fShowMessage = false;
	private String fLabel;
	private IWorkbenchAdapter fWorkbenchAdapter;
	private int fPageSize;
	private int fPreBufferSize = -1;
	private int fPostBufferSize = -1;
	private SashForm fSashForm;
	private GoToAddressComposite fGoToAddressComposite;

	// actions
	private GoToAddressAction fGoToAddressAction;
	private PrintTableRenderingAction fPrintViewTabAction;
	private CopyTableRenderingToClipboardAction fCopyToClipboardAction;
	private FormatTableRenderingAction fFormatRenderingAction;
	private ReformatAction fReformatAction;
	private ToggleAddressColumnAction fToggleAddressColumnAction;
	private ResetToBaseAddressAction fResetMemoryBlockAction;
	private PropertyDialogAction fPropertiesDialogAction;
	private NextPageAction fNextAction;
	private PrevPageAction fPrevAction;

	private ArrayList<IContextActivation> fContext = new ArrayList<IContextActivation>();
	private AbstractHandler fGoToAddressHandler;

	private AbstractHandler fNextPageHandler;
	private AbstractHandler fPrevPageHandler;

	private boolean fIsCreated = false;
	private boolean fIsDisposed = false;
	private boolean fIsShowAddressColumn = true;

	private SwitchPageJob fSwitchPageJob = new SwitchPageJob();
	private boolean fError = false;

	private PendingPropertyChanges fPendingSyncProperties;

	// list of menu listeners for popupMenuMgr.
	private ArrayList<IMenuListener> fMenuListeners;
	private MenuManager fMenuMgr;

	private ISchedulingRule serialByRenderingRule = new SerialByObjectRule(this);

	/**
	 * Identifier for an empty group preceding all context menu actions (value
	 * <code>"popUpBegin"</code>).
	 */
	public static final String EMPTY_MEMORY_GROUP = "popUpBegin"; //$NON-NLS-1$

	/**
	 * Identifier for an empty group following navigation actions in the
	 * rendering (value <code>navigationGroup</code>).
	 */
	public static final String EMPTY_NAVIGATION_GROUP = "navigationGroup"; //$NON-NLS-1$

	/**
	 * Identifier for an empty group following actions that are only applicable
	 * in non-auto loading mode (value <code>nonAutoLoadGroup</code>).
	 */
	public static final String EMPTY_NON_AUTO_LOAD_GROUP = "nonAutoLoadGroup"; //$NON-NLS-1$

	/**
	 * Identifier for an empty group following properties actions (value
	 * <code>propertyGroup</code>).
	 */
	public static final String EMPTY_PROPERTY_GROUP = "propertyGroup"; //$NON-NLS-1$

	private ISelectionChangedListener fViewerSelectionChangedListener = new ISelectionChangedListener() {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			updateSyncTopAddress(getTopVisibleAddress());
			updateSyncSelectedAddress(getSelectedAddress());
		}
	};

	private SelectionAdapter fScrollBarSelectionListener = new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent e) {
			updateSyncTopAddress(getTopVisibleAddress());
		}
	};

	private IModelChangedListener fModelChangedListener = new IModelChangedListener() {
		@Override
		public void modelChanged(IModelDelta delta, IModelProxy proxy) {
			if (delta.getElement() == getMemoryBlock()) {
				showTable();
				updateRenderingLabel(isVisible());
			}
		}
	};

	private IVirtualContentListener fViewerListener = new IVirtualContentListener() {

		private int startThreshold;
		private int endThreshold;

		@Override
		public void handledAtBufferStart() {
			if (getMemoryBlock() instanceof IMemoryBlockExtension) {
				if (isDynamicLoad() && startThreshold != 0) {
					BigInteger address = getTopVisibleAddress();
					if (address != null && !isAtTopLimit()) {
						reloadTable(address);
					}
				}
			}
		}

		@Override
		public void handleAtBufferEnd() {
			if (getMemoryBlock() instanceof IMemoryBlockExtension) {
				if (isDynamicLoad() && endThreshold != 0) {
					BigInteger address = getTopVisibleAddress();
					if (address != null && !isAtBottomLimit()) {
						reloadTable(address);
					}
				}
			}
		}

		@Override
		public int getThreshold(int bufferEndOrStart) {

			int threshold = DEFAULT_BUFFER_THRESHOLD;

			if (bufferEndOrStart == IVirtualContentListener.BUFFER_START) {
				if (threshold > getPreBufferSize()) {
					threshold = getPreBufferSize();
				}
			} else {
				if (threshold > getPostBufferSize()) {
					threshold = getPostBufferSize();
				}
			}

			if (bufferEndOrStart == IVirtualContentListener.BUFFER_START) {
				startThreshold = threshold;
			} else {
				endThreshold = threshold;
			}

			return threshold;
		}
	};

	private IPresentationErrorListener fPresentationErrorListener = new IPresentationErrorListener() {
		@Override
		public void handlePresentationFailure(IStatusMonitor monitor, IStatus status) {
			showMessage(status.getMessage());
		}
	};

	/**
	 * Constructs a new table rendering of the specified type.
	 *
	 * @param renderingId memory rendering type identifier
	 */
	public AbstractAsyncTableRendering(String renderingId) {
		super(renderingId);
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.ui.memory.IResettableMemoryRendering#resetRendering()
	 */
	@Override
	public void resetRendering() throws DebugException {
		if (!fIsCreated) {
			return;
		}

		BigInteger baseAddress = fContentDescriptor.getContentBaseAddress();

		fTableViewer.setSelection(baseAddress);
		reloadTable(baseAddress);
		fTableViewer.setTopIndex(baseAddress);
		if (!isDynamicLoad()) {
			updateSyncPageStartAddress(baseAddress);
		}

		updateSyncSelectedAddress(baseAddress);
		updateSyncTopAddress(baseAddress);
	}

	@Override
	public Control createControl(Composite parent) {

		fPageBook = new PageBook(parent, SWT.NONE);
		createMessagePage(fPageBook);
		createTableViewer(fPageBook);
		addListeners();

		return fPageBook;
	}

	/**
	 * Create the error page of this rendering
	 *
	 * @param parent the parent to add the page to
	 */
	private void createMessagePage(Composite parent) {
		if (fTextViewer == null) {
			fTextViewer = new TextViewer(parent, SWT.WRAP);
			fTextViewer.setDocument(new Document());
			StyledText styleText = fTextViewer.getTextWidget();
			styleText.setEditable(false);
			styleText.setEnabled(false);
		}
	}

	/**
	 * @param parent the parent composite
	 */
	private void createTableViewer(final Composite parent) {
		StringBuffer buffer = new StringBuffer();
		IMemoryRenderingType type = DebugUITools.getMemoryRenderingManager().getRenderingType(getRenderingId());
		buffer.append(type.getLabel());
		buffer.append(": "); //$NON-NLS-1$
		buffer.append(DebugUIMessages.AbstractAsyncTableRendering_2);

		Job job = new Job(buffer.toString()) {

			@Override
			protected IStatus run(IProgressMonitor monitor) {

				// gather information from memory block
				initAddressableSize();
				final BigInteger topVisibleAddress = getInitialTopVisibleAddress();
				BigInteger mbBaseAddress = null;
				try {
					mbBaseAddress = getMemoryBlockBaseAddress();
				} catch (DebugException e) {
					fError = true;
					showMessage(e.getMessage());
				}

				// if it takes too long to get the base address, and user has
				// canceled
				// remove this rendering.
				if (monitor.isCanceled()) {
					getMemoryRenderingContainer().removeMemoryRendering(AbstractAsyncTableRendering.this);
					return Status.CANCEL_STATUS;
				}

				final BigInteger finalMbBaseAddress = mbBaseAddress;
				final BigInteger initialSelectedAddress = getInitialSelectedAddress();

				if (monitor.isCanceled()) {
					getMemoryRenderingContainer().removeMemoryRendering(AbstractAsyncTableRendering.this);
					return Status.CANCEL_STATUS;
				}

				createContentDescriptor(topVisibleAddress);

				// if it takes too long to get other information, and user has
				// canceled
				// remove this rendering.
				if (monitor.isCanceled()) {
					getMemoryRenderingContainer().removeMemoryRendering(AbstractAsyncTableRendering.this);
					return Status.CANCEL_STATUS;
				}

				// batch update on UI thread
				UIJob uiJob = new UIJob("Create Table Viewer UI Job") { //$NON-NLS-1$
					@Override
					public IStatus runInUIThread(IProgressMonitor progressMonitor) {

						if (fPageBook.isDisposed()) {
							return Status.OK_STATUS;
						}

						fSashForm = new SashForm(parent, SWT.VERTICAL);
						fTableViewer = new AsyncTableRenderingViewer(AbstractAsyncTableRendering.this, fSashForm, SWT.VIRTUAL | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.HIDE_SELECTION | SWT.BORDER);

						GridData data = new GridData(GridData.FILL_BOTH);
						fTableViewer.getControl().setLayoutData(data);

						createGoToAddressComposite(fSashForm);
						hideGotoAddressComposite();

						IMemoryRenderingSite site = getMemoryRenderingContainer().getMemoryRenderingSite();
						IMemoryRenderingContainer container = getMemoryRenderingContainer();
						fPresentationContext = new MemoryViewPresentationContext(site, container, AbstractAsyncTableRendering.this);
						fTableViewer.setContext(fPresentationContext);

						// must call this after the context is created as the
						// information is stored in the context
						getDynamicLoadFromPreference();
						getPageSizeFromPreference();

						int numberOfLines = getNumLinesToLoad();
						fContentDescriptor.setNumLines(numberOfLines);

						if (numberOfLines == 0) {
							// if the table viewer is not initialized yet, add
							// listener
							// and load table when we can get the height of the
							// table
							fTableViewer.getTable().addPaintListener(new PaintListener() {
								@Override
								public void paintControl(PaintEvent e) {
									fTableViewer.getTable().removePaintListener(this);
									fContentDescriptor.setNumLines(getNumLinesToLoad());
									refresh();
								}
							});
						}

						BigInteger baseAddress = finalMbBaseAddress;
						if (baseAddress == null) {
							baseAddress = BigInteger.ZERO;
						}

						if (!(getMemoryBlock() instanceof IMemoryBlockExtension) || !isDynamicLoad()) {
							// If not extended memory block, do not create any
							// buffer
							// no scrolling
							fContentDescriptor.setPreBuffer(0);
							fContentDescriptor.setPostBuffer(0);
						}

						setupInitialFormat();
						fTableViewer.setCellModifier(newInternalCellModifier());
						fTableViewer.getTable().setHeaderVisible(true);
						fTableViewer.getTable().setLinesVisible(true);
						fTableViewer.addPresentationErrorListener(fPresentationErrorListener);
						fTableViewer.setInput(getMemoryBlock());
						fTableViewer.resizeColumnsToPreferredSize();
						fTableViewer.setTopIndex(topVisibleAddress);

						fTableViewer.setSelection(initialSelectedAddress);

						// SET UP FONT
						// set to a non-proportional font
						fTableViewer.getTable().setFont(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME));

						if (!fError) {
							showTable();
						}

						fTableViewer.addVirtualContentListener(fViewerListener);

						// create context menu
						// create pop up menu for the rendering
						createActions();
						IMenuListener menuListener = new IMenuListener() {
							@Override
							public void menuAboutToShow(IMenuManager mgr) {
								fillContextMenu(mgr);
							}
						};
						createPopupMenu(fTableViewer.getControl(), menuListener);
						createPopupMenu(fTableViewer.getCursor(), menuListener);

						fTableViewer.addSelectionChangedListener(fViewerSelectionChangedListener);
						fTableViewer.getTable().getVerticalBar().addSelectionListener(fScrollBarSelectionListener);

						// add resize listener to figure out number of visible
						// lines
						// so that the viewer get refreshed with the correct
						// number of lines on the
						// next refresh request
						fTableViewer.getTable().addListener(SWT.Resize, new Listener() {
							@Override
							public void handleEvent(Event event) {
								if (!fTableViewer.getTable().isDisposed()) {
									fContentDescriptor.setNumLines(getNumLinesToLoad());
								}
							}
						});

						createToolTip();

						if (isActivated()) {
							activatePageActions();
						}

						// now the rendering is successfully created
						fIsCreated = true;

						return Status.OK_STATUS;
					}
				};
				uiJob.setSystem(true);
				uiJob.schedule();

				return Status.OK_STATUS;

			}
		};

		job.schedule();
	}

	/**
	 * Create popup menu for this rendering
	 *
	 * @param control - control to create the popup menu for
	 * @param menuListener - listener to notify when popup menu is about to show
	 */
	private void createPopupMenu(Control control, IMenuListener menuListener) {
		IMemoryRenderingContainer container = getMemoryRenderingContainer();
		if (fMenuMgr == null) {
			fMenuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
			fMenuMgr.setRemoveAllWhenShown(true);
			IMemoryRenderingSite site = container.getMemoryRenderingSite();
			String menuId = container.getId();

			ISelectionProvider selProvider = site.getSite().getSelectionProvider();

			addMenuListener(menuListener);

			site.getSite().registerContextMenu(menuId, fMenuMgr, selProvider);
		}

		addMenuListener(menuListener);

		Menu popupMenu = fMenuMgr.createContextMenu(control);
		control.setMenu(popupMenu);
	}

	private void addMenuListener(IMenuListener menuListener) {
		if (fMenuListeners == null) {
			fMenuListeners = new ArrayList<IMenuListener>();
		}

		if (!fMenuListeners.contains(menuListener)) {
			fMenuMgr.addMenuListener(menuListener);
			fMenuListeners.add(menuListener);
		}
	}

	private BigInteger getInitialSelectedAddress() {
		// figure out selected address
		BigInteger selectedAddress = (BigInteger) getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS);
		if (selectedAddress == null) {
			if (getMemoryBlock() instanceof IMemoryBlockExtension) {
				try {
					selectedAddress = ((IMemoryBlockExtension) getMemoryBlock()).getBigBaseAddress();
				} catch (DebugException e) {
					selectedAddress = BigInteger.ZERO;
				}

				if (selectedAddress == null) {
					selectedAddress = BigInteger.ZERO;
				}

			} else {
				long address = getMemoryBlock().getStartAddress();
				selectedAddress = BigInteger.valueOf(address);
			}
		}
		return selectedAddress;
	}

	private void addListeners() {
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		addRenderingToSyncService();
		JFaceResources.getFontRegistry().addListener(this);
	}

	private void removeListeners() {
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		removeRenderingFromSyncService();
		JFaceResources.getFontRegistry().removeListener(this);

		if (fMenuListeners != null) {
			Iterator<IMenuListener> iter = fMenuListeners.iterator();
			while (iter.hasNext()) {
				fMenuMgr.removeMenuListener(iter.next());
			}

			fMenuListeners.clear();
		}
	}

	private void addRenderingToSyncService() {
		IMemoryRenderingSynchronizationService syncService = getMemoryRenderingContainer().getMemoryRenderingSite().getSynchronizationService();

		if (syncService == null) {
			return;
		}

		syncService.addPropertyChangeListener(this, null);
	}

	private void removeRenderingFromSyncService() {
		IMemoryRenderingSynchronizationService syncService = getMemoryRenderingContainer().getMemoryRenderingSite().getSynchronizationService();

		if (syncService == null) {
			return;
		}

		syncService.removePropertyChangeListener(this);
	}

	private void initAddressableSize() {
		// set up addressable size and figure out number of bytes required per
		// line
		fAddressableSize = -1;
		try {
			if (getMemoryBlock() instanceof IMemoryBlockExtension) {
				fAddressableSize = ((IMemoryBlockExtension) getMemoryBlock()).getAddressableSize();
			} else {
				fAddressableSize = 1;
			}
		} catch (DebugException e1) {
			DebugUIPlugin.log(e1);
			// log error and default to 1
			fAddressableSize = 1;
			return;

		}
		if (fAddressableSize < 1) {
			DebugUIPlugin.logErrorMessage("Invalid addressable size"); //$NON-NLS-1$
			fAddressableSize = 1;
		}
	}

	private BigInteger getInitialTopVisibleAddress() {
		BigInteger topVisibleAddress = (BigInteger) getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS);
		if (topVisibleAddress == null) {
			if (getMemoryBlock() instanceof IMemoryBlockExtension) {
				try {
					topVisibleAddress = ((IMemoryBlockExtension) getMemoryBlock()).getBigBaseAddress();
				} catch (DebugException e1) {
					topVisibleAddress = new BigInteger("0"); //$NON-NLS-1$
				}
			} else {
				topVisibleAddress = BigInteger.valueOf(getMemoryBlock().getStartAddress());
			}
		}
		return topVisibleAddress;
	}

	private void setupInitialFormat() {

		boolean validated = validateInitialFormat();

		if (!validated) {
			// pop up dialog to ask user for default values
			StringBuffer msgBuffer = new StringBuffer(DebugUIMessages.AbstractTableRendering_20);
			msgBuffer.append(" "); //$NON-NLS-1$
			msgBuffer.append(this.getLabel());
			msgBuffer.append("\n\n"); //$NON-NLS-1$
			msgBuffer.append(DebugUIMessages.AbstractTableRendering_16);
			msgBuffer.append("\n"); //$NON-NLS-1$
			msgBuffer.append(DebugUIMessages.AbstractTableRendering_18);
			msgBuffer.append("\n\n"); //$NON-NLS-1$

			int bytePerLine = fBytePerLine;
			int columnSize = fColumnSize;

			// initialize this value to populate the dialog properly
			fBytePerLine = getDefaultRowSize() / getAddressableSize();
			fColumnSize = getDefaultColumnSize() / getAddressableSize();

			FormatTableRenderingDialog dialog = new FormatTableRenderingDialog(this, DebugUIPlugin.getShell());
			dialog.openError(msgBuffer.toString());

			// restore to original value before formatting
			fBytePerLine = bytePerLine;
			fColumnSize = columnSize;

			bytePerLine = dialog.getRowSize() * getAddressableSize();
			columnSize = dialog.getColumnSize() * getAddressableSize();

			format(bytePerLine, columnSize);
		} else {
			// Row size is stored as number of addressable units in preference
			// store
			int bytePerLine = getDefaultRowSize();
			// column size is now stored as number of addressable units
			int columnSize = getDefaultColumnSize();

			// format memory block with specified "bytesPerLine" and
			// "columnSize"
			boolean ok = format(bytePerLine, columnSize);

			if (!ok) {
				// this is to ensure that the rest of the rendering can be
				// created
				// and we can recover from a format error
				format(bytePerLine, bytePerLine);
			}
		}
	}

	private boolean validateInitialFormat() {
		int rowSize = getDefaultRowSize();
		int columnSize = getDefaultColumnSize();

		if (rowSize < columnSize || rowSize % columnSize != 0 || rowSize == 0 || columnSize == 0) {
			return false;
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#getControl()
	 */
	@Override
	public Control getControl() {
		return fPageBook;
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse
	 * .jface.util.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		if (!fIsCreated) {
			return;
		}

		// if memory view table font has changed
		if (event.getProperty().equals(IInternalDebugUIConstants.FONT_NAME)) {
			if (!fIsDisposed) {
				Font memoryViewFont = JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME);
				setFont(memoryViewFont);
			}
			return;
		}

		Object evtSrc = event.getSource();

		// always update page size, only refresh if the table is visible
		if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) {
			getPageSizeFromPreference();
		}
		if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PRE_BUFFER_SIZE)) {
			getPreBufferSizeFromPreference();
			fContentDescriptor.setPreBuffer(getPreBufferSize());
		}
		if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_POST_BUFFER_SIZE)) {
			getPostBufferSizeFromPreference();
			fContentDescriptor.setPostBuffer(getPostBufferSize());
		}

		// do not handle event if the rendering is displaying an error
		// or if it's not visible
		if (isDisplayingError() || !isVisible()) {
			handlePropertiesChangeWhenHidden(event);
			return;
		}

		if (event.getProperty().equals(IDebugUIConstants.PREF_PADDED_STR) || event.getProperty().equals(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR) || event.getProperty().equals(IDebugUIConstants.PREF_MEMORY_HISTORY_KNOWN_COLOR) || event.getProperty().equals(IDebugUIConstants.PREF_MEMORY_HISTORY_UNKNOWN_COLOR)) {
			if (!fIsDisposed) {
				fTableViewer.refresh(false);
			}
			return;
		}

		if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PRE_BUFFER_SIZE) || event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_POST_BUFFER_SIZE)) {
			if (!fIsDisposed) {
				fTableViewer.refresh(true);
			}
			return;
		}

		if (event.getProperty().equals(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM)) {
			handleDyanicLoadChanged();
			return;
		}

		if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) {
			if (!isDynamicLoad()) {
				int pageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE);
				handlePageSizeChanged(pageSize);
			}
			return;
		}

		if (evtSrc == this) {
			return;
		}

		if (evtSrc instanceof IMemoryRendering) {
			IMemoryRendering rendering = (IMemoryRendering) evtSrc;
			IMemoryBlock memoryBlock = rendering.getMemoryBlock();

			// do not handle event from renderings displaying other memory
			// blocks
			if (memoryBlock != getMemoryBlock()) {
				return;
			}
		}

		String propertyName = event.getProperty();
		Object value = event.getNewValue();

		if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS) && value instanceof BigInteger) {
			selectedAddressChanged((BigInteger) value);
		} else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_COL_SIZE) && value instanceof Integer) {
			columnSizeChanged(((Integer) value).intValue());
		} else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_ROW_SIZE) && value instanceof Integer) {
			rowSizeChanged(((Integer) value).intValue());
		} else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS) && value instanceof BigInteger) {
			topVisibleAddressChanged((BigInteger) value);
		} else if (propertyName.equals(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS) && value instanceof BigInteger) {
			handlePageStartAddressChanged((BigInteger) value);
		}
	}

	/**
	 * @param pageSize the new page size
	 */
	private void handlePageSizeChanged(int pageSize) {
		fPageSize = pageSize;
		// only refresh if in non-auto-load mode
		fContentDescriptor.setNumLines(pageSize);
		refresh();
	}

	private void handlePropertiesChangeWhenHidden(PropertyChangeEvent event) {
		if (fPendingSyncProperties == null) {
			return;
		}

		String propertyName = event.getProperty();
		Object value = event.getNewValue();

		if (event.getSource() instanceof IMemoryRendering) {
			IMemoryRendering rendering = (IMemoryRendering) event.getSource();
			if (rendering == this || rendering.getMemoryBlock() != getMemoryBlock()) {
				return;
			}
		}

		if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_COL_SIZE) && value instanceof Integer) {
			fPendingSyncProperties.setColumnSize(((Integer) value).intValue());
		} else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_ROW_SIZE) && value instanceof Integer) {
			fPendingSyncProperties.setRowSize(((Integer) value).intValue());
		}

		else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS) && value instanceof BigInteger) {
			fPendingSyncProperties.setSelectedAddress((BigInteger) value);
		} else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS) && value instanceof BigInteger) {
			fPendingSyncProperties.setTopVisibleAddress((BigInteger) value);
		} else if (propertyName.equals(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS) && value instanceof BigInteger) {
			fPendingSyncProperties.setPageStartAddress((BigInteger) value);
		} else if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) {
			int pageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE);
			fPendingSyncProperties.setPageSize(pageSize);
		}
	}

	private void topVisibleAddressChanged(final BigInteger address) {
		final Runnable runnable = new Runnable() {
			@Override
			public void run() {
				if (fTableViewer.getTable().isDisposed()) {
					return;
				}

				doTopVisibleAddressChanged(address);
			}
		};
		runOnUIThread(runnable);
	}

	/**
	 * @param address the changed address
	 */
	private void doTopVisibleAddressChanged(final BigInteger address) {
		if (fIsDisposed) {
			return;
		}

		if (!isDynamicLoad()) {
			fTableViewer.setTopIndex(address);
			fTableViewer.topIndexChanged();
			return;
		}

		if (!isAtTopBuffer(address) && !isAtBottomBuffer(address)) {
			fTableViewer.setTopIndex(address);
			fTableViewer.topIndexChanged();
		} else {
			reloadTable(address);
		}
	}

	private boolean isAtBottomBuffer(BigInteger address) {
		int idx = fTableViewer.indexOf(address);
		if (idx < 0) {
			return true;
		}

		int bottomIdx = idx + getNumberOfVisibleLines();
		int elementsCnt = fTableViewer.getVirtualContentModel().getElements().length;
		int numLinesLeft = elementsCnt - bottomIdx;

		if (numLinesLeft < fViewerListener.getThreshold(IVirtualContentListener.BUFFER_END)) {
			return true;
		}

		return false;
	}

	private boolean isAtTopBuffer(BigInteger address) {
		int topIdx = fTableViewer.indexOf(address);
		if (topIdx < fViewerListener.getThreshold(IVirtualContentListener.BUFFER_START)) {
			return true;
		}

		return false;
	}

	private void runOnUIThread(final Runnable runnable) {
		if (Display.getCurrent() != null) {
			runnable.run();
		} else {
			UIJob job = new UIJob("Async Table Rendering UI Job") { //$NON-NLS-1$

				@Override
				public IStatus runInUIThread(IProgressMonitor monitor) {
					runnable.run();
					return Status.OK_STATUS;
				}
			};
			job.setSystem(true);
			job.schedule();
		}
	}

	private void selectedAddressChanged(final BigInteger address) {
		Runnable runnable = new Runnable() {

			@Override
			public void run() {

				if (fTableViewer.getTable().isDisposed()) {
					return;
				}

				// call this to make the table viewer to reload when needed
				int i = fTableViewer.indexOf(address);
				if (i < 0) {
					// the model may not have been populated yet,
					// try to predict if the address will be in the buffer
					boolean contained = isAddressBufferred(address);
					if (!contained) {
						topVisibleAddressChanged(address);
					}
				}
				fTableViewer.setSelection(address);
			}
		};

		runOnUIThread(runnable);
	}

	private boolean isAddressBufferred(BigInteger address) {
		// figure out the buffer top address
		BigInteger loadAddress = fContentDescriptor.getLoadAddress();
		loadAddress = MemoryViewUtil.alignToBoundary(loadAddress, getAddressableUnitPerLine());
		int unitPerLine = getAddressableUnitPerLine();

		loadAddress = loadAddress.subtract(BigInteger.valueOf(getPreBufferSize() * unitPerLine));

		// figure out the buffer end address
		int numLines = fContentDescriptor.getNumLines();
		BigInteger bufferEnd = loadAddress.add(BigInteger.valueOf(fContentDescriptor.getPostBuffer() * unitPerLine));
		bufferEnd = bufferEnd.add(BigInteger.valueOf(numLines * unitPerLine + unitPerLine));

		// see if the address is contained based on current content descriptor
		if (address.compareTo(loadAddress) >= 0 && address.compareTo(bufferEnd) <= 0) {
			return true;
		}

		return false;
	}

	private void setFont(Font font) {
		// set font
		fTableViewer.getTable().setFont(font);
		fTableViewer.getCursor().setFont(font);
	}

	private int getDefaultColumnSize() {

		// default to global preference store
		IPreferenceStore prefStore = DebugUITools.getPreferenceStore();
		int columnSize = prefStore.getInt(IDebugPreferenceConstants.PREF_COLUMN_SIZE);
		// actual column size is number of addressable units * size of the
		// addressable unit
		columnSize = columnSize * getAddressableSize();

		// check synchronized col size
		Integer colSize = (Integer) getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_COL_SIZE);
		if (colSize != null) {
			// column size is stored as actual number of bytes in synchronizer
			int syncColSize = colSize.intValue();
			if (syncColSize > 0) {
				columnSize = syncColSize;
			}
		} else {
			IPersistableDebugElement elmt = getMemoryBlock().getAdapter(IPersistableDebugElement.class);
			int defaultColSize = -1;

			if (elmt != null) {
				if (elmt.supportsProperty(this, IDebugPreferenceConstants.PREF_COL_SIZE_BY_MODEL)) {
					defaultColSize = getDefaultFromPersistableElement(IDebugPreferenceConstants.PREF_COL_SIZE_BY_MODEL);
				}
			}

			if (defaultColSize <= 0) {
				// if not provided, get default by model
				defaultColSize = getDefaultColumnSizeByModel(getMemoryBlock().getModelIdentifier());
			}

			if (defaultColSize > 0) {
				columnSize = defaultColSize * getAddressableSize();
			}
		}
		return columnSize;
	}

	private int getDefaultRowSize() {

		int rowSize = DebugUITools.getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_ROW_SIZE);
		int bytePerLine = rowSize * getAddressableSize();

		// check synchronized row size
		Integer size = (Integer) getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_ROW_SIZE);
		if (size != null) {
			// row size is stored as actual number of bytes in synchronizer
			int syncRowSize = size.intValue();
			if (syncRowSize > 0) {
				bytePerLine = syncRowSize;
			}
		} else {
			int defaultRowSize = -1;
			IPersistableDebugElement elmt = getMemoryBlock().getAdapter(IPersistableDebugElement.class);
			if (elmt != null) {
				if (elmt.supportsProperty(this, IDebugPreferenceConstants.PREF_ROW_SIZE_BY_MODEL)) {
					defaultRowSize = getDefaultFromPersistableElement(IDebugPreferenceConstants.PREF_ROW_SIZE_BY_MODEL);
					return defaultRowSize * getAddressableSize();
				}
			}

			if (defaultRowSize <= 0) {
				// no synchronized property, ask preference store by id
				defaultRowSize = getDefaultRowSizeByModel(getMemoryBlock().getModelIdentifier());
			}

			if (defaultRowSize > 0) {
				bytePerLine = defaultRowSize * getAddressableSize();
			}
		}
		return bytePerLine;
	}

	/**
	 * Returns the addressable size of this rendering's memory block in bytes.
	 *
	 * @return the addressable size of this rendering's memory block in bytes
	 */
	@Override
	public int getAddressableSize() {
		return fAddressableSize;
	}

	private Object getSynchronizedProperty(String propertyId) {
		IMemoryRenderingSynchronizationService syncService = getMemoryRenderingContainer().getMemoryRenderingSite().getSynchronizationService();

		if (syncService == null) {
			return null;
		}

		return syncService.getProperty(getMemoryBlock(), propertyId);
	}

	private int getDefaultFromPersistableElement(String propertyId) {
		int defaultValue = -1;
		IPersistableDebugElement elmt = getMemoryBlock().getAdapter(IPersistableDebugElement.class);
		if (elmt != null) {
			try {
				Object valueMB = elmt.getProperty(this, propertyId);
				if (valueMB != null && !(valueMB instanceof Integer)) {
					IStatus status = DebugUIPlugin.newErrorStatus("Model returned invalid type on " + propertyId, null); //$NON-NLS-1$
					DebugUIPlugin.log(status);
				}

				if (valueMB != null) {
					Integer value = (Integer) valueMB;
					defaultValue = value.intValue();
				}
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
		}
		return defaultValue;
	}

	/**
	 * @param modelId the {@link String} model id
	 * @return default number of addressable units per line for the model
	 */
	private int getDefaultRowSizeByModel(String modelId) {
		int row = DebugUITools.getPreferenceStore().getInt(getRowPrefId(modelId));
		if (row == 0) {
			DebugUITools.getPreferenceStore().setValue(getRowPrefId(modelId), IDebugPreferenceConstants.PREF_ROW_SIZE_DEFAULT);
		}

		row = DebugUITools.getPreferenceStore().getInt(getRowPrefId(modelId));
		return row;

	}

	/**
	 * @param modelId the {@link String} model id
	 * @return default number of addressable units per column for the model
	 */
	private int getDefaultColumnSizeByModel(String modelId) {
		int col = DebugUITools.getPreferenceStore().getInt(getColumnPrefId(modelId));
		if (col == 0) {
			DebugUITools.getPreferenceStore().setValue(getColumnPrefId(modelId), IDebugPreferenceConstants.PREF_COLUMN_SIZE_DEFAULT);
		}

		col = DebugUITools.getPreferenceStore().getInt(getColumnPrefId(modelId));
		return col;
	}

	private String getRowPrefId(String modelId) {
		String rowPrefId = IDebugPreferenceConstants.PREF_ROW_SIZE + ":" + modelId; //$NON-NLS-1$
		return rowPrefId;
	}

	private String getColumnPrefId(String modelId) {
		String colPrefId = IDebugPreferenceConstants.PREF_COLUMN_SIZE + ":" + modelId; //$NON-NLS-1$
		return colPrefId;
	}

	/**
	 * Format view tab based on the bytes per line and column.
	 *
	 * @param bytesPerLine - number of bytes per line, possible values: (1 / 2 /
	 *            4 / 8 / 16 / 32 / 64/ 128) * addressableSize
	 * @param columnSize - number of bytes per column, possible values: (1 / 2 /
	 *            4 / 8 / 16 / 32/ 64 / 128) * addressableSize
	 * @return true if format is successful, false, otherwise
	 */
	@Override
	public boolean format(int bytesPerLine, int columnSize) {

		// bytes per cell must be divisible to bytesPerLine
		if (bytesPerLine % columnSize != 0) {
			return false;
		}

		if (bytesPerLine < columnSize) {
			return false;
		}

		// do not format if the view tab is already in that format
		if (fBytePerLine == bytesPerLine && fColumnSize == columnSize) {
			return false;
		}

		fBytePerLine = bytesPerLine;
		fColumnSize = columnSize;
		formatViewer();

		updateSyncRowSize();
		updateSyncColSize();

		return true;
	}

	/**
	 * Returns the number of addressable units per row.
	 *
	 * @return number of addressable units per row
	 */
	@Override
	public int getAddressableUnitPerLine() {
		return fBytePerLine / getAddressableSize();
	}

	/**
	 * Returns the number of addressable units per column.
	 *
	 * @return number of addressable units per column
	 */
	@Override
	public int getAddressableUnitPerColumn() {
		return fColumnSize / getAddressableSize();
	}

	/**
	 * This method estimates the number of visible lines in the rendering table.
	 *
	 * @return estimated number of visible lines in the table
	 */
	private int getNumberOfVisibleLines() {
		if (fTableViewer == null) {
			return -1;
		}

		Table table = fTableViewer.getTable();
		int height = fTableViewer.getTable().getSize().y;

		// when table is not yet created, height is zero
		if (height == 0) {
			// make use of the table viewer to estimate table size
			height = fTableViewer.getTable().getParent().getSize().y;
		}

		if (height == 0) {
			return 0;
		}

		// height of border
		int border = fTableViewer.getTable().getHeaderHeight();

		// height of scroll bar
		int scroll = fTableViewer.getTable().getHorizontalBar().getSize().y;

		// height of table is table's area minus border and scroll bar height
		height = height - border - scroll;

		// calculate number of visible lines
		int lineHeight = getMinTableItemHeight(table);

		int numberOfLines = height / lineHeight;

		if (numberOfLines <= 0) {
			return 0;
		}

		return numberOfLines;
	}

	private int getMinTableItemHeight(Table table) {

		// Hack to get around Linux GTK problem.
		// On Linux GTK, table items have variable item height as
		// carriage returns are actually shown in a cell. Some rows will be
		// taller than others. When calculating number of visible lines, we
		// need to find the smallest table item height. Otherwise, the rendering
		// underestimates the number of visible lines. As a result the rendering
		// will not be able to get more memory as needed.
		if (MemoryViewUtil.isLinuxGTK()) {
			// check each of the items and find the minimum
			TableItem[] items = table.getItems();
			int minHeight = table.getItemHeight();
			for (int i = 0; i < items.length; i++) {
				if (items[i].getData() != null) {
					minHeight = Math.min(items[i].getBounds(0).height, minHeight);
				}
			}

			return minHeight;

		}
		return table.getItemHeight();
	}

	private BigInteger getMemoryBlockBaseAddress() throws DebugException {
		if (getMemoryBlock() instanceof IMemoryBlockExtension) {
			return ((IMemoryBlockExtension) getMemoryBlock()).getBigBaseAddress();
		} else {
			return BigInteger.valueOf(getMemoryBlock().getStartAddress());
		}
	}

	/**
	 * Displays the given message on the error page
	 *
	 * @param message - the message to display
	 */
	protected void showMessage(final String message) {
		fSwitchPageJob.setShowMessagePage(true);
		fSwitchPageJob.setMessage(message);
		fSwitchPageJob.schedule();
	}

	/**
	 * Returns the number of bytes displayed in a single column cell.
	 *
	 * @return the number of bytes displayed in a single column cell
	 */
	@Override
	public int getBytesPerColumn() {
		return fColumnSize;
	}

	/**
	 * Returns the number of bytes displayed in a row.
	 *
	 * @return the number of bytes displayed in a row
	 */
	@Override
	public int getBytesPerLine() {
		return fBytePerLine;
	}

	/**
	 * Returns whether the error page is displayed.
	 *
	 * @return whether the error page is displayed
	 */
	public boolean isDisplayingError() {
		return fShowMessage;
	}

	/**
	 * Displays the content of the table viewer.
	 */
	public void showTable() {
		fSwitchPageJob.setShowMessagePage(false);
		fSwitchPageJob.schedule();
	}

	private BigInteger getTopVisibleAddress() {

		if (fTableViewer == null) {
			return BigInteger.valueOf(0);
		}

		Table table = fTableViewer.getTable();
		int topIndex = table.getTopIndex();

		if (topIndex < 0) {
			return null;
		}

		if (table.getItemCount() > topIndex) {
			MemorySegment topItem = (MemorySegment) table.getItem(topIndex).getData();
			if (topItem != null) {
				return topItem.getAddress();
			}
		}
		return null;
	}

	private synchronized void reloadTable(final BigInteger topAddress) {

		if (DebugUIPlugin.DEBUG_DYNAMIC_LOADING) {
			DebugUIPlugin.trace(this + " reload at: " + topAddress.toString(16)); //$NON-NLS-1$
		}
		fContentDescriptor.setLoadAddress(topAddress);
		fContentDescriptor.setNumLines(getNumLinesToLoad());
		fTableViewer.setTopIndex(topAddress);
		fTableViewer.refresh();

	}

	private boolean isAtTopLimit() {
		BigInteger startAddress = fContentDescriptor.getStartAddress();
		startAddress = MemoryViewUtil.alignToBoundary(startAddress, getAddressableUnitPerLine());
		AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel();

		if (model != null) {
			Object key = model.getKey(0);
			if (key instanceof BigInteger) {
				BigInteger startBufferAddress = (BigInteger) key;
				startBufferAddress = MemoryViewUtil.alignToBoundary(startBufferAddress, getAddressableUnitPerLine());

				if (startAddress.compareTo(startBufferAddress) == 0) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean isAtBottomLimit() {
		BigInteger endAddress = fContentDescriptor.getEndAddress();
		endAddress = MemoryViewUtil.alignToBoundary(endAddress, getAddressableUnitPerLine());

		AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel();
		if (model != null) {
			int numElements = model.getElements().length;
			Object key = model.getKey(numElements - 1);
			if (key instanceof BigInteger) {
				BigInteger endBufferAddress = (BigInteger) key;
				endBufferAddress = MemoryViewUtil.alignToBoundary(endBufferAddress, getAddressableUnitPerLine());

				if (endAddress.compareTo(endBufferAddress) == 0) {
					return true;
				}
			}
		}

		return false;
	}

	private void formatViewer() {

		fTableViewer.disposeColumns();
		fTableViewer.disposeCellEditors();
		doFormatTable();
		fTableViewer.setColumnHeaders(getColumnProperties());
		fTableViewer.showColumnHeader(true);

		Table table = fTableViewer.getTable();
		int colCnt = table.getColumnCount();
		CellEditor[] editors = new CellEditor[fTableViewer.getTable().getColumnCount()];
		for (int i = 0; i < colCnt; i++) {
			editors[i] = createCellEditor(table, i);
		}

		fTableViewer.setCellEditors(editors);

		fTableViewer.formatViewer();

		// This resize needs to happen after the viewer has finished
		// getting the labels.
		// This fix is a hack to delay the resize until the viewer has a chance
		// to get
		// the setData event from the UI thread. Otherwise, the columns will be
		// squeezed together.
		UIJob job = new UIJob("resize to fit") { //$NON-NLS-1$
			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {
				resizeColumnsToPreferredSize();
				return Status.OK_STATUS;
			}
		};

		job.setSystem(true);
		job.schedule();
	}

	private void doFormatTable() {
		int bytesPerLine = getBytesPerLine();
		int columnSize = getBytesPerColumn();
		int numColumns = bytesPerLine / columnSize;

		Table table = fTableViewer.getTable();
		TableColumn column0 = new TableColumn(table, SWT.LEFT, 0);
		column0.setText(DebugUIMessages.AbstractTableRendering_2);

		// create new byte columns
		TableColumn[] byteColumns = new TableColumn[numColumns];
		for (int i = 0; i < byteColumns.length; i++) {
			TableColumn column = new TableColumn(table, SWT.LEFT, i + 1);
			byteColumns[i] = column;
		}

		// Empty column for cursor navigation
		TableColumn emptyCol = new TableColumn(table, SWT.LEFT, byteColumns.length + 1);
		emptyCol.setText(" "); //$NON-NLS-1$
		emptyCol.setWidth(1);
		emptyCol.setResizable(false);
		table.setHeaderVisible(true);

		// allow clients to override column labels
		setColumnHeadings();

	}

	private String[] getColumnProperties() {
		int numColumns = getAddressableUnitPerLine() / getAddressableUnitPerColumn();
		// +2 to include properties for address and navigation column
		String[] columnProperties = new String[numColumns + 2];
		columnProperties[0] = TableRenderingLine.P_ADDRESS;

		int addressableUnit = getAddressableUnitPerColumn();

		// use column beginning offset to the row address as properties
		for (int i = 1; i < columnProperties.length - 1; i++) {
			// column properties are stored as number of addressable units from
			// the
			// the line address
			columnProperties[i] = Integer.toHexString((i - 1) * addressableUnit);
		}

		// Empty column for cursor navigation
		columnProperties[columnProperties.length - 1] = " "; //$NON-NLS-1$
		return columnProperties;
	}

	/**
	 * Create a cell editor from the specified composite and column.
	 *
	 * @param composite parent composite that the cell editor is to be created
	 *            from.
	 * @param column the column where the cell editor is required
	 * @return the cell editor for editing memory
	 *
	 * @since 3.3
	 *
	 */
	protected CellEditor createCellEditor(Composite composite, int column) {

		return new TextCellEditor(composite);
	}

	private ICellModifier newInternalCellModifier() {
		return new AsyncTableRenderingCellModifier(this, createCellModifier());
	}

	/**
	 * Create a custom cell modifier for this rendering. Return null if the
	 * default cell modifier is to be used.
	 *
	 * @return the cell modifier for this rendering, or <code>null</code> if the
	 *         default cell modifier is to be used.
	 *
	 * @since 3.3
	 *
	 */
	protected ICellModifier createCellModifier() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.AbstractMemoryRendering#dispose()
	 */
	@Override
	public void dispose() {

		if (fIsDisposed) {
			return;
		}

		fIsDisposed = true;

		removeListeners();

		if (fMenuMgr != null) {
			fMenuMgr.removeAll();
			fMenuMgr.dispose();
			fMenuMgr = null;
		}

		if (fTableViewer != null) {
			if (fViewerListener != null) {
				fTableViewer.removeVirtualContentListener(fViewerListener);
			}

			if (fPresentationErrorListener != null) {
				fTableViewer.removePresentationErrorListener(fPresentationErrorListener);
			}

			fTableViewer.removeSelectionChangedListener(fViewerSelectionChangedListener);
			fTableViewer.getTable().getVerticalBar().removeSelectionListener(fScrollBarSelectionListener);

			fTableViewer.dispose();
		}

		if (fPresentationContext != null) {
			fPresentationContext.dispose();
		}

		if (fToolTipShell != null && !fToolTipShell.isDisposed()) {
			fToolTipShell.dispose();
			fToolTipShell = null;
		}

		fIsDisposed = true;

		super.dispose();
	}

	/**
	 * Updates the label of this rendering, optionally displaying the base
	 * address of this rendering's memory block.
	 *
	 * @param showAddress whether to display the base address of this
	 *            rendering's memory block in this rendering's label
	 */
	protected void updateRenderingLabel(final boolean showAddress) {
		Job job = new Job("Update Rendering Label") { //$NON-NLS-1$
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				if (fIsDisposed) {
					return Status.OK_STATUS;
				}
				fLabel = buildLabel(showAddress);
				firePropertyChangedEvent(new PropertyChangeEvent(AbstractAsyncTableRendering.this, IBasicPropertyConstants.P_TEXT, null, fLabel));
				return Status.OK_STATUS;
			}
		};
		job.setSystem(true);
		job.setRule(serialByRenderingRule);
		job.schedule();
	}

	private String buildLabel(boolean showAddress) {
		String label = IInternalDebugCoreConstants.EMPTY_STRING;
		if (getMemoryBlock() instanceof IMemoryBlockExtension) {
			label = ((IMemoryBlockExtension) getMemoryBlock()).getExpression();

			if (label == null) {
				label = DebugUIMessages.AbstractTableRendering_8;
			}

			if (label.startsWith("&")) { //$NON-NLS-1$
				label = "&" + label; //$NON-NLS-1$
			}

			try {
				if (showAddress && ((IMemoryBlockExtension) getMemoryBlock()).getBigBaseAddress() != null) {
					label += " : 0x"; //$NON-NLS-1$
					label += ((IMemoryBlockExtension) getMemoryBlock()).getBigBaseAddress().toString(16).toUpperCase();
				}
			} catch (DebugException e) {
				// do nothing, the label will not show the address
			}
		} else {
			long address = getMemoryBlock().getStartAddress();
			label = Long.toHexString(address).toUpperCase();
		}

		String preName = DebugUITools.getMemoryRenderingManager().getRenderingType(getRenderingId()).getLabel();

		if (preName != null) {
			label += " <" + preName + ">"; //$NON-NLS-1$ //$NON-NLS-2$
		}

		return decorateLabel(label);
	}

	/*
	 * Returns the label of this rendering.
	 * @return label of this rendering
	 */
	@Override
	public String getLabel() {

		if (fLabel == null) {
			fLabel = DebugUIMessages.AbstractAsyncTableRendering_1;
			updateRenderingLabel(isVisible());
		}

		return fLabel;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {

		if (adapter == IColorProvider.class) {
			return (T) getColorProviderAdapter();
		}

		if (adapter == ILabelProvider.class) {
			return (T) getLabelProviderAdapter();
		}

		if (adapter == IFontProvider.class) {
			return (T) getFontProviderAdapter();
		}

		if (adapter == IModelChangedListener.class) {
			return (T) fModelChangedListener;
		}

		if (adapter == IWorkbenchAdapter.class) {
			// needed workbench adapter to fill the title of property page
			if (fWorkbenchAdapter == null) {
				fWorkbenchAdapter = new IWorkbenchAdapter() {
					@Override
					public Object[] getChildren(Object o) {
						return new Object[0];
					}

					@Override
					public ImageDescriptor getImageDescriptor(Object object) {
						return null;
					}

					@Override
					public String getLabel(Object o) {
						return AbstractAsyncTableRendering.this.getLabel();
					}

					@Override
					public Object getParent(Object o) {
						return null;
					}
				};
			}
			return (T) fWorkbenchAdapter;
		}

		if (adapter == TableRenderingContentDescriptor.class) {
			return (T) getContentDescriptor();
		}

		return super.getAdapter(adapter);
	}

	/**
	 * Returns the number of characters a byte will convert to or -1 if unknown.
	 *
	 * @return the number of characters a byte will convert to or -1 if unknown
	 */
	@Override
	public int getNumCharsPerByte() {
		return -1;
	}

	/**
	 * Create actions for this rendering
	 */
	protected void createActions() {

		fCopyToClipboardAction = new AsyncCopyTableRenderingAction(this, fTableViewer);
		fGoToAddressAction = new RenderingGoToAddressAction(getMemoryRenderingContainer(), this);
		fResetMemoryBlockAction = new ResetToBaseAddressAction(this);

		fPrintViewTabAction = new AsyncPrintTableRenderingAction(this, fTableViewer);

		fFormatRenderingAction = new FormatTableRenderingAction(this);
		fReformatAction = new ReformatAction(this);
		fToggleAddressColumnAction = new ToggleAddressColumnAction();

		IMemoryRenderingSite site = getMemoryRenderingContainer().getMemoryRenderingSite();
		if (site.getSite().getSelectionProvider() != null) {
			fPropertiesDialogAction = new PropertyDialogAction(site.getSite(), site.getSite().getSelectionProvider());
		}

		fNextAction = new NextPageAction();
		fPrevAction = new PrevPageAction();
	}

	/**
	 * Returns the currently selected address in this rendering.
	 *
	 * @return the currently selected address in this rendering
	 */
	@Override
	public BigInteger getSelectedAddress() {
		if (!fIsCreated) {
			return null;
		}

		Object key = fTableViewer.getSelectionKey();

		if (key != null && key instanceof BigInteger) {
			return (BigInteger) key;
		}

		return null;
	}

	/**
	 * Returns the currently selected content in this rendering as MemoryByte.
	 *
	 * @return the currently selected content in array of MemoryByte. Returns an
	 *         empty array if the selected address is out of buffered range.
	 */
	@Override
	public MemoryByte[] getSelectedAsBytes() {
		if (getSelectedAddress() == null) {
			return new MemoryByte[0];
		}

		Object key = fTableViewer.getSelectionKey();
		AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel();

		if (model != null) {
			model = (AbstractVirtualContentTableModel) fTableViewer.getModel();
			int row = model.indexOfKey(key);
			Object element = model.getElement(row);
			int col = model.columnOf(element, key);

			// check precondition
			if (col <= 0 || col > getBytesPerLine() / getBytesPerColumn()) {
				return new MemoryByte[0];
			}

			if (!(element instanceof MemorySegment)) {
				return new MemoryByte[0];
			}

			MemorySegment line = (MemorySegment) element;
			int offset = (col - 1) * (getAddressableUnitPerColumn() * getAddressableSize());

			// make a copy of the bytes to ensure that data cannot be changed
			// by caller
			MemoryByte[] bytes = line.getBytes(offset, getAddressableUnitPerColumn() * getAddressableSize());
			MemoryByte[] retBytes = new MemoryByte[bytes.length];

			System.arraycopy(bytes, 0, retBytes, 0, bytes.length);
			return retBytes;
		}
		return new MemoryByte[0];
	}

	/**
	 * Returns the currently selected content in this rendering as a String.
	 *
	 * @return the currently selected content in this rendering
	 */
	@Override
	public String getSelectedAsString() {

		if (getSelectedAddress() == null) {
			return IInternalDebugCoreConstants.EMPTY_STRING;
		}

		MemoryByte[] bytes = getSelectedAsBytes();
		if (bytes.length > 0) {
			return getString(this.getRenderingId(), getSelectedAddress(), bytes);
		} else {
			return IInternalDebugCoreConstants.EMPTY_STRING;
		}

	}

	/**
	 * Moves the cursor to the specified address. Will load more memory if the
	 * address is not currently visible.
	 *
	 * @param address address to position cursor at
	 * @throws DebugException if an exception occurs
	 */
	@Override
	public void goToAddress(final BigInteger address) throws DebugException {

		if (!fIsCreated || fTableViewer.getVirtualContentModel() == null) {
			return;
		}

		final int keyIndex = fTableViewer.getVirtualContentModel().indexOfKey(address);

		if (keyIndex < 0) {
			// if not extended memory block
			// do not allow user to go to an address that's out of range
			if (!(getMemoryBlock() instanceof IMemoryBlockExtension)) {
				Status stat = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), DebugException.NOT_SUPPORTED, DebugUIMessages.AbstractTableRendering_11, null);
				DebugException e = new DebugException(stat);
				throw e;
			}

			BigInteger startAdd = fContentDescriptor.getStartAddress();
			BigInteger endAdd = fContentDescriptor.getEndAddress();

			if (address.compareTo(startAdd) < 0 || address.compareTo(endAdd) > 0) {
				Status stat = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), DebugException.NOT_SUPPORTED, DebugUIMessages.AbstractTableRendering_11, null);
				DebugException e = new DebugException(stat);
				throw e;
			}
		}

		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				showTable();
				if (keyIndex >= 0) {
					// address is within range, set cursor and reveal
					fTableViewer.setSelection(address);
					updateSyncTopAddress(getTopVisibleAddress());
					updateSyncSelectedAddress(address);
				} else {
					// load at the address
					fTableViewer.setSelection(address);
					reloadTable(address);

					updateSyncSelectedAddress(address);
					if (!isDynamicLoad()) {
						updateSyncPageStartAddress(address);
					}
					updateSyncTopAddress(address);
				}
			}
		};
		runOnUIThread(runnable);
	}

	/**
	 * Refresh the table viewer with the current top visible address. Update
	 * labels in the memory rendering.
	 */
	@Override
	public void refresh() {
		if (!fIsCreated) {
			return;
		}

		fTableViewer.refresh();
	}

	/**
	 * Resize column to the preferred size.
	 */
	@Override
	public void resizeColumnsToPreferredSize() {
		if (!fIsCreated) {
			return;
		}

		fTableViewer.resizeColumnsToPreferredSize();
		if (!fIsShowAddressColumn) {
			final TableColumn column = fTableViewer.getTable().getColumn(0);
			column.addControlListener(new ControlListener() {

				@Override
				public void controlMoved(ControlEvent e) {
				}

				@Override
				public void controlResized(ControlEvent e) {
					column.removeControlListener(this);
					column.setWidth(0);
				}
			});
		}
	}

	/**
	 * Updates labels of this rendering.
	 */
	@Override
	public void updateLabels() {
		if (!fIsCreated) {
			return;
		}

		UIJob job = new UIJob("updateLabels") { //$NON-NLS-1$

			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {

				// do not handle if the rendering is already disposed
				if (fPageBook.isDisposed()) {
					return Status.OK_STATUS;
				}

				// update tab labels
				updateRenderingLabel(true);

				if (fTableViewer != null) {
					// update column labels
					setColumnHeadings();

					// rebuild cache and force labels to be refreshed
					fTableViewer.formatViewer();
				}
				return Status.OK_STATUS;
			}
		};
		job.setSystem(true);
		job.schedule();
	}

	/**
	 * Fills the context menu for this rendering
	 *
	 * @param menu menu to fill
	 */
	protected void fillContextMenu(IMenuManager menu) {

		menu.add(new Separator(EMPTY_MEMORY_GROUP));
		menu.add(new Separator());
		menu.add(fResetMemoryBlockAction);
		menu.add(fGoToAddressAction);
		menu.add(new Separator(EMPTY_NAVIGATION_GROUP));

		menu.add(new Separator());
		menu.add(fFormatRenderingAction);

		if (!isDynamicLoad() && getMemoryBlock() instanceof IMemoryBlockExtension) {
			menu.add(new Separator());
			menu.add(fPrevAction);
			menu.add(fNextAction);
			menu.add(new Separator(EMPTY_NON_AUTO_LOAD_GROUP));
		}

		menu.add(new Separator());
		menu.add(fReformatAction);
		menu.add(fToggleAddressColumnAction);
		menu.add(new Separator());
		menu.add(fCopyToClipboardAction);
		menu.add(fPrintViewTabAction);
		if (fPropertiesDialogAction != null) {
			menu.add(new Separator());
			menu.add(fPropertiesDialogAction);
			menu.add(new Separator(EMPTY_PROPERTY_GROUP));
		}

		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	private int getPageSizeInUnits() {
		return fPageSize * getAddressableUnitPerLine();
	}

	private void getPageSizeFromPreference() {
		fPageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE);
	}

	private void getPreBufferSizeFromPreference() {
		fPreBufferSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PRE_BUFFER_SIZE);
	}

	private void getPostBufferSizeFromPreference() {
		fPostBufferSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_POST_BUFFER_SIZE);
	}

	private void updateDynamicLoadProperty() {

		boolean value = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM);

		if (value != isDynamicLoad()) {
			setDynamicLoad(value);

			if (!fIsDisposed) {
				if (isDynamicLoad()) {
					fContentDescriptor.setPostBuffer(getPostBufferSize());
					fContentDescriptor.setPreBuffer(getPreBufferSize());
					fContentDescriptor.setNumLines(getNumberOfVisibleLines());

				} else {
					fContentDescriptor.setPostBuffer(0);
					fContentDescriptor.setPreBuffer(0);
					fContentDescriptor.setNumLines(fPageSize);
				}
			}
		}
	}

	private void getDynamicLoadFromPreference() {
		setDynamicLoad(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM));
	}

	private boolean isDynamicLoad() {
		return fContentDescriptor.isDynamicLoad();
	}

	private int getPageSize() {
		return fPageSize;
	}

	private int getNumLinesToLoad() {
		int numberOfLines = -1;

		if (isDynamicLoad()) {
			numberOfLines = getNumberOfVisibleLines();
		} else {
			numberOfLines = getPageSize();
		}

		return numberOfLines;
	}

	private void setDynamicLoad(boolean load) {
		fContentDescriptor.setDynamicLoad(load);
	}

	private void handlePageStartAddressChanged(BigInteger address) {
		// do not handle if in dynamic mode
		if (isDynamicLoad()) {
			return;
		}

		if (!(getMemoryBlock() instanceof IMemoryBlockExtension)) {
			return;
		}

		// do not handle event if the base address of the memory
		// block has changed, wait for debug event to update to
		// new location
		if (isMemoryBlockBaseAddressChanged()) {
			return;
		}

		Object key = fTableViewer.getKey(0);
		if (key != null) {
			if (key.equals(address)) {
				return;
			}
		}

		BigInteger start = fContentDescriptor.getStartAddress();
		BigInteger end = fContentDescriptor.getEndAddress();

		// smaller than start address, load at start address
		if (address.compareTo(start) < 0) {
			if (isAtTopLimit()) {
				return;
			}

			address = start;
		}

		// bigger than end address, no need to load, already at top
		if (address.compareTo(end) > 0) {
			if (isAtBottomLimit()) {
				return;
			}

			address = end.subtract(BigInteger.valueOf(getPageSizeInUnits()));
		}

		fContentDescriptor.setLoadAddress(address);
		final BigInteger finaladdress = address;
		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				if (fTableViewer.getTable().isDisposed()) {
					return;
				}

				fTableViewer.setTopIndex(finaladdress);
				refresh();
			}
		};

		runOnUIThread(runnable);

		updateSyncPageStartAddress(address);
		updateSyncTopAddress(address);
	}

	private void handleDyanicLoadChanged() {

		// if currently in dynamic load mode, update page
		// start address
		BigInteger pageStart = getTopVisibleAddress();
		updateSyncPageStartAddress(pageStart);

		updateDynamicLoadProperty();
		if (isDynamicLoad()) {
			refresh();
			fTableViewer.setTopIndex(pageStart);
		} else {
			handlePageStartAddressChanged(pageStart);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesHidden()
	 */
	@Override
	public void becomesHidden() {
		// creates new object for storing potential changes in sync properties
		fPendingSyncProperties = new PendingPropertyChanges();
		super.becomesHidden();

		if (getMemoryBlock() instanceof IMemoryBlockExtension) {
			updateRenderingLabel(false);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesVisible()
	 */
	@Override
	public void becomesVisible() {

		if (!fIsCreated) {
			// label can still be constructed even though the rendering has not
			// finished being
			// initialized
			updateRenderingLabel(true);
			super.becomesVisible();
			return;
		}

		// do not do anything if already visible
		if (isVisible() == true) {
			// super should always be called
			super.becomesVisible();
			return;
		}

		super.becomesVisible();

		if (fPendingSyncProperties != null) {
			// deal with format
			boolean format = false;
			int rowSize = getBytesPerLine();
			if (fPendingSyncProperties.getRowSize() > 0) {
				format = true;
				rowSize = fPendingSyncProperties.getRowSize();
			}

			int colSize = getBytesPerColumn();
			if (fPendingSyncProperties.getColumnSize() > 0) {
				format = true;
				colSize = fPendingSyncProperties.getColumnSize();
			}

			if (format) {
				format(rowSize, colSize);
			}

			BigInteger selectedAddress = fPendingSyncProperties.getSelectedAddress();
			if (selectedAddress != null) {
				fTableViewer.setSelection(selectedAddress);
			}

			updateDynamicLoadProperty();

			if (isDynamicLoad()) {
				BigInteger topVisibleAddress = fPendingSyncProperties.getTopVisibleAddress();
				if (topVisibleAddress != null) {
					fContentDescriptor.setLoadAddress(topVisibleAddress);
					fTableViewer.setTopIndex(topVisibleAddress);
				}
			} else if (!(getMemoryBlock() instanceof IMemoryBlockExtension)) {
				BigInteger topVisibleAddress = fPendingSyncProperties.getTopVisibleAddress();
				if (topVisibleAddress != null) {
					fTableViewer.setTopIndex(topVisibleAddress);
				}
			} else {
				if (fPendingSyncProperties.getPageSize() > 0) {
					fPageSize = fPendingSyncProperties.getPageSize();
					fContentDescriptor.setNumLines(fPageSize);
				}

				BigInteger pageStartAddress = fPendingSyncProperties.getPageStartAddress();
				if (pageStartAddress != null) {
					fContentDescriptor.setLoadAddress(pageStartAddress);
				}

				fTableViewer.setTopIndex(pageStartAddress);
			}

			showTable();
			refresh();
		}

		updateRenderingLabel(true);

		Job job = new Job("becomesVisible") //$NON-NLS-1$
		{
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				if (fIsDisposed) {
					return Status.OK_STATUS;
				}
				try {
					fContentDescriptor.updateContentBaseAddress();
				} catch (DebugException e) {
					showMessage(e.getMessage());
				}
				return Status.OK_STATUS;
			}
		};
		job.setSystem(true);
		job.schedule();

		// discard these properties
		fPendingSyncProperties = null;
	}

	/**
	 * Handle column size changed event from synchronizer
	 *
	 * @param newColumnSize the new column size
	 */
	private void columnSizeChanged(final int newColumnSize) {
		// ignore event if rendering is not visible
		if (!isVisible()) {
			return;
		}

		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				int rowSize = getBytesPerLine();
				if (rowSize < newColumnSize) {
					rowSize = newColumnSize;
				}

				format(rowSize, newColumnSize);
			}
		});
	}

	/**
	 * @param newRowSize - new row size in number of bytes
	 */
	private void rowSizeChanged(final int newRowSize) {
		// ignore event if rendering is not visible
		if (!isVisible()) {
			return;
		}

		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				int colSize = getBytesPerColumn();
				if (newRowSize < colSize) {
					colSize = newRowSize;
				}

				format(newRowSize, colSize);
			}
		});
	}

	/**
	 * update selected address in synchronizer if update is true.
	 *
	 * @param address the address to update
	 */
	private void updateSyncSelectedAddress(BigInteger address) {

		if (!fIsCreated) {
			return;
		}
		PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS, null, address);
		firePropertyChangedEvent(event);
	}

	/**
	 * update column size in synchronizer
	 */
	private void updateSyncColSize() {

		if (!fIsCreated) {
			return;
		}

		PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_COL_SIZE, null, Integer.valueOf(fColumnSize));
		firePropertyChangedEvent(event);
	}

	/**
	 * update column size in synchronizer
	 */
	private void updateSyncRowSize() {

		if (!fIsCreated) {
			return;
		}

		PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_ROW_SIZE, null, Integer.valueOf(fBytePerLine));
		firePropertyChangedEvent(event);
	}

	/**
	 * update top visible address in synchronizer
	 *
	 * @param address the address to update
	 */
	private void updateSyncTopAddress(BigInteger address) {

		if (!fIsCreated) {
			return;
		}

		PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS, null, address);
		firePropertyChangedEvent(event);
	}

	private void updateSyncPageStartAddress(BigInteger address) {

		if (!fIsCreated) {
			return;
		}

		if (isMemoryBlockBaseAddressChanged()) {
			return;
		}

		PropertyChangeEvent event = new PropertyChangeEvent(this, IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS, null, address);
		firePropertyChangedEvent(event);
	}

	/**
	 * Returns the color provider for this rendering's memory block or
	 * <code>null</code> if none.
	 * <p>
	 * By default a color provider is obtained by asking this rendering's memory
	 * block for its {@link IColorProvider} adapter. When the color provider is
	 * queried for color information, it is provided with a
	 * {@link MemoryRenderingElement} as an argument.
	 * </p>
	 *
	 * @return the color provider for this rendering's memory block, or
	 *         <code>null</code>
	 */
	protected IColorProvider getColorProviderAdapter() {
		return getMemoryBlock().getAdapter(IColorProvider.class);
	}

	/**
	 * Returns the label provider for this rendering's memory block or
	 * <code>null</code> if none.
	 * <p>
	 * By default a label provider is obtained by asking this rendering's memory
	 * block for its {@link ILabelProvider} adapter. When the label provider is
	 * queried for label information, it is provided with a
	 * {@link MemoryRenderingElement} as an argument.
	 * </p>
	 *
	 * @return the label provider for this rendering's memory block, or
	 *         <code>null</code>
	 */
	protected ILabelProvider getLabelProviderAdapter() {
		return getMemoryBlock().getAdapter(ILabelProvider.class);
	}

	/**
	 * Returns the font provider for this rendering's memory block or
	 * <code>null</code> if none.
	 * <p>
	 * By default a font provider is obtained by asking this rendering's memory
	 * block for its {@link IFontProvider} adapter. When the font provider is
	 * queried for font information, it is provided with a
	 * {@link MemoryRenderingElement} as an argument.
	 * </p>
	 *
	 * @return the font provider for this rendering's memory block, or
	 *         <code>null</code>
	 */
	protected IFontProvider getFontProviderAdapter() {
		return getMemoryBlock().getAdapter(IFontProvider.class);
	}

	/**
	 * Returns the table presentation for this rendering's memory block or
	 * <code>null</code> if none.
	 * <p>
	 * By default a table presentation is obtained by asking this rendering's
	 * memory block for its {@link IMemoryBlockTablePresentation} adapter.
	 * </p>
	 *
	 * @return the table presentation for this rendering's memory block, or
	 *         <code>null</code>
	 */
	protected IMemoryBlockTablePresentation getTablePresentationAdapter() {
		return getMemoryBlock().getAdapter(IMemoryBlockTablePresentation.class);
	}

	/**
	 * Setup the viewer so it supports hovers to show the offset of each field
	 */
	private void createToolTip() {

		fToolTipShell = new Shell(DebugUIPlugin.getShell(), SWT.ON_TOP | SWT.RESIZE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		gridLayout.marginWidth = 2;
		gridLayout.marginHeight = 0;
		fToolTipShell.setLayout(gridLayout);
		fToolTipShell.setBackground(fTableViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));

		final Control toolTipControl = createToolTipControl(fToolTipShell);

		if (toolTipControl == null) {
			// if client decide not to use tooltip support
			fToolTipShell.dispose();
			return;
		}

		MouseTrackAdapter listener = new MouseTrackAdapter() {

			private TableItem fTooltipItem = null;
			private int fCol = -1;

			@Override
			public void mouseExit(MouseEvent e) {

				if (!fToolTipShell.isDisposed()) {
					fToolTipShell.setVisible(false);
				}
				fTooltipItem = null;
			}

			@Override
			public void mouseHover(MouseEvent e) {

				Point hoverPoint = new Point(e.x, e.y);
				Control control = null;

				if (e.widget instanceof Control) {
					control = (Control) e.widget;
				}

				if (control == null) {
					return;
				}

				hoverPoint = control.toDisplay(hoverPoint);
				TableItem item = getItem(hoverPoint);
				int column = getColumn(hoverPoint);

				// Only if there is a change in hover
				if (this.fTooltipItem != item || fCol != column) {

					// Keep Track of the latest hover
					fTooltipItem = item;
					fCol = column;

					if (item != null) {
						toolTipAboutToShow(toolTipControl, fTooltipItem, column);

						// Setting location of the tooltip
						Rectangle shellBounds = fToolTipShell.getBounds();
						shellBounds.x = hoverPoint.x;
						shellBounds.y = hoverPoint.y + item.getBounds(0).height;

						fToolTipShell.setBounds(shellBounds);
						fToolTipShell.pack();

						fToolTipShell.setVisible(true);
					} else {
						fToolTipShell.setVisible(false);
					}
				}
			}
		};

		fTableViewer.getTable().addMouseTrackListener(listener);
		fTableViewer.getCursor().addMouseTrackListener(listener);
	}

	/**
	 * Creates the control used to display tool tips for cells in this table. By
	 * default a label is used to display the address of the cell. Clients may
	 * override this method to create custom tooltip controls.
	 * <p>
	 * Also see the methods <code>getToolTipText(...)</code> and
	 * <code>toolTipAboutToShow(...)</code>.
	 * </p>
	 *
	 * @param composite parent for the tooltip control
	 * @return the tooltip control to be displayed
	 * @since 3.2
	 */
	protected Control createToolTipControl(Composite composite) {
		Control fToolTipLabel = new Label(composite, SWT.NONE);
		fToolTipLabel.setForeground(fTableViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
		fToolTipLabel.setBackground(fTableViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		fToolTipLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
		return fToolTipLabel;
	}

	/**
	 * Bug with table widget,BUG 113015, the widget is not able to return the
	 * correct table item if SWT.FULL_SELECTION is not on when the table is
	 * created. Created the following function to work around the problem. We
	 * can remove this method when the bug is fixed.
	 *
	 * @param point the given {@link Point} to find the {@link TableItem} for
	 * @return the table item where the point is located, return null if the
	 *         item cannot be located.
	 */
	private TableItem getItem(Point point) {
		TableItem[] items = fTableViewer.getTable().getItems();
		for (int i = 0; i < items.length; i++) {
			TableItem item = items[i];
			if (item.getData() != null) {
				Point start = new Point(item.getBounds(0).x, item.getBounds(0).y);
				start = fTableViewer.getTable().toDisplay(start);
				Point end = new Point(start.x + item.getBounds(0).width, start.y + item.getBounds(0).height);

				if (start.y < point.y && point.y < end.y) {
					return item;
				}
			}
		}
		return null;
	}

	/**
	 * Method for figuring out which column the point is located.
	 *
	 * @param point the {@link Point} the get the column number for
	 * @return the column index where the point is located, return -1 if column
	 *         is not found.
	 */
	private int getColumn(Point point) {
		int colCnt = fTableViewer.getTable().getColumnCount();

		TableItem item = null;
		for (int i = 0; i < fTableViewer.getTable().getItemCount(); i++) {
			item = fTableViewer.getTable().getItem(i);
			if (item.getData() != null) {
				break;
			}
		}

		if (item != null) {
			for (int i = 0; i < colCnt; i++) {
				Point start = new Point(item.getBounds(i).x, item.getBounds(i).y);
				start = fTableViewer.getTable().toDisplay(start);
				Point end = new Point(start.x + item.getBounds(i).width, start.y + item.getBounds(i).height);

				if (start.x < point.x && end.x > point.x) {
					return i;
				}
			}
		}
		return -1;
	}

	/**
	 * Called when the tool tip is about to show in this rendering. Clients who
	 * overrides <code>createTooltipControl</code> may need to also override
	 * this method to ensure that the tooltip shows up properly in their
	 * customized control.
	 * <p>
	 * By default a text tooltip is displayed, and the contents for the tooltip
	 * are generated by the <code>getToolTipText(...)</code> method.
	 * </p>
	 *
	 * @param toolTipControl - the control for displaying the tooltip
	 * @param item - the table item where the mouse is pointing.
	 * @param col - the column at which the mouse is pointing.
	 * @since 3.2
	 */
	protected void toolTipAboutToShow(Control toolTipControl, TableItem item, int col) {
		if (toolTipControl instanceof Label) {
			Object address = fTableViewer.getKey(fTableViewer.getTable().indexOf(item), col);
			if (address != null && address instanceof BigInteger) {
				Object data = item.getData();
				if (data instanceof MemorySegment) {
					MemorySegment line = (MemorySegment) data;

					if (col > 0) {
						int start = (col - 1) * getBytesPerColumn();
						int end = start + getBytesPerColumn();
						MemoryByte[] bytes = line.getBytes(start, end);

						String str = getToolTipText((BigInteger) address, bytes);

						if (str != null) {
							((Label) toolTipControl).setText(str);
						}
					} else {
						String str = getToolTipText((BigInteger) address, new MemoryByte[] {});

						if (str != null) {
							((Label) toolTipControl).setText(str);
						}
					}
				}
			}
		}
	}

	/**
	 * Returns the text to display in a tool tip at the specified address for
	 * the specified bytes. By default the address of the bytes is displayed.
	 * Subclasses may override.
	 *
	 * @param address address of cell that tool tip is displayed for
	 * @param bytes the bytes in the cell
	 * @return the tooltip text for the memory bytes located at the specified
	 *         address
	 * @since 3.2
	 */
	protected String getToolTipText(BigInteger address, MemoryByte[] bytes) {
		StringBuffer buf = new StringBuffer("0x"); //$NON-NLS-1$
		buf.append(address.toString(16).toUpperCase());

		return buf.toString();
	}

	private void setColumnHeadings() {
		String[] columnLabels = new String[0];

		IMemoryBlockTablePresentation presentation = getTablePresentationAdapter();
		if (presentation != null) {
			columnLabels = presentation.getColumnLabels(getMemoryBlock(), getBytesPerLine(), getBytesPerLine() / getBytesPerColumn());
		}

		// check that column labels returned are not null
		if (columnLabels == null) {
			columnLabels = new String[0];
		}

		int numByteColumns = fBytePerLine / fColumnSize;

		TableColumn[] columns = fTableViewer.getTable().getColumns();

		int j = 0;
		for (int i = 1; i < columns.length - 1; i++) {
			// if the number of column labels returned is correct
			// use supplied column labels
			if (columnLabels.length == numByteColumns) {
				columns[i].setText(columnLabels[j]);
				j++;
			} else {
				// otherwise, use default
				int addressableUnit = getAddressableUnitPerColumn();
				if (addressableUnit >= 4) {
					columns[i].setText(Integer.toHexString(j * addressableUnit).toUpperCase() + " - " + Integer.toHexString(j * addressableUnit + addressableUnit - 1).toUpperCase()); //$NON-NLS-1$
				} else {
					columns[i].setText(Integer.toHexString(j * addressableUnit).toUpperCase());
				}
				j++;
			}
		}
	}

	/**
	 *
	 * Return this rendering's viewer
	 *
	 * @return this rendering's viewer
	 */
	public StructuredViewer getViewer() {
		return fTableViewer;
	}

	private boolean isMemoryBlockBaseAddressChanged() {
		try {
			BigInteger address = getMemoryBlockBaseAddress();
			BigInteger oldBaseAddress = fContentDescriptor.getContentBaseAddress();
			if (!oldBaseAddress.equals(address)) {
				return true;
			}
		} catch (DebugException e) {
			// fail silently
		}
		return false;
	}

	/**
	 * @param topVisibleAddress the address to get the description for
	 */
	private void createContentDescriptor(final BigInteger topVisibleAddress) {
		fContentDescriptor = new TableRenderingContentDescriptor(AbstractAsyncTableRendering.this);
		fContentDescriptor.setPostBuffer(getPostBufferSize());
		fContentDescriptor.setPreBuffer(getPreBufferSize());
		fContentDescriptor.setLoadAddress(topVisibleAddress);
		try {
			fContentDescriptor.updateContentBaseAddress();

		} catch (DebugException e) {
			fError = true;
			showMessage(e.getMessage());
		}

		fContentDescriptor.setAddressableSize(getAddressableSize());

		try {
			int addressSize = 4;
			if (getMemoryBlock() instanceof IMemoryBlockExtension) {
				IMemoryBlockExtension extMb = (IMemoryBlockExtension) getMemoryBlock();
				addressSize = extMb.getAddressSize();

				if (addressSize <= 0) {
					DebugUIPlugin.logErrorMessage("Invalid address Size: " + addressSize); //$NON-NLS-1$
					addressSize = 4;
				}
				fContentDescriptor.setAddressSize(addressSize);
			}
			fContentDescriptor.setAddressSize(addressSize);
		} catch (DebugException e) {
			fError = true;
			showMessage(e.getMessage());
		} finally {
			if (fContentDescriptor.getAddressSize() <= 0) {
				fContentDescriptor.setAddressSize(4);
			}
		}
	}

	/**
	 * Return the number of lines to be bufferred before the top visible line of
	 * the memory rendering
	 *
	 * @return number of lines to be buffered before the top visible line in the
	 *         memory rendering
	 */
	private int getPreBufferSize() {
		if (fPreBufferSize < 0) {
			getPreBufferSizeFromPreference();
		}

		return fPreBufferSize;
	}

	/**
	 * Returns the number of lines to be bufferred after the last visible line
	 * in the memory rendering
	 *
	 * @return the number of lines to be bufferred after the last visible line
	 *         in the memory rendering
	 */
	private int getPostBufferSize() {
		if (fPostBufferSize < 0) {
			getPostBufferSizeFromPreference();
		}

		return fPostBufferSize;
	}

	private TableRenderingContentDescriptor getContentDescriptor() {
		return fContentDescriptor;
	}

	private void createGoToAddressComposite(Composite parent) {
		fGoToAddressComposite = new GoToAddressComposite();
		fGoToAddressComposite.createControl(parent);
		Button button = fGoToAddressComposite.getButton(IDialogConstants.OK_ID);
		if (button != null) {
			button.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					doGoToAddress();
				}
			});

			button = fGoToAddressComposite.getButton(IDialogConstants.CANCEL_ID);
			if (button != null) {
				button.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						hideGotoAddressComposite();
					}
				});
			}
		}

		fGoToAddressComposite.getExpressionWidget().addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				doGoToAddress();
			}
		});

		fGoToAddressComposite.getExpressionWidget().addKeyListener(new KeyAdapter() {

			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.ESC) {
					hideGotoAddressComposite();
				}
				super.keyPressed(e);
			}
		});
	}

	private void showGoToAddressComposite() {

		String selectedStr = getSelectedAsString();
		Text text = fGoToAddressComposite.getExpressionWidget();
		text.setText(selectedStr);
		text.setSelection(0, text.getCharCount());

		double height = fGoToAddressComposite.getHeight();
		double canvasHeight = fSashForm.getParent().getClientArea().height;
		double tableHeight = canvasHeight - height;

		double tableWeight = (tableHeight / canvasHeight) * 100;
		double textWeight = (height / canvasHeight) * 100;
		fSashForm.setWeights(new int[] { (int) tableWeight, (int) textWeight });
		fSashForm.setMaximizedControl(null);

		fGoToAddressComposite.getExpressionWidget().setFocus();
	}

	private void hideGotoAddressComposite() {
		fSashForm.setMaximizedControl(fTableViewer.getControl());
		if (isActivated()) {
			fTableViewer.getControl().setFocus();
		}
	}

	/**
	 *
	 */
	private void doGoToAddress() {
		try {
			BigInteger address = fGoToAddressComposite.getGoToAddress(fContentDescriptor.getContentBaseAddress(), getSelectedAddress());
			fGoToAddressAction.doGoToAddress(address.toString(16));
			hideGotoAddressComposite();
		} catch (DebugException e1) {
			MemoryViewUtil.openError(DebugUIMessages.GoToAddressAction_Go_to_address_failed, DebugUIMessages.GoToAddressAction_Go_to_address_failed, e1);
		} catch (NumberFormatException e1) {
			MemoryViewUtil.openError(DebugUIMessages.GoToAddressAction_Go_to_address_failed, DebugUIMessages.GoToAddressAction_Address_is_invalid, e1);
		}
	}

	@Override
	public void activated() {
		super.activated();

		fActivated = true;
		IWorkbench workbench = PlatformUI.getWorkbench();
		ICommandService commandSupport = workbench.getAdapter(ICommandService.class);
		IContextService contextSupport = workbench.getAdapter(IContextService.class);

		if (commandSupport != null && contextSupport != null) {
			fContext.add(contextSupport.activateContext(ID_ASYNC_TABLE_RENDERING_CONTEXT));
			Command gotoCommand = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND);

			if (fGoToAddressHandler == null) {
				fGoToAddressHandler = new AbstractHandler() {
					@Override
					public Object execute(ExecutionEvent event) throws ExecutionException {
						if (fSashForm.getMaximizedControl() != null) {
							fGoToAddressAction.run();
						} else {
							hideGotoAddressComposite();
						}
						return null;
					}
				};
			}
			gotoCommand.setHandler(fGoToAddressHandler);

			// The page up and page down actions can only be activated if the
			// rendering
			// is in manual scrolling mode. We are unable to determine the
			// scrolling mode
			// until the content descriptor is created. When the rendering is
			// activated, the content
			// descriptor may not be created yet. In that case, we cannot
			// activate the shortcuts here.
			// We will activate the shortcut after the rendering is created.
			if (fContentDescriptor != null && !isDynamicLoad()) {
				activatePageActions();
			}
		}
	}

	private void activatePageActions() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		ICommandService commandSupport = workbench.getAdapter(ICommandService.class);
		if (commandSupport != null) {
			Command nextPage = commandSupport.getCommand(ID_NEXT_PAGE_COMMAND);
			if (fNextPageHandler == null) {
				fNextPageHandler = new AbstractHandler() {

					@Override
					public Object execute(ExecutionEvent arg0) throws ExecutionException {
						fNextAction.run();
						return null;
					}
				};
			}
			nextPage.setHandler(fNextPageHandler);

			Command prevPage = commandSupport.getCommand(ID_PREV_PAGE_COMMAND);
			if (fPrevPageHandler == null) {
				fPrevPageHandler = new AbstractHandler() {

					@Override
					public Object execute(ExecutionEvent arg0) throws ExecutionException {
						fPrevAction.run();
						return null;
					}
				};
			}
			prevPage.setHandler(fPrevPageHandler);
		}
	}

	@Override
	public void deactivated() {

		fActivated = false;
		IWorkbench workbench = PlatformUI.getWorkbench();
		ICommandService commandSupport = workbench.getAdapter(ICommandService.class);
		IContextService contextSupport = workbench.getAdapter(IContextService.class);

		if (commandSupport != null && contextSupport != null) {
			// remove handler
			Command command = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND);
			command.setHandler(null);

			command = commandSupport.getCommand(ID_NEXT_PAGE_COMMAND);
			command.setHandler(null);

			command = commandSupport.getCommand(ID_PREV_PAGE_COMMAND);
			command.setHandler(null);

			if (fContext != null) {
				contextSupport.deactivateContexts(fContext);
			}
		}
		super.deactivated();
	}

	private boolean isActivated() {
		return fActivated;
	}

	/**
	 * Returns text for the given memory bytes at the specified address for the
	 * specified rendering type. This is called by the label provider for.
	 * Subclasses must override.
	 *
	 * @param renderingTypeId rendering type identifier
	 * @param address address where the bytes belong to
	 * @param data the bytes
	 * @return a string to represent the memory. Cannot not return
	 *         <code>null</code>. Returns a string to pad the cell if the memory
	 *         cannot be converted successfully.
	 */
	@Override
	abstract public String getString(String renderingTypeId, BigInteger address, MemoryByte[] data);

	/**
	 * Returns bytes for the given text corresponding to bytes at the given
	 * address for the specified rendering type. This is called by the cell
	 * modifier when modifying bytes in a memory block. Subclasses must convert
	 * the string value to an array of bytes. The bytes will be passed to the
	 * debug adapter for memory block modification. Returns <code>null</code> if
	 * the bytes cannot be formatted properly.
	 *
	 * @param renderingTypeId rendering type identifier
	 * @param address address the bytes begin at
	 * @param currentValues current values of the data in bytes format
	 * @param newValue the string to be converted to bytes
	 * @return the bytes converted from a string
	 */
	@Override
	abstract public byte[] getBytes(String renderingTypeId, BigInteger address, MemoryByte[] currentValues, String newValue);
}
