Revert "Bug 354549 timing problems in ChartView"

This reverts commit 20e0d32b40e19ef8161d96361a18ee4937100985.
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 c207c9c..d706c3a 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
@@ -49,7 +49,6 @@
 import org.eclipse.draw2d.geometry.Dimension;

 import org.eclipse.draw2d.geometry.Point;

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

-import org.eclipse.gef.EditPart;

 import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

 import org.eclipse.jface.viewers.IColorProvider;

 import org.eclipse.swt.events.DisposeEvent;

@@ -91,7 +90,6 @@
 	 * Instantiates a new chart edit part.

 	 */

 	public ChartEditPart() {

-		chartStrategy = getInitStrategie();

 		resourceManager = new ResourceManager();

 		PlatformConfig config = new PlatformConfig();

 		try {

@@ -104,10 +102,6 @@
 		genericPalette.shift(0);

 	}

 

-	IChartDesignStrategy getInitStrategie() {

-		return ChartType.TIME_SERIES.createStrategy();

-	}

-

 	/**

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

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

@@ -119,7 +113,6 @@
 	 * @see ChartModelEvent

 	 */

 	class ChartModelListener extends SWTAsyncModelListener {

-

 		/**

 		 * Instantiates a new chart model listener.

 		 */

@@ -129,7 +122,15 @@
 

 		@Override

 		public void observing(IObservationProvider observed) {

-			setChartStrategy(getInitStrategie());

+			// 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

@@ -200,7 +201,6 @@
 		chartListener.setWidget(getViewer().getControl());

 

 		final Figure newFigure = new Figure() {

-

 			@Override

 			public void paintFigure(Graphics graphics) {

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

@@ -212,7 +212,6 @@
 			}

 		};

 		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);

@@ -228,7 +227,6 @@
 			}

 		});

 		newFigure.addFigureListener(new FigureListener() {

-

 			public void figureMoved(IFigure source) {

 				regenerateChart();

 			}

@@ -244,7 +242,12 @@
 

 	@Override

 	public void refresh() {

-		regenerateChart(true);

+		new Thread() {

+			@Override

+			public void run() {

+				regenerateChart(true);

+			}

+		}.run();

 	}

 

 	@Override

@@ -258,9 +261,7 @@
 		Object provider = adapterManager.loadAdapter(this.getModel(), IDataProvider.ID);

 

 		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());

+			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);

@@ -305,8 +306,7 @@
 				chartListener.endPainting();

 			}

 		} catch (ChartException ce) {

-			StatusManager.getManager().handle(

-					new Status(Status.WARNING, AGFChartPlugin.PLUGIN_ID, "Couldn't generate chart.", ce));

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

 			chartListener.endPainting();

 		}

 	}

@@ -325,6 +325,14 @@
 	}

 

 	/**

+	 * Creates the chart.

+	 */

+	public synchronized void createChart() {

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

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

+	}

+

+	/**

 	 * Update chart series.

 	 */

 	public synchronized void updateChartSelection() {

@@ -379,7 +387,8 @@
 

 	/**

 	 * 

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

+	 * @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) {

@@ -438,12 +447,10 @@
 		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);

 						}

@@ -452,24 +459,14 @@
 			}

 		};

 		dataProvider.addListener(dataSource, dataListener);

-		createAndInitChart();

 	}

 

 	public void setChartStrategy(IChartDesignStrategy chartStrategy) {

 		this.chartStrategy = chartStrategy;

-		createAndInitChart();

-	}

-

-	private void createAndInitChart() {

-		if(dataProvider == null){

-			return;

-		}

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

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

+		createChart();

 		updateChartSelection();

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

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

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

-

 				public void run() {

 					repaintChart();

 				}

@@ -496,7 +493,6 @@
 	 * @author fei

 	 */

 	public class ResourceManager implements DisposeListener {

-

 		private GC gc;

 

 		private Image image;

@@ -534,8 +530,7 @@
 

 		private void addDisposeListener() {

 			removeDisposeListener();

-			if (disposeEventProvider == null && getViewer() != null && getViewer().getControl() != null

-					&& !getViewer().getControl().isDisposed()) {

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

 				disposeEventProvider = getViewer().getControl();

 				disposeEventProvider.addDisposeListener(this);

 			}

diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/view/ScaleGranularityControl.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/view/ScaleGranularityControl.java
index 28ed94c..a4cbeb8 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/view/ScaleGranularityControl.java
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/view/ScaleGranularityControl.java
@@ -64,12 +64,7 @@
 			}

 		});

 

-		IModel activeModel = ModelViewManager.getInstance().getActiveModel();

-		if (activeModel != null) {

-			engine = activeModel.getEngine();

-		}

-

-		ModelViewManager.getInstance().getManagerListeners().addModelManagerListener(this);

+		ModelViewManager.getInstance().getManagerListeners().addModelManagerListener(ScaleGranularityControl.this);

 		return scale;

 	}

 

diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.views/src/org/eclipse/amp/axf/view/SWTAsyncModelListener.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.views/src/org/eclipse/amp/axf/view/SWTAsyncModelListener.java
index ab6c150..cb57ee0 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.views/src/org/eclipse/amp/axf/view/SWTAsyncModelListener.java
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.views/src/org/eclipse/amp/axf/view/SWTAsyncModelListener.java
@@ -15,9 +15,6 @@
  */
 package org.eclipse.amp.axf.view;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.eclipse.amp.axf.core.IModel;
 import org.eclipse.amp.axf.core.LifeCycleState;
 import org.eclipse.amp.axf.time.TimeGranularity;
@@ -36,161 +33,155 @@
  */
 public abstract class SWTAsyncModelListener extends SWTThreadModelListener {
 
-	private List<ReportingRunner> reportingRunners;
+    private final class ReportingRunner implements Runnable {
+        private final LifeCycleState key;
+        private final IModel model;
+        Exception t;
 
-	private boolean waitForPaint = true;
+        public ReportingRunner(LifeCycleState key, IModel model) {
+            this.key = key;
+            this.model = model;
+        }
 
-	private long minTimeBetweenUpdates = 10000;
+        public void run() {
+            try {
+                doUpdate(key, model);
+            } catch (Exception e) {
+                t = e;
+            } finally {
+                updating = false;
+                if (t != null) {
+                    painting = false;
+                    t.printStackTrace();
+                    throw new RuntimeException("Problem in view updating for " + getName(), t);
+                }
+            }
+        }
+    }
 
-	protected boolean updating = false;
+    private boolean waitForPaint = true;
 
-	private boolean painting = false;
+    private long minTimeBetweenUpdates = 10000;
 
-	private long lastUpdate;
+    protected boolean updating = false;
 
-	/**
-	 * Instantiates a new sWT async model listener.
-	 * 
-	 * @param widget the widget
-	 * @param name the name
-	 */
-	public SWTAsyncModelListener(Control widget, String name) {
-		super(widget, name);
-		reportingRunners = new ArrayList<SWTAsyncModelListener.ReportingRunner>();
-	}
+    private boolean painting = false;
 
-	/**
-	 * Instantiates a new sWT async model listener.
-	 * 
-	 * @param widget the widget
-	 * @param name the name
-	 * @param updatePeriod the update period
-	 */
-	public SWTAsyncModelListener(Control widget, String name, long updatePeriod) {
-		this(widget, name);
-		this.minTimeBetweenUpdates = updatePeriod;
-	}
+    private long lastUpdate;
 
-	List<ReportingRunner> getReportingRunners() {
-		return reportingRunners;
-	}
+    /**
+     * Instantiates a new sWT async model listener.
+     * 
+     * @param widget the widget
+     * @param name the name
+     */
+    public SWTAsyncModelListener(Control widget, String name) {
+        super(widget, name);
+    }
 
-	/**
-	 * @param key
-	 * @param observed
-	 * @see org.eclipse.amp.axf.core.AbstractLifecycleListener#stateChange(java.lang.Object, java.lang.Object)
-	 */
-	@Override
-	public void stateChange(Object key, Object observed) {
-		IModel model = (IModel) observed;
-		if (model.getEngine().isRunning()
-				&& (System.currentTimeMillis() > lastUpdate + minTimeBetweenUpdates || model.getPeriod()
-						% ((TimeGranularity) model.getEngine().getUpdateGranularity()).getUpdateFrequency() == 0)) {
-			lastUpdate = System.currentTimeMillis();
-			updating = true;
-			if (AXFViewPlugin.getDefault() != null) {
-				Display display = AXFViewPlugin.getDefault().getWorkbench().getDisplay();
-				if (!display.isDisposed()) {
-					ReportingRunner runnable = new ReportingRunner((LifeCycleState) key, model);
-					reportingRunners.add(runnable);
-					display.asyncExec(runnable);
+    /**
+     * Instantiates a new sWT async model listener.
+     * 
+     * @param widget the widget
+     * @param name the name
+     * @param updatePeriod the update period
+     */
+    public SWTAsyncModelListener(Control widget, String name, long updatePeriod) {
+        super(widget, name);
+        this.minTimeBetweenUpdates = updatePeriod;
+    }
 
-				}
-			}
-		} else if (key == LifeCycleState.OBSERVED || key == LifeCycleState.END) {
-			SWTAsyncModelListener.super.stateChange(key, model);
-		}
-		// Even though model is not null on method entrance (state change), it could become null during execution of
-		// reporting runner
-		if (model != null) {
-			forceModelNotify(model);
-		}
-	}
+    /**
+     * @param key
+     * @param observed
+     * @see org.eclipse.amp.axf.core.AbstractLifecycleListener#stateChange(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public void stateChange(Object key, Object observed) {
+        IModel model = (IModel) observed;
+        if (model.getEngine().isRunning()
+                && (System.currentTimeMillis() > lastUpdate + minTimeBetweenUpdates || model.getPeriod()
+                        % ((TimeGranularity) model.getEngine().getUpdateGranularity()).getUpdateFrequency() == 0)) {
+            lastUpdate = System.currentTimeMillis();
+            updating = true;
+            ReportingRunner runnable = new ReportingRunner((LifeCycleState) key, model);
+            if (AXFViewPlugin.getDefault() != null) {
+                Display display = AXFViewPlugin.getDefault().getWorkbench().getDisplay();
+                if (!display.isDisposed()) {
+                    display.asyncExec(runnable);
+                    while ((updating || painting) && isWaitForUpdate()
+                            && (getWidget() == null || !getWidget().isDisposed())) {
+                        try {
+                            // Assume best case of 60fps + allow compute
+                            Thread.sleep(5);
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                }
+            }
+            if (runnable.t != null) {
+                runnable.t.printStackTrace();
+            }
+        } else if (key == LifeCycleState.OBSERVED || key == LifeCycleState.END) {
+            SWTAsyncModelListener.super.stateChange(key, model);
+        }
+        // Even though model is not null on method entrance (state change), it could become null during execution of
+        // reporting runner
+        if (model != null) {
+            forceModelNotify(model);
+        }
+    }
 
-	private void doUpdate(Object key, final IModel model) {
-		// Have to check visibility within UI thread
-		if (getWidget() == null || !getWidget().isDisposed() && getWidget().isVisible()) {
-			update(model);
-			getListener().stateChange(key, model);
-		}
-		// If the update method hasn't explicitly indicated beginPainting, we are not waiting for the
-		// actual update or it has already occurred.
-		if (!painting) {
-		}
-	}
+    private void doUpdate(Object key, final IModel model) {
+        // Have to check visibility within UI thread
+        if (getWidget() == null || !getWidget().isDisposed() && getWidget().isVisible()) {
+            update(model);
+            getListener().stateChange(key, model);
+        }
+        // If the update method hasn't explicitly indicated beginPainting, we are not waiting for the
+        // actual update or it has already occurred.
+        if (!painting) {
+        }
+    }
 
-	/**
-	 * Force model notify.
-	 * 
-	 * @param model the model
-	 */
-	public void forceModelNotify(IModel model) {
-		model.getEngine().observationComplete(this);
-	}
+    /**
+     * Force model notify.
+     * 
+     * @param model the model
+     */
+    public void forceModelNotify(IModel model) {
+        model.getEngine().observationComplete(this);
+    }
 
-	/**
-	 * Begin painting.
-	 */
-	public void beginPainting() {
-		this.painting = true;
-	}
+    /**
+     * Begin painting.
+     */
+    public void beginPainting() {
+        this.painting = true;
+    }
 
-	/**
-	 * End painting.
-	 */
-	public void endPainting() {
-		this.painting = false;
-	}
+    /**
+     * End painting.
+     */
+    public void endPainting() {
+        this.painting = false;
+    }
 
-	/**
-	 * Sets the wait for paint.
-	 * 
-	 * @param waitForPaint the new wait for paint
-	 */
-	public void setWaitForUpdate(boolean waitForPaint) {
-		this.waitForPaint = waitForPaint;
-	}
+    /**
+     * Sets the wait for paint.
+     * 
+     * @param waitForPaint the new wait for paint
+     */
+    public void setWaitForUpdate(boolean waitForPaint) {
+        this.waitForPaint = waitForPaint;
+    }
 
-	/**
-	 * Checks if is wait for paint.
-	 * 
-	 * @return true, if is wait for paint
-	 */
-	public boolean isWaitForUpdate() {
-		return waitForPaint;
-	}
-
-	private final class ReportingRunner implements Runnable {
-
-		private final LifeCycleState key;
-
-		private final IModel model;
-
-		Exception t;
-
-		public ReportingRunner(LifeCycleState key, IModel model) {
-			this.key = key;
-			this.model = model;
-		}
-
-		public void run() {
-			try {
-				if (reportingRunners.size() > 1) {
-					return;
-				}
-				doUpdate(key, model);
-			} catch (Exception e) {
-				t = e;
-			} finally {
-				reportingRunners.remove(this);
-				updating = false;
-				if (t != null) {
-					painting = false;
-					t.printStackTrace();
-					throw new RuntimeException("Problem in view updating for " + getName(), t);
-				}
-			}
-		}
-	}
-
+    /**
+     * Checks if is wait for paint.
+     * 
+     * @return true, if is wait for paint
+     */
+    public boolean isWaitForUpdate() {
+        return waitForPaint;
+    }
 }
diff --git a/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ascape/src/org/eclipse/amp/escape/ascape/wrap/ScapeWrapperModel.java b/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ascape/src/org/eclipse/amp/escape/ascape/wrap/ScapeWrapperModel.java
index e8c2d09..022d4af 100644
--- a/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ascape/src/org/eclipse/amp/escape/ascape/wrap/ScapeWrapperModel.java
+++ b/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ascape/src/org/eclipse/amp/escape/ascape/wrap/ScapeWrapperModel.java
@@ -71,12 +71,17 @@
 	}
 
 	public void addModelListener(final ILifeCycleListener listener) {
-		listeners.add(listener);
-		if (!(listener instanceof ScapeWrapperModelListener)) {
-			ModelWrapperScapeListener wrapper = new ModelWrapperScapeListener(ScapeWrapperModel.this, getScape(), listener);
-			getScape().addView(wrapper);
-			wrapperForListener.put(listener, wrapper);
-		}
+		new Thread() {
+			@Override
+			public void run() {
+				listeners.add(listener);
+				if (!(listener instanceof ScapeWrapperModelListener)) {
+					ModelWrapperScapeListener wrapper = new ModelWrapperScapeListener(ScapeWrapperModel.this, getScape(), listener);
+					getScape().addView(wrapper);
+					wrapperForListener.put(listener, wrapper);
+				}
+			}
+		}.start();
 	}
 
 	public Collection<ILifeCycleListener> getModelListeners() {
@@ -84,11 +89,16 @@
 	}
 
 	public void removeModelListener(final ILifeCycleListener listener) {
-		listeners.remove(listener);
-		if (listener instanceof ScapeWrapperModelListener) {
-			getScape().removeScapeListener(((ScapeWrapperModelListener) listener).getWrapped());
-		}
-		listener.observationEnd(ScapeWrapperModel.this);
+		new Thread() {
+			@Override
+			public void run() {
+				listeners.remove(listener);
+				if (listener instanceof ScapeWrapperModelListener) {
+					getScape().removeScapeListener(((ScapeWrapperModelListener) listener).getWrapped());
+				}
+				listener.observationEnd(ScapeWrapperModel.this);
+			}
+		}.start();
 	}
 
 	public boolean isInitialized() {
diff --git a/org.eclipse.amp.escape/tests/org.eclipse.amp.escape.ide.test/src/org/eclipse/amp/escape/ide/ProjectLoaderTest.java b/org.eclipse.amp.escape/tests/org.eclipse.amp.escape.ide.test/src/org/eclipse/amp/escape/ide/ProjectLoaderTest.java
index e4e07e1..9c3ac80 100644
--- a/org.eclipse.amp.escape/tests/org.eclipse.amp.escape.ide.test/src/org/eclipse/amp/escape/ide/ProjectLoaderTest.java
+++ b/org.eclipse.amp.escape/tests/org.eclipse.amp.escape.ide.test/src/org/eclipse/amp/escape/ide/ProjectLoaderTest.java
@@ -6,12 +6,8 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
 import java.util.List;
 
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
@@ -35,7 +31,7 @@
 	 */
 	@Test
 	public void testReadDependencies() throws IllegalStateException, FileNotFoundException, BundleException, IOException {
-		List<Bundle> dependencies = ProjectLoader.readDependencies(getInputStream("defaultManifest.MF"));
+		List<Bundle> dependencies = ProjectLoader.readDependencies(new FileInputStream("testFiles/defaultManifest.MF"));
 		assertEquals(8, dependencies.size());
 		assertTrue(dependencies.contains(Platform.getBundle("org.eclipse.core.resources")));
 		assertTrue(dependencies.contains(Platform.getBundle("org.eclipse.core.runtime")));
@@ -57,7 +53,7 @@
 	 */
 	@Test
 	public void testReadDependencies_optionalBundles() throws IllegalStateException, FileNotFoundException, BundleException, IOException {
-		List<Bundle> dependencies = ProjectLoader.readDependencies(getInputStream("optionalBundles.MF"));
+		List<Bundle> dependencies = ProjectLoader.readDependencies(new FileInputStream("testFiles/optionalBundles.MF"));
 		assertEquals(8, dependencies.size());
 		assertTrue(dependencies.contains(Platform.getBundle("org.eclipse.core.resources")));
 		assertTrue(dependencies.contains(Platform.getBundle("org.eclipse.core.runtime")));
@@ -81,7 +77,7 @@
 	 */
 	@Test
 	public void testReadDependencies_bundleUnavalilableButOptional() throws IllegalStateException, FileNotFoundException, BundleException, IOException {
-		List<Bundle> dependencies = ProjectLoader.readDependencies(getInputStream("bundleUnavalilableButOptional.MF"));
+		List<Bundle> dependencies = ProjectLoader.readDependencies(new FileInputStream("testFiles/bundleUnavalilableButOptional.MF"));
 		assertEquals(8, dependencies.size());
 		assertTrue(dependencies.contains(Platform.getBundle("org.eclipse.core.resources")));
 		assertTrue(dependencies.contains(Platform.getBundle("org.eclipse.core.runtime")));
@@ -105,12 +101,7 @@
 	 */
 	@Test(expected = IllegalStateException.class)
 	public void testReadDependencies_bundleUnavailableButNecessary() throws IllegalStateException, FileNotFoundException, BundleException, IOException {
-		ProjectLoader.readDependencies(getInputStream("bundleUnavailableButNecessary.MF"));
+		ProjectLoader.readDependencies(new FileInputStream("testFiles/bundleUnavailableButNecessary.MF"));
 	}
 
-	private InputStream getInputStream(String fileName) throws IOException{
-		URL[] url = FileLocator.findEntries(EscapeIDEPlugin.getDefault().getBundle(), new Path("testFiles/"+fileName));
-		assert url.length == 1 : "Es wurde nicht genau einen Pfad gefunden. Erwartet wurde der Pfad für das:testFiles/" + fileName;
-		return url[0].openStream();
-	}
 }