/*******************************************************************************
 *  Copyright (c) 2006, 2009 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
 *******************************************************************************/

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.AsyncVirtualContentTableViewer;
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.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.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()
		 */
		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$ 
		}

		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$
		}

		public void run() {
			BigInteger address = fContentDescriptor.getLoadAddress();
			address = address.subtract(BigInteger.valueOf(getPageSizeInUnits()));
			handlePageStartAddressChanged(address);
		}
	}
	
	private class RenderingGoToAddressAction extends GoToAddressAction
	{
		public RenderingGoToAddressAction(AbstractBaseTableRendering rendering) {
			super(rendering);
		}
		
		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;
			}
		}

		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)
		 */
		public boolean contains(ISchedulingRule rule) {
			return rule == this;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse.core.runtime.jobs.ISchedulingRule)
		 */
		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 fContext = new ArrayList();
	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 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() {
		public void selectionChanged(SelectionChangedEvent event) {
			updateSyncTopAddress(getTopVisibleAddress());
			updateSyncSelectedAddress(getSelectedAddress());
		}
	};
	
	private SelectionAdapter fScrollBarSelectionListener = new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
			updateSyncTopAddress(getTopVisibleAddress());
		}
	};
	
	private IModelChangedListener fModelChangedListener = new IModelChangedListener() {
		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;

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

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

		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() {
		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()
	 */
	public void resetRendering() throws DebugException {
		BigInteger baseAddress = fContentDescriptor.getContentBaseAddress();

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

	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
	 */
	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
	 */
	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()) {

			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$
					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() {
								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() {
							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() {
							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();
		
		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 iter = fMenuListeners.iterator();
			while (iter.hasNext())
			{
				fMenuMgr.removeMenuListener((IMenuListener)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()
	 */
	public Control getControl() {
		return fPageBook;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	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);
		}
	}

	/**
	 * 
	 */
	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() {
			public void run() {
				if (fTableViewer.getTable().isDisposed())
					return;
				
				doTopVisibleAddressChanged(address);
			}};
		runOnUIThread(runnable);
	}
	
	/**
	 * @param 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$
	
				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() {

			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 = (IPersistableDebugElement)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 = (IPersistableDebugElement)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
	 */
	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 = (IPersistableDebugElement)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
	 * @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
	 * @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
	 */
	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
	 */
	public int getAddressableUnitPerLine() {
		return fBytePerLine / getAddressableSize();
	}
	
	/**
	 * Returns the number of addressable units per column.
	 * 
	 * @return number of addressable units per column
	 */
	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
	 */
	public int getBytesPerColumn()
	{
		return fColumnSize;
	}

	/**
	 * Returns the number of bytes displayed in a row.
	 * 
	 * @return the number of bytes displayed in a row
	 */
	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 (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
			System.out.println(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$
			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()
	 */
	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.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$
			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
	 */
	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)
	 */
	public Object getAdapter(Class adapter) {
		
		if (adapter == IColorProvider.class)
			return getColorProviderAdapter();
		
		if (adapter == ILabelProvider.class)
			return getLabelProviderAdapter();
		
		if (adapter == IFontProvider.class)
			return getFontProviderAdapter();
		
		if (adapter == IModelChangedListener.class)
		{
			return fModelChangedListener;
		}
		
		if (adapter == IWorkbenchAdapter.class)
		{
			// needed workbench adapter to fill the title of property page
			if (fWorkbenchAdapter == null) {
				fWorkbenchAdapter = new IWorkbenchAdapter() {
					public Object[] getChildren(Object o) {
						return new Object[0];
					}
	
					public ImageDescriptor getImageDescriptor(Object object) {
						return null;
					}
	
					public String getLabel(Object o) {
						return AbstractAsyncTableRendering.this.getLabel();
					}
	
					public Object getParent(Object o) {
						return null;
					}
				};
			}
			return fWorkbenchAdapter;
		}
		
		if (adapter == TableRenderingContentDescriptor.class)
			return 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
	 */
	public int getNumCharsPerByte()
	{
		return -1;
	}
	
	/**
	 * Create actions for this rendering
	 */
	protected void createActions() {
		
		fCopyToClipboardAction = new AsyncCopyTableRenderingAction(this, fTableViewer);
		fGoToAddressAction = new RenderingGoToAddressAction(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
	 */
	public BigInteger getSelectedAddress() {
		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.
	 */
	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
	 */
	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
	 */
	public void goToAddress(BigInteger address) throws DebugException {
		
		if (fTableViewer.getVirtualContentModel() == null)
			return;
		
		int i = fTableViewer.getVirtualContentModel().indexOfKey(address);

		if (i >= 0)
		{	
			// address is within range, set cursor and reveal
			fTableViewer.setSelection(address);
			updateSyncTopAddress(getTopVisibleAddress());
			updateSyncSelectedAddress(address);
		}
		else
		{
			// 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;
			}
	
			// load at the address
			fTableViewer.setSelection(address);
			reloadTable(address);
	
			updateSyncSelectedAddress(address);

			if (!isDynamicLoad())
			{						
				updateSyncPageStartAddress(address);
			}
			
			updateSyncTopAddress(address);
		}
	}			
	
	/**
	 * Refresh the table viewer with the current top visible address.
	 * Update labels in the memory rendering.
	 */
	public void refresh() {
		fTableViewer.refresh();
	}

	
	/**
	 * Resize column to the preferred size.
	 */
	public void resizeColumnsToPreferredSize() {
		fTableViewer.resizeColumnsToPreferredSize();
		if (!fIsShowAddressColumn)
		{
			final TableColumn column = fTableViewer.getTable().getColumn(0);
			column.addControlListener(new ControlListener() {

				public void controlMoved(ControlEvent e) {
				}

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

	/**
	 * Updates labels of this rendering.
	 */
	public void updateLabels()
	{
		UIJob job = new UIJob("updateLabels"){ //$NON-NLS-1$

			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;

		if(fTableViewer.getKey(0).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() {
			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()
	 */
	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()
	 */
	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$
		{
			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
	 */
	private void columnSizeChanged(final int newColumnSize) {
		// ignore event if rendering is not visible
		if (!isVisible())
			return;

		Display.getDefault().asyncExec(new Runnable() {
			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() {
			public void run() {
				int colSize = getBytesPerColumn();
				if (newRowSize < colSize)
					colSize = newRowSize;
				
				format(newRowSize, colSize);
			}
		});		
	}
	
	/**
	 * update selected address in synchronizer if update is true.
	 */
	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, new Integer(fColumnSize));
		firePropertyChangedEvent(event);
	}
	
	/**
	 * update column size in synchronizer
	 */
	private void updateSyncRowSize() {
		
		if (!fIsCreated)
			return;
		
		PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_ROW_SIZE, null, new Integer(fBytePerLine));
		firePropertyChangedEvent(event);
	}
	
	/**
	 * update top visible address in synchronizer
	 */
	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 (IColorProvider)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 (ILabelProvider)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 (IFontProvider)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 (IMemoryBlockTablePresentation)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;
			
			public void mouseExit(MouseEvent e){
				
				if (!fToolTipShell.isDisposed())
					fToolTipShell.setVisible(false);
				fTooltipItem = null;
			}
			
			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
	 * @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
	 * @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
	 */
	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() {

				public void widgetSelected(SelectionEvent e) {
					doGoToAddress();
				}
			});
			
			button = fGoToAddressComposite.getButton(IDialogConstants.CANCEL_ID);
			if (button != null)
			{
				button.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						hideGotoAddressComposite();
					}});
			}
		}
		
		fGoToAddressComposite.getExpressionWidget().addSelectionListener(new SelectionAdapter() {
			public void widgetDefaultSelected(SelectionEvent e) {
				doGoToAddress();
			}});
		
		fGoToAddressComposite.getExpressionWidget().addKeyListener(new KeyAdapter() {

			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);
		}
	}
	
	public void activated() {
		super.activated();
		
		fActivated = true;
		IWorkbench workbench = PlatformUI.getWorkbench();
		ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class);
		IContextService contextSupport = (IContextService)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() {
					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 = (ICommandService)workbench.getAdapter(ICommandService.class);
		if (commandSupport != null)
		{
			Command nextPage = commandSupport.getCommand(ID_NEXT_PAGE_COMMAND);
			if (fNextPageHandler == null)
			{
				fNextPageHandler = new AbstractHandler() {
	
					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() {
	
					public Object execute(ExecutionEvent arg0)
							throws ExecutionException {
						fPrevAction.run();
						return null;
					}						
				};
			}
			prevPage.setHandler(fPrevPageHandler);
		}
	}

	public void deactivated() {
		
		fActivated = false;
    	IWorkbench workbench = PlatformUI.getWorkbench();
		ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class);
		IContextService contextSupport = (IContextService)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.
	 */
	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
	 */
	abstract public byte[] getBytes(String renderingTypeId, BigInteger address, MemoryByte[] currentValues, String newValue);
}
