public static void initializeStyling(Display display, IEclipseContext appContext) {
    String cssTheme = (String) appContext.get(E4Application.THEME_ID);
    String cssURI = (String) appContext.get(E4Workbench.CSS_URI_ARG);

    if (cssTheme != null) {
      String cssResourcesURI = (String) appContext.get(E4Workbench.CSS_RESOURCE_URI_ARG);

      Bundle bundle = WorkbenchSWTActivator.getDefault().getBundle();
      BundleContext context = bundle.getBundleContext();
      ServiceReference ref = context.getServiceReference(IThemeManager.class.getName());
      IThemeManager mgr = (IThemeManager) context.getService(ref);
      final IThemeEngine engine = mgr.getEngineForDisplay(display);

      // Store the app context
      IContributionFactory contribution =
          (IContributionFactory) appContext.get(IContributionFactory.class.getName());
      IEclipseContext cssContext = EclipseContextFactory.create();
      cssContext.set(IContributionFactory.class.getName(), contribution);
      display.setData("org.eclipse.e4.ui.css.context", cssContext); // $NON-NLS-1$

      // Create the OSGi resource locator
      if (cssResourcesURI != null) {
        // TODO: Should this be set through an extension as well?
        engine.registerResourceLocator(new OSGiResourceLocator(cssResourcesURI));
      }

      engine.restore(cssTheme);
      // TODO Should we create an empty default theme?

      appContext.set(IThemeEngine.class.getName(), engine);

      appContext.set(
          IStylingEngine.SERVICE_NAME,
          new IStylingEngine() {
            public void setClassname(Object widget, String classname) {
              WidgetElement.setCSSClass((Widget) widget, classname);
              engine.applyStyles((Widget) widget, true);
            }

            public void setId(Object widget, String id) {
              WidgetElement.setID((Widget) widget, id);
              engine.applyStyles((Widget) widget, true);
            }

            public void style(Object widget) {
              engine.applyStyles((Widget) widget, true);
            }

            public CSSStyleDeclaration getStyle(Object widget) {
              return engine.getStyle((Widget) widget);
            }

            public void setClassnameAndId(Object widget, String classname, String id) {
              WidgetElement.setCSSClass((Widget) widget, classname);
              WidgetElement.setID((Widget) widget, id);
              engine.applyStyles((Widget) widget, true);
            }
          });
    } else if (cssURI != null) {
      String cssResourcesURI = (String) appContext.get(E4Workbench.CSS_RESOURCE_URI_ARG);
      final CSSSWTEngineImpl engine = new CSSSWTEngineImpl(display, true);
      WidgetElement.setEngine(display, engine);
      if (cssResourcesURI != null) {
        engine
            .getResourcesLocatorManager()
            .registerResourceLocator(new OSGiResourceLocator(cssResourcesURI.toString()));
      }
      // FIXME: is this needed?
      display.setData("org.eclipse.e4.ui.css.context", appContext); // $NON-NLS-1$
      appContext.set(
          IStylingEngine.SERVICE_NAME,
          new IStylingEngine() {
            public void setClassname(Object widget, String classname) {
              WidgetElement.setCSSClass((Widget) widget, classname);
              engine.applyStyles((Widget) widget, true);
            }

            public void setId(Object widget, String id) {
              WidgetElement.setID((Widget) widget, id);
              engine.applyStyles((Widget) widget, true);
            }

            public void style(Object widget) {
              engine.applyStyles((Widget) widget, true);
            }

            public CSSStyleDeclaration getStyle(Object widget) {
              Element e = engine.getCSSElementContext(widget).getElement();
              if (e == null) {
                return null;
              }
              return engine.getViewCSS().getComputedStyle(e, null);
            }

            public void setClassnameAndId(Object widget, String classname, String id) {
              WidgetElement.setCSSClass((Widget) widget, classname);
              WidgetElement.setID((Widget) widget, id);
              engine.applyStyles((Widget) widget, true);
            }
          });

      URL url;
      InputStream stream = null;
      try {
        url = FileLocator.resolve(new URL(cssURI));
        stream = url.openStream();
        engine.parseStyleSheet(stream);
      } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } finally {
        if (stream != null) {
          try {
            stream.close();
          } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
      }

      Shell[] shells = display.getShells();
      for (Shell s : shells) {
        try {
          s.setRedraw(false);
          s.reskin(SWT.ALL);
          engine.applyStyles(s, true);
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } finally {
          s.setRedraw(true);
        }
      }
    }

    CSSRenderingUtils cssUtils = ContextInjectionFactory.make(CSSRenderingUtils.class, appContext);
    appContext.set(CSSRenderingUtils.class, cssUtils);
  }
  private void drag(Event dragEvent) {
    DNDEvent event = new DNDEvent();
    event.widget = this;
    event.x = dragEvent.x;
    event.y = dragEvent.y;
    event.time = OS.GetMessageTime();
    event.doit = true;
    notifyListeners(DND.DragStart, event);
    if (!event.doit || transferAgents == null || transferAgents.length == 0) return;

    int[] pdwEffect = new int[1];
    int operations = opToOs(getStyle());
    Display display = control.getDisplay();
    String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; // $NON-NLS-1$
    Object oldValue = display.getData(key);
    display.setData(key, Boolean.TRUE);
    ImageList imagelist = null;
    Image image = event.image;
    hwndDrag = 0;
    topControl = null;
    if (image != null) {
      imagelist = new ImageList(SWT.NONE);
      imagelist.add(image);
      topControl = control.getShell();
      /*
       * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT.
       * The fix is to create a transparent window that covers the shell client
       * area and use it during the drag to prevent the image from being inverted.
       * On XP if the shell is RTL, the image is not displayed.
       */
      int offsetX = event.offsetX;
      hwndDrag = topControl.handle;
      if ((topControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0) {
        offsetX = image.getBounds().width - offsetX;
        RECT rect = new RECT();
        OS.GetClientRect(topControl.handle, rect);
        hwndDrag =
            OS.CreateWindowEx(
                OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT,
                WindowClass,
                null,
                OS.WS_CHILD | OS.WS_CLIPSIBLINGS,
                0,
                0,
                rect.right - rect.left,
                rect.bottom - rect.top,
                topControl.handle,
                0,
                OS.GetModuleHandle(null),
                null);
        OS.ShowWindow(hwndDrag, OS.SW_SHOW);
      }
      OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offsetX, event.offsetY);
      /*
       * Feature in Windows. When ImageList_DragEnter() is called,
       * it takes a snapshot of the screen  If a drag is started
       * when another window is in front, then the snapshot will
       * contain part of the other window, causing pixel corruption.
       * The fix is to force all paints to be delivered before
       * calling ImageList_DragEnter().
       */
      if (OS.IsWinCE) {
        OS.UpdateWindow(topControl.handle);
      } else {
        int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
        OS.RedrawWindow(topControl.handle, null, 0, flags);
      }
      POINT pt = new POINT();
      pt.x = dragEvent.x;
      pt.y = dragEvent.y;
      OS.MapWindowPoints(control.handle, 0, pt, 1);
      RECT rect = new RECT();
      OS.GetWindowRect(hwndDrag, rect);
      OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top);
    }
    int result = COM.DRAGDROP_S_CANCEL;
    try {
      result =
          COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect);
    } finally {
      // ensure that we don't leave transparent window around
      if (hwndDrag != 0) {
        OS.ImageList_DragLeave(hwndDrag);
        OS.ImageList_EndDrag();
        imagelist.dispose();
        if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag);
        hwndDrag = 0;
        topControl = null;
      }
      display.setData(key, oldValue);
    }
    int operation = osToOp(pdwEffect[0]);
    if (dataEffect == DND.DROP_MOVE) {
      operation =
          (operation == DND.DROP_NONE || operation == DND.DROP_COPY)
              ? DND.DROP_TARGET_MOVE
              : DND.DROP_MOVE;
    } else {
      if (dataEffect != DND.DROP_NONE) {
        operation = dataEffect;
      }
    }
    event = new DNDEvent();
    event.widget = this;
    event.time = OS.GetMessageTime();
    event.doit = (result == COM.DRAGDROP_S_DROP);
    event.detail = operation;
    notifyListeners(DND.DragEnd, event);
    dataEffect = DND.DROP_NONE;
  }