Bug removed: assertion error when disposed
diff --git a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java
index 83b2500..0b5b137 100644
--- a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java
+++ b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java
@@ -1,537 +1,557 @@
-/**
- * <copyright>
- *
- * Copyright (c) 2009 Metascape, LLC.
- * 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:
- *   Metascape - Initial API and Implementation
- *
- * </copyright>
- *
- */
-package org.eclipse.amp.agf.chart;
-
-import java.util.List;
-
-import org.eclipse.amp.agf.chart.ide.AGFChartPlugin;
-import org.eclipse.amp.axf.core.IModel;
-import org.eclipse.amp.axf.core.IObservationProvider;
-import org.eclipse.amp.axf.view.SWTAsyncModelListener;
-import org.eclipse.birt.chart.api.ChartEngine;
-import org.eclipse.birt.chart.device.ICallBackNotifier;
-import org.eclipse.birt.chart.device.IDeviceRenderer;
-import org.eclipse.birt.chart.exception.ChartException;
-import org.eclipse.birt.chart.factory.GeneratedChartState;
-import org.eclipse.birt.chart.factory.Generator;
-import org.eclipse.birt.chart.factory.RunTimeContext;
-import org.eclipse.birt.chart.model.Chart;
-import org.eclipse.birt.chart.model.attribute.Bounds;
-import org.eclipse.birt.chart.model.attribute.CallBackValue;
-import org.eclipse.birt.chart.model.attribute.ColorDefinition;
-import org.eclipse.birt.chart.model.attribute.Fill;
-import org.eclipse.birt.chart.model.attribute.Palette;
-import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
-import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
-import org.eclipse.birt.chart.model.attribute.impl.PaletteImpl;
-import org.eclipse.birt.core.framework.PlatformConfig;
-import org.eclipse.core.runtime.IAdapterManager;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.draw2d.AbstractLayout;
-import org.eclipse.draw2d.Figure;
-import org.eclipse.draw2d.FigureListener;
-import org.eclipse.draw2d.Graphics;
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.geometry.Dimension;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
-import org.eclipse.jface.viewers.IColorProvider;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.statushandlers.StatusManager;
-
-public class ChartEditPart extends AbstractGraphicalEditPart implements ICallBackNotifier {
-
-	private Chart chart;
-
-	private final ResourceManager resourceManager;
-
-	private IDeviceRenderer renderer;
-
-	private GeneratedChartState chartState;
-
-	private IDataProvider dataProvider;
-
-	private IColorProvider seriesColorProvider;
-
-	private Palette genericPalette;
-
-	private Object dataSource;
-
-	private ChartModelListener chartListener;
-
-	private IDataSelectionListener dataListener;
-
-	private int nextOpenPaletteIndex;
-
-	private IChartDesignStrategy chartStrategy;
-
-	/**
-	 * Instantiates a new chart edit part.
-	 */
-	public ChartEditPart() {
-		resourceManager = new ResourceManager();
-		PlatformConfig config = new PlatformConfig();
-		try {
-			config.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this);
-			renderer = ChartEngine.instance(config).getRenderer("dv.SWT");
-		} catch (ChartException e) {
-			throw new RuntimeException(e);
-		}
-		genericPalette = PaletteImpl.create(0, true);
-		genericPalette.shift(0);
-	}
-
-	/**
-	 * The listener interface for receiving chartModel events. The class that is interested in processing a chartModel
-	 * event implements this interface, and the object created with that class is registered with a component using the
-	 * component's <code>addChartModelListener<code> method. When
-	 * the chartModel event occurs, that object's appropriate
-	 * method is invoked.
-	 * 
-	 * @see ChartModelEvent
-	 */
-	class ChartModelListener extends SWTAsyncModelListener {
-		/**
-		 * Instantiates a new chart model listener.
-		 */
-		public ChartModelListener() {
-			super(null, "Chart Updated View", 10000);
-		}
-
-		@Override
-		public void observing(IObservationProvider observed) {
-			// wait for data source to be available from model set..
-			while (getDataProvider() == null) {
-				try {
-					Thread.sleep(25);
-				} catch (InterruptedException e) {
-					//
-				}
-			}
-			setChartStrategy(ChartType.TIME_SERIES.createStrategy());
-		}
-
-		@Override
-		public void observeStart(IObservationProvider observed) {
-			updateChartSelection();
-			endPainting();
-		}
-
-		@Override
-		public void observeInitialize(IObservationProvider model) {
-			getResourceManager().setImage(null);
-		}
-
-		@Override
-		public void update(final IModel model) {
-			beginPainting();
-			getChartStrategy().update();
-			refresh();
-		}
-
-		@Override
-		public void observationEnd(IObservationProvider model) {
-			getDataProvider().removeListener(getDataSource(), getDataListener());
-			model = null;
-		}
-
-	}
-
-	private void updateValueSetColor(Object valueSet) {
-		String seriesLabel = dataProvider.getText(valueSet);
-		Color swtColor = seriesColorProvider.getForeground(seriesLabel);
-		EList<Fill> entries = chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries();
-		ColorDefinition cd = null;
-		if (swtColor == null) {
-			// List<Fill> palette = ySeriesDefinition.getSeriesPalette().getEntries();
-			// if (nextOpenPaletteIndex >= palette.size()) {
-			// nextOpenPaletteIndex = 0;
-			// }
-			// cd = (ColorDefinition) palette.get(nextOpenPaletteIndex);
-			// Color lineColor = new Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(), cd.getGreen(), cd
-			// .getBlue());
-			if (seriesColorProvider instanceof CachedColorProvider) {
-				cd = (ColorDefinition) genericPalette.getEntries().get(nextOpenPaletteIndex++);
-				if (nextOpenPaletteIndex > genericPalette.getEntries().size() - 1) {
-					nextOpenPaletteIndex = 0;
-				}
-				swtColor = new Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(), cd.getGreen(), cd.getBlue());
-				((CachedColorProvider) seriesColorProvider).putForegroundColor(seriesLabel, swtColor);
-			}
-		} else {
-			cd = ColorDefinitionImpl.create(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue());
-			// if (chartType == ChartType.TIME_SERIES) {
-			// cd = ((LineSeries) lineSeries).getLineAttributes().getColor();
-			// } else if (chartType == ChartType.STACKED_AREA) {
-			// cd = ((AreaSeries) lineSeries).getLineAttributes().getColor();
-			// }
-			// cd.setRed(swtColor.getRed());
-			// cd.setGreen(swtColor.getGreen());
-			// cd.setBlue(swtColor.getBlue());
-		}
-		entries.add(cd);
-	}
-
-	@Override
-	protected IFigure createFigure() {
-		chartListener.setWidget(getViewer().getControl());
-
-		final Figure newFigure = new Figure() {
-			@Override
-			public void paintFigure(Graphics graphics) {
-				if (getResourceManager().getImage() != null) {
-					graphics.drawImage(getResourceManager().getImage(), 0, 0);
-					if (getChartListener() != null) {
-						getChartListener().endPainting();
-					}
-				}
-			}
-		};
-		newFigure.setLayoutManager(new AbstractLayout() {
-			@Override
-			public Dimension getMinimumSize(IFigure container, int hintWidth, int hintHeight) {
-				return new Dimension(hintWidth < 1 ? 1 : hintWidth, hintHeight < 1 ? 1 : hintHeight);
-			}
-
-			@Override
-			protected Dimension calculatePreferredSize(IFigure container, int hintWidth, int hintHeight) {
-				return new Dimension(hintWidth < 1 ? 100 : hintWidth, hintHeight < 1 ? 100 : hintHeight);
-			}
-
-			public void layout(IFigure container) {
-				newFigure.setLocation(new Point(0, 0));
-			}
-		});
-		newFigure.addFigureListener(new FigureListener() {
-			public void figureMoved(IFigure source) {
-				regenerateChart();
-			}
-		});
-		
-		return newFigure;
-	}
-
-	@Override
-	protected void createEditPolicies() {
-		//
-	}
-
-	@Override
-	public void refresh() {
-		new Thread() {
-			@Override
-			public void run() {
-				regenerateChart(true);
-			}
-		}.run();
-	}
-
-	@Override
-	public void setModel(Object model) {
-		super.setModel(model);
-		chartListener = new ChartModelListener();
-		((IModel) model).addModelListener(chartListener);
-		IAdapterManager adapterManager = Platform.getAdapterManager();
-		// We seem to need to force loading of the data provider, at least in the exemplar case
-		Object provider = adapterManager.loadAdapter(this.getModel(), "org.eclipse.amp.agf.chart.IDataProvider");
-
-		if (!(provider instanceof IDataProvider)) {
-			throw new RuntimeException("Couldn't find data provider for chart model. Please ensure that a data provider adapter has been defined for the class: " + this.getModel().getClass());
-		}
-
-		setDataProvider((IDataProvider) provider);
-
-		// createChart();
-	}
-
-	/**
-	 * 
-	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart()
-	 */
-	public void regenerateChart() {
-		regenerateChart(true);
-	}
-
-	/**
-	 * Regenerate chart.
-	 * 
-	 * @param forceNewImage
-	 *          the force new image
-	 */
-	public synchronized void regenerateChart(boolean forceNewImage) {
-		if (forceNewImage) {
-			getResourceManager().setImage(null);
-		}
-		try {
-			if (chart != null && chartStrategy.isInitialized() && getFigure() != null && !getFigure().getSize().isEmpty()) {
-				createImage();
-				Dimension area = getFigure().getSize();
-				Bounds chartBounds = BoundsImpl.create(0, 0, area.width, area.height);
-				chartBounds.scale(72d / renderer.getDisplayServer().getDpiResolution());
-				Generator gr = Generator.instance();
-				RunTimeContext rtc = new RunTimeContext();
-				rtc.setScriptingEnabled(false);
-
-				// rtc.setScriptContext(csc);
-				// csc.setChartInstance(chart);
-				chartState = gr.build(renderer.getDisplayServer(), chart, chartBounds, rtc);
-				gr.render(renderer, chartState);
-				getFigure().repaint();
-			} else {
-				chartListener.endPainting();
-			}
-		} catch (ChartException ce) {
-			StatusManager.getManager().handle(new Status(Status.WARNING, AGFChartPlugin.PLUGIN_ID, "Couldn't generate chart.", ce));
-			chartListener.endPainting();
-		}
-	}
-
-	/**
-	 * Creates the image.
-	 */
-	public void createImage() {
-		Dimension area = getFigure().getSize();
-		Rectangle swtBounds = new Rectangle(0, 0, Math.max(area.width, 10), Math.max(area.height, 10));
-		if (resourceManager.getImage() == null || !resourceManager.getImage().getBounds().equals(swtBounds)) {
-			resourceManager.setImage(new Image(getViewer().getControl().getDisplay(), swtBounds));
-			resourceManager.setGc(new GC(resourceManager.getImage()));
-			renderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, resourceManager.getGc());
-		}
-	}
-
-	/**
-	 * Creates the chart.
-	 */
-	public synchronized void createChart() {
-		chart = chartStrategy.createChart(dataProvider, dataSource);
-		chart.getTitle().getLabel().setVisible(false);
-	}
-
-	/**
-	 * Update chart series.
-	 */
-	public synchronized void updateChartSelection() {
-		chartStrategy.updateSelection();
-		@SuppressWarnings("rawtypes")
-		List valueSets = dataProvider.getValueSets(dataSource);
-		chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries().clear();
-		for (Object valueSet : valueSets) {
-			updateValueSetColor(valueSet);
-		}
-	}
-
-	/**
-	 * 
-	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel()
-	 */
-	public Chart getDesignTimeModel() {
-		return chart;
-	}
-
-	/**
-	 * 
-	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel()
-	 */
-	public Chart getRunTimeModel() {
-		return chartState.getChartModel();
-	}
-
-	ChartModelListener getChartListener() {
-		return chartListener;
-	}
-
-	IChartDesignStrategy getChartStrategy() {
-		return chartStrategy;
-	}
-
-	Object getDataSource() {
-		return dataSource;
-	}
-
-	IDataSelectionListener getDataListener() {
-		return dataListener;
-	}
-
-	/**
-	 * 
-	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance()
-	 */
-	public Object peerInstance() {
-		return this;
-	}
-
-	/**
-	 * 
-	 * @see org.eclipse.birt.chart.device.ICallBackNotifier#callback(java.lang.Object, java.lang.Object,
-	 *      org.eclipse.birt.chart.model.attribute.CallBackValue)
-	 */
-	public void callback(Object arg0, Object arg1, CallBackValue arg2) {
-		//
-	}
-
-	/**
-	 * Gets the chart.
-	 * 
-	 * @return the chart
-	 */
-	public Chart getChart() {
-		return chart;
-	}
-
-	/**
-	 * Sets the series color provider.
-	 * 
-	 * @param seriesColorProvider
-	 *          the new series color provider
-	 */
-	public void setSeriesColorProvider(IColorProvider seriesColorProvider) {
-		this.seriesColorProvider = seriesColorProvider;
-	}
-
-	/**
-	 * 
-	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart()
-	 */
-	public void repaintChart() {
-		refresh();
-	}
-
-	@Override
-	public void deactivate() {
-		super.deactivate();
-		dataProvider.removeListener(dataSource, dataListener);
-	}
-
-	/**
-	 * Gets the data provider.
-	 * 
-	 * @return the data provider
-	 */
-	public IDataProvider getDataProvider() {
-		return dataProvider;
-	}
-
-	/**
-	 * Sets the data provider.
-	 * 
-	 * @param dataProvider
-	 *          the new data provider
-	 */
-	public synchronized void setDataProvider(IDataProvider dataProvider) {
-		this.dataProvider = dataProvider;
-		dataSource = dataProvider.getDataSource(getModel());
-		dataListener = new IDataSelectionListener() {
-			public void selectionChanged(Object dataSet) {
-				if (getParent() != null && getRoot() != null && getViewer() != null && getChart() != null) {
-					updateChartSelection();
-					getViewer().getControl().getDisplay().asyncExec(new Runnable() {
-						public void run() {
-							regenerateChart(true);
-						}
-					});
-				}
-			}
-		};
-		dataProvider.addListener(dataSource, dataListener);
-	}
-
-	public void setChartStrategy(IChartDesignStrategy chartStrategy) {
-		this.chartStrategy = chartStrategy;
-		createChart();
-		updateChartSelection();
-		if (getViewer().getControl().getDisplay() != null) {
-			getViewer().getControl().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					repaintChart();
-				}
-			});
-		}
-	}
-
-	/**
-	 * Gets the series color provider.
-	 * 
-	 * @return the series color provider
-	 */
-	public IColorProvider getSeriesColorProvider() {
-		return seriesColorProvider;
-	}
-
-	ResourceManager getResourceManager() {
-		return resourceManager;
-	}
-	/**
-	 * Encapsulate the dispose of gc and image
-	 * @author fei
-	 *
-	 */
-	class ResourceManager implements DisposeListener{
-		private GC gc;
-
-		private Image image;
-		
-		private Control attachedToDispose;
-
-		public ResourceManager() {
-			// 
-		}
-
-		void setGc(GC gc) {
-			if (this.gc != null && !this.gc.isDisposed()) {
-				this.gc.dispose();
-			}
-			this.gc = gc;
-			addDisposeListener();
-		}
-		
-		GC getGc() {
-			return gc;
-		}
-
-		private void addDisposeListener(){
-			assert attachedToDispose == null || attachedToDispose.equals(getViewer().getControl());
-			if(attachedToDispose == null && getViewer() != null){
-				attachedToDispose = getViewer().getControl();
-				attachedToDispose.addDisposeListener(this);
-			}
-		}
-		
-		Image getImage() {
-			return image;
-		}
-
-		void setImage(Image image) {
-			if (this.image != null && !this.image.isDisposed()) {
-				this.image.dispose();
-			}
-			this.image = image;
-			addDisposeListener();
-		}
-
-		public void widgetDisposed(DisposeEvent arg0) {
-			setImage(null);
-			setGc(null);
-		}
-	}
-}
+/**

+ * <copyright>

+ *

+ * Copyright (c) 2009 Metascape, LLC.

+ * 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:

+ *   Metascape - Initial API and Implementation

+ *

+ * </copyright>

+ *

+ */

+package org.eclipse.amp.agf.chart;

+

+import java.util.List;

+

+import org.eclipse.amp.agf.chart.ide.AGFChartPlugin;

+import org.eclipse.amp.axf.core.IModel;

+import org.eclipse.amp.axf.core.IObservationProvider;

+import org.eclipse.amp.axf.view.SWTAsyncModelListener;

+import org.eclipse.birt.chart.api.ChartEngine;

+import org.eclipse.birt.chart.device.ICallBackNotifier;

+import org.eclipse.birt.chart.device.IDeviceRenderer;

+import org.eclipse.birt.chart.exception.ChartException;

+import org.eclipse.birt.chart.factory.GeneratedChartState;

+import org.eclipse.birt.chart.factory.Generator;

+import org.eclipse.birt.chart.factory.RunTimeContext;

+import org.eclipse.birt.chart.model.Chart;

+import org.eclipse.birt.chart.model.attribute.Bounds;

+import org.eclipse.birt.chart.model.attribute.CallBackValue;

+import org.eclipse.birt.chart.model.attribute.ColorDefinition;

+import org.eclipse.birt.chart.model.attribute.Fill;

+import org.eclipse.birt.chart.model.attribute.Palette;

+import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;

+import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;

+import org.eclipse.birt.chart.model.attribute.impl.PaletteImpl;

+import org.eclipse.birt.core.framework.PlatformConfig;

+import org.eclipse.core.runtime.IAdapterManager;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.draw2d.AbstractLayout;

+import org.eclipse.draw2d.Figure;

+import org.eclipse.draw2d.FigureListener;

+import org.eclipse.draw2d.Graphics;

+import org.eclipse.draw2d.IFigure;

+import org.eclipse.draw2d.geometry.Dimension;

+import org.eclipse.draw2d.geometry.Point;

+import org.eclipse.emf.common.util.EList;

+import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

+import org.eclipse.jface.viewers.IColorProvider;

+import org.eclipse.swt.events.DisposeEvent;

+import org.eclipse.swt.events.DisposeListener;

+import org.eclipse.swt.graphics.Color;

+import org.eclipse.swt.graphics.GC;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.graphics.Rectangle;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.ui.statushandlers.StatusManager;

+

+public class ChartEditPart extends AbstractGraphicalEditPart implements ICallBackNotifier {

+

+	private Chart chart;

+

+	private final ResourceManager resourceManager;

+

+	private IDeviceRenderer renderer;

+

+	private GeneratedChartState chartState;

+

+	private IDataProvider dataProvider;

+

+	private IColorProvider seriesColorProvider;

+

+	private Palette genericPalette;

+

+	private Object dataSource;

+

+	private ChartModelListener chartListener;

+

+	private IDataSelectionListener dataListener;

+

+	private int nextOpenPaletteIndex;

+

+	private IChartDesignStrategy chartStrategy;

+

+	/**

+	 * Instantiates a new chart edit part.

+	 */

+	public ChartEditPart() {

+		resourceManager = new ResourceManager();

+		PlatformConfig config = new PlatformConfig();

+		try {

+			config.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this);

+			renderer = ChartEngine.instance(config).getRenderer("dv.SWT");

+		} catch (ChartException e) {

+			throw new RuntimeException(e);

+		}

+		genericPalette = PaletteImpl.create(0, true);

+		genericPalette.shift(0);

+	}

+

+	/**

+	 * The listener interface for receiving chartModel events. The class that is

+	 * interested in processing a chartModel event implements this interface, and

+	 * the object created with that class is registered with a component using the

+	 * component's <code>addChartModelListener<code> method. When

+	 * the chartModel event occurs, that object's appropriate

+	 * method is invoked.

+	 * 

+	 * @see ChartModelEvent

+	 */

+	class ChartModelListener extends SWTAsyncModelListener {

+		/**

+		 * Instantiates a new chart model listener.

+		 */

+		public ChartModelListener() {

+			super(null, "Chart Updated View", 10000);

+		}

+

+		@Override

+		public void observing(IObservationProvider observed) {

+			// wait for data source to be available from model set..

+			while (getDataProvider() == null) {

+				try {

+					Thread.sleep(25);

+				} catch (InterruptedException e) {

+					//

+				}

+			}

+			setChartStrategy(ChartType.TIME_SERIES.createStrategy());

+		}

+

+		@Override

+		public void observeStart(IObservationProvider observed) {

+			updateChartSelection();

+			endPainting();

+		}

+

+		@Override

+		public void observeInitialize(IObservationProvider model) {

+			getResourceManager().setImage(null);

+		}

+

+		@Override

+		public void update(final IModel model) {

+			beginPainting();

+			getChartStrategy().update();

+			refresh();

+		}

+

+		@Override

+		public void observationEnd(IObservationProvider model) {

+			getDataProvider().removeListener(getDataSource(), getDataListener());

+			model = null;

+		}

+

+	}

+

+	private void updateValueSetColor(Object valueSet) {

+		String seriesLabel = dataProvider.getText(valueSet);

+		Color swtColor = seriesColorProvider.getForeground(seriesLabel);

+		EList<Fill> entries = chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries();

+		ColorDefinition cd = null;

+		if (swtColor == null) {

+			// List<Fill> palette = ySeriesDefinition.getSeriesPalette().getEntries();

+			// if (nextOpenPaletteIndex >= palette.size()) {

+			// nextOpenPaletteIndex = 0;

+			// }

+			// cd = (ColorDefinition) palette.get(nextOpenPaletteIndex);

+			// Color lineColor = new

+			// Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(),

+			// cd.getGreen(), cd

+			// .getBlue());

+			if (seriesColorProvider instanceof CachedColorProvider) {

+				cd = (ColorDefinition) genericPalette.getEntries().get(nextOpenPaletteIndex++);

+				if (nextOpenPaletteIndex > genericPalette.getEntries().size() - 1) {

+					nextOpenPaletteIndex = 0;

+				}

+				swtColor = new Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(), cd.getGreen(), cd.getBlue());

+				((CachedColorProvider) seriesColorProvider).putForegroundColor(seriesLabel, swtColor);

+			}

+		} else {

+			cd = ColorDefinitionImpl.create(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue());

+			// if (chartType == ChartType.TIME_SERIES) {

+			// cd = ((LineSeries) lineSeries).getLineAttributes().getColor();

+			// } else if (chartType == ChartType.STACKED_AREA) {

+			// cd = ((AreaSeries) lineSeries).getLineAttributes().getColor();

+			// }

+			// cd.setRed(swtColor.getRed());

+			// cd.setGreen(swtColor.getGreen());

+			// cd.setBlue(swtColor.getBlue());

+		}

+		entries.add(cd);

+	}

+

+	@Override

+	protected IFigure createFigure() {

+		chartListener.setWidget(getViewer().getControl());

+

+		final Figure newFigure = new Figure() {

+			@Override

+			public void paintFigure(Graphics graphics) {

+				if (getResourceManager().getImage() != null) {

+					graphics.drawImage(getResourceManager().getImage(), 0, 0);

+					if (getChartListener() != null) {

+						getChartListener().endPainting();

+					}

+				}

+			}

+		};

+		newFigure.setLayoutManager(new AbstractLayout() {

+			@Override

+			public Dimension getMinimumSize(IFigure container, int hintWidth, int hintHeight) {

+				return new Dimension(hintWidth < 1 ? 1 : hintWidth, hintHeight < 1 ? 1 : hintHeight);

+			}

+

+			@Override

+			protected Dimension calculatePreferredSize(IFigure container, int hintWidth, int hintHeight) {

+				return new Dimension(hintWidth < 1 ? 100 : hintWidth, hintHeight < 1 ? 100 : hintHeight);

+			}

+

+			public void layout(IFigure container) {

+				newFigure.setLocation(new Point(0, 0));

+			}

+		});

+		newFigure.addFigureListener(new FigureListener() {

+			public void figureMoved(IFigure source) {

+				regenerateChart();

+			}

+		});

+

+		return newFigure;

+	}

+

+	@Override

+	protected void createEditPolicies() {

+		//

+	}

+

+	@Override

+	public void refresh() {

+		new Thread() {

+			@Override

+			public void run() {

+				regenerateChart(true);

+			}

+		}.run();

+	}

+

+	@Override

+	public void setModel(Object model) {

+		super.setModel(model);

+		chartListener = new ChartModelListener();

+		((IModel) model).addModelListener(chartListener);

+		IAdapterManager adapterManager = Platform.getAdapterManager();

+		// We seem to need to force loading of the data provider, at least in the

+		// exemplar case

+		Object provider = adapterManager.loadAdapter(this.getModel(), "org.eclipse.amp.agf.chart.IDataProvider");

+

+		if (!(provider instanceof IDataProvider)) {

+			throw new RuntimeException("Couldn't find data provider for chart model. Please ensure that a data provider adapter has been defined for the class: " + this.getModel().getClass());

+		}

+

+		setDataProvider((IDataProvider) provider);

+

+		// createChart();

+	}

+

+	/**

+	 * 

+	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart()

+	 */

+	public void regenerateChart() {

+		regenerateChart(true);

+	}

+

+	/**

+	 * Regenerate chart.

+	 * 

+	 * @param forceNewImage

+	 *          the force new image

+	 */

+	public synchronized void regenerateChart(boolean forceNewImage) {

+		if (forceNewImage) {

+			getResourceManager().setImage(null);

+		}

+		try {

+			if (chart != null && chartStrategy.isInitialized() && getFigure() != null && !getFigure().getSize().isEmpty()) {

+				createImage();

+				Dimension area = getFigure().getSize();

+				Bounds chartBounds = BoundsImpl.create(0, 0, area.width, area.height);

+				chartBounds.scale(72d / renderer.getDisplayServer().getDpiResolution());

+				Generator gr = Generator.instance();

+				RunTimeContext rtc = new RunTimeContext();

+				rtc.setScriptingEnabled(false);

+

+				// rtc.setScriptContext(csc);

+				// csc.setChartInstance(chart);

+				chartState = gr.build(renderer.getDisplayServer(), chart, chartBounds, rtc);

+				gr.render(renderer, chartState);

+				getFigure().repaint();

+			} else {

+				chartListener.endPainting();

+			}

+		} catch (ChartException ce) {

+			StatusManager.getManager().handle(new Status(Status.WARNING, AGFChartPlugin.PLUGIN_ID, "Couldn't generate chart.", ce));

+			chartListener.endPainting();

+		}

+	}

+

+	/**

+	 * Creates the image.

+	 */

+	public void createImage() {

+		Dimension area = getFigure().getSize();

+		Rectangle swtBounds = new Rectangle(0, 0, Math.max(area.width, 10), Math.max(area.height, 10));

+		if (resourceManager.getImage() == null || !resourceManager.getImage().getBounds().equals(swtBounds)) {

+			resourceManager.setImage(new Image(getViewer().getControl().getDisplay(), swtBounds));

+			resourceManager.setGc(new GC(resourceManager.getImage()));

+			renderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, resourceManager.getGc());

+		}

+	}

+

+	/**

+	 * Creates the chart.

+	 */

+	public synchronized void createChart() {

+		chart = chartStrategy.createChart(dataProvider, dataSource);

+		chart.getTitle().getLabel().setVisible(false);

+	}

+

+	/**

+	 * Update chart series.

+	 */

+	public synchronized void updateChartSelection() {

+		chartStrategy.updateSelection();

+		@SuppressWarnings("rawtypes")

+		List valueSets = dataProvider.getValueSets(dataSource);

+		chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries().clear();

+		for (Object valueSet : valueSets) {

+			updateValueSetColor(valueSet);

+		}

+	}

+

+	/**

+	 * 

+	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel()

+	 */

+	public Chart getDesignTimeModel() {

+		return chart;

+	}

+

+	/**

+	 * 

+	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel()

+	 */

+	public Chart getRunTimeModel() {

+		return chartState.getChartModel();

+	}

+

+	ChartModelListener getChartListener() {

+		return chartListener;

+	}

+

+	IChartDesignStrategy getChartStrategy() {

+		return chartStrategy;

+	}

+

+	Object getDataSource() {

+		return dataSource;

+	}

+

+	IDataSelectionListener getDataListener() {

+		return dataListener;

+	}

+

+	/**

+	 * 

+	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance()

+	 */

+	public Object peerInstance() {

+		return this;

+	}

+

+	/**

+	 * 

+	 * @see org.eclipse.birt.chart.device.ICallBackNotifier#callback(java.lang.Object,

+	 *      java.lang.Object,

+	 *      org.eclipse.birt.chart.model.attribute.CallBackValue)

+	 */

+	public void callback(Object arg0, Object arg1, CallBackValue arg2) {

+		//

+	}

+

+	/**

+	 * Gets the chart.

+	 * 

+	 * @return the chart

+	 */

+	public Chart getChart() {

+		return chart;

+	}

+

+	/**

+	 * Sets the series color provider.

+	 * 

+	 * @param seriesColorProvider

+	 *          the new series color provider

+	 */

+	public void setSeriesColorProvider(IColorProvider seriesColorProvider) {

+		this.seriesColorProvider = seriesColorProvider;

+	}

+

+	/**

+	 * 

+	 * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart()

+	 */

+	public void repaintChart() {

+		refresh();

+	}

+

+	@Override

+	public void deactivate() {

+		super.deactivate();

+		dataProvider.removeListener(dataSource, dataListener);

+	}

+

+	/**

+	 * Gets the data provider.

+	 * 

+	 * @return the data provider

+	 */

+	public IDataProvider getDataProvider() {

+		return dataProvider;

+	}

+

+	/**

+	 * Sets the data provider.

+	 * 

+	 * @param dataProvider

+	 *          the new data provider

+	 */

+	public synchronized void setDataProvider(IDataProvider dataProvider) {

+		this.dataProvider = dataProvider;

+		dataSource = dataProvider.getDataSource(getModel());

+		dataListener = new IDataSelectionListener() {

+			public void selectionChanged(Object dataSet) {

+				if (getParent() != null && getRoot() != null && getViewer() != null && getChart() != null) {

+					updateChartSelection();

+					getViewer().getControl().getDisplay().asyncExec(new Runnable() {

+						public void run() {

+							regenerateChart(true);

+						}

+					});

+				}

+			}

+		};

+		dataProvider.addListener(dataSource, dataListener);

+	}

+

+	public void setChartStrategy(IChartDesignStrategy chartStrategy) {

+		this.chartStrategy = chartStrategy;

+		createChart();

+		updateChartSelection();

+		if (getViewer().getControl().getDisplay() != null) {

+			getViewer().getControl().getDisplay().asyncExec(new Runnable() {

+				public void run() {

+					repaintChart();

+				}

+			});

+		}

+	}

+

+	/**

+	 * Gets the series color provider.

+	 * 

+	 * @return the series color provider

+	 */

+	public IColorProvider getSeriesColorProvider() {

+		return seriesColorProvider;

+	}

+

+	ResourceManager getResourceManager() {

+		return resourceManager;

+	}

+

+	/**

+	 * Encapsulate disposing of {@link GC} and {@link Image} resources.

+	 * 

+	 * @author fei

+	 */

+	class ResourceManager implements DisposeListener {

+		private GC gc;

+

+		private Image image;

+

+		private Control disposeEventProvider;

+

+		public ResourceManager() {

+			//

+		}

+

+		void setGc(GC gc) {

+			if (this.gc != null && !this.gc.isDisposed()) {

+				this.gc.dispose();

+			}

+			this.gc = gc;

+			addDisposeListener();

+		}

+

+		GC getGc() {

+			return gc;

+		}

+

+		private void removeDisposeListener() {

+			if (disposeEventProvider != null) {

+				if (!disposeEventProvider.isDisposed()) {

+					if (getViewer() != null && disposeEventProvider.equals(getViewer().getControl())) {

+						return;

+					}

+

+					disposeEventProvider.removeDisposeListener(this);

+				}

+				disposeEventProvider = null;

+			}

+		}

+

+		private void addDisposeListener() {

+			removeDisposeListener();

+			if (disposeEventProvider == null && getViewer() != null && getViewer().getControl() != null && !getViewer().getControl().isDisposed()) {

+				disposeEventProvider = getViewer().getControl();

+				disposeEventProvider.addDisposeListener(this);

+			}

+		}

+

+		Image getImage() {

+			return image;

+		}

+

+		void setImage(Image image) {

+			if (this.image != null && !this.image.isDisposed()) {

+				this.image.dispose();

+			}

+			this.image = image;

+			addDisposeListener();

+		}

+

+		public void widgetDisposed(DisposeEvent arg0) {

+			setImage(null);

+			setGc(null);

+			removeDisposeListener();

+		}

+	}

+}