@Override
						public void run() {
							/* Create an off-screen image to draw on, and fill it with the shell background. */
							Image offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight);
							GC offScreenImageGC = new GC(offScreenImage);
							offScreenImageGC.setBackground(shellBackground);
							offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight);
								
							try {
								/* Create the first image and draw it on the off-screen image. */
								int imageDataIndex = 0;	
								ImageData imageData = imageDataArray[imageDataIndex];
								if (image != null && !image.isDisposed()) image.dispose();
								image = new Image(display, imageData);
								offScreenImageGC.drawImage(
									image,
									0,
									0,
									imageData.width,
									imageData.height,
									imageData.x,
									imageData.y,
									imageData.width,
									imageData.height);

								/* Now loop through the images, creating and drawing each one
								 * on the off-screen image before drawing it on the shell. */
								int repeatCount = loader.repeatCount;
								while (loader.repeatCount == 0 || repeatCount > 0) {
									switch (imageData.disposalMethod) {
									case SWT.DM_FILL_BACKGROUND:
										/* Fill with the background color before drawing. */
										Color bgColor = null;
										if (useGIFBackground && loader.backgroundPixel != -1) {
											bgColor = new Color(display, imageData.palette.getRGB(loader.backgroundPixel));
										}
										offScreenImageGC.setBackground(bgColor != null ? bgColor : shellBackground);
										offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height);
										if (bgColor != null) bgColor.dispose();
										break;
									case SWT.DM_FILL_PREVIOUS:
										/* Restore the previous image before drawing. */
										offScreenImageGC.drawImage(
											image,
											0,
											0,
											imageData.width,
											imageData.height,
											imageData.x,
											imageData.y,
											imageData.width,
											imageData.height);
										break;
									}
														
									imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
									imageData = imageDataArray[imageDataIndex];
									image.dispose();
									image = new Image(display, imageData);
									offScreenImageGC.drawImage(
										image,
										0,
										0,
										imageData.width,
										imageData.height,
										imageData.x,
										imageData.y,
										imageData.width,
										imageData.height);
									
									/* Draw the off-screen image to the shell. */
									shellGC.drawImage(offScreenImage, 0, 0);
									
									/* Sleep for the specified delay time (adding commonly-used slow-down fudge factors). */
									try {
										int ms = imageData.delayTime * 10;
										if (ms < 20) ms += 30;
										if (ms < 30) ms += 10;
										Thread.sleep(ms);
									} catch (InterruptedException e) {
									}
									
									/* If we have just drawn the last image, decrement the repeat count and start again. */
									if (imageDataIndex == imageDataArray.length - 1) repeatCount--;
								}
							} catch (SWTException ex) {
								System.out.println("There was an error animating the GIF");
							} finally {
								if (offScreenImage != null && !offScreenImage.isDisposed()) offScreenImage.dispose();
								if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) offScreenImageGC.dispose();
								if (image != null && !image.isDisposed()) image.dispose();
							}
						}