diff --git a/org.eclipse.emf.cdo.threedee.ui/icons/text.gif b/org.eclipse.emf.cdo.threedee.ui/icons/text.gif
new file mode 100644
index 0000000..5990f5f
--- /dev/null
+++ b/org.eclipse.emf.cdo.threedee.ui/icons/text.gif
Binary files differ
diff --git a/org.eclipse.emf.cdo.threedee.ui/plugin.xml b/org.eclipse.emf.cdo.threedee.ui/plugin.xml
index ede5fe7..cec4052 100644
--- a/org.eclipse.emf.cdo.threedee.ui/plugin.xml
+++ b/org.eclipse.emf.cdo.threedee.ui/plugin.xml
@@ -21,6 +21,13 @@
             id="org.eclipse.emf.cdo.threedee.ui.ThreeDeeWorld"

             name="ThreeDee World">

       </view>

+      <view

+            category="org.eclipse.emf.cdo.threedee"

+            class="org.eclipse.emf.cdo.threedee.ui.InfoTransformView"

+            icon="icons/text.gif"

+            id="org.eclipse.emf.cdo.threedee.ui.InfoTransformView"

+            name="ThreeDee Info Transform">

+      </view>

    </extension>

 

 </plugin>

diff --git a/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/InfoTransformView.java b/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/InfoTransformView.java
new file mode 100644
index 0000000..9e856e3
--- /dev/null
+++ b/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/InfoTransformView.java
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) 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:
+ *    Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.threedee.ui;
+
+import org.eclipse.emf.cdo.threedee.ui.ThreeDeeWorld.InfoPanel;
+import org.eclipse.emf.cdo.threedee.ui.bundle.OM;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Slider;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+import javax.media.j3d.Transform3D;
+import javax.media.j3d.TransformGroup;
+import javax.vecmath.Vector3f;
+
+/**
+ * @author Eike Stepper
+ */
+public class InfoTransformView extends ViewPart
+{
+  public static final String ID = "org.eclipse.emf.cdo.threedee.ui.InfoTransformView";
+
+  public InfoTransformView()
+  {
+  }
+
+  @Override
+  public void createPartControl(Composite parent)
+  {
+    Composite composite = new Composite(parent, SWT.NONE);
+    composite.setLayout(new GridLayout(2, false));
+
+    try
+    {
+      IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+      if (page == null)
+      {
+        return;
+      }
+
+      ThreeDeeView view = (ThreeDeeView)page.findView(ThreeDeeView.ID);
+      InfoPanel infoPanel = view.getWorld().getInfoPanel();
+
+      Transform3D transform = new Transform3D();
+
+      final TransformGroup translationGroup = infoPanel.getTranslationGroup();
+      translationGroup.getTransform(transform);
+      Vector3f translation = new Vector3f();
+      transform.get(translation);
+
+      final TransformGroup scaleGroup = infoPanel.getScaleGroup();
+      scaleGroup.getTransform(transform);
+      double scale = transform.getScale();
+
+      final Transformer xTransformer = new Transformer(composite, "x", -1f, 0f, translation.getX());
+      final Transformer yTransformer = new Transformer(composite, "y", 0f, 1f, translation.getY());
+      final Transformer zTransformer = new Transformer(composite, "z", -2f, 2f, translation.getZ());
+
+      SelectionAdapter translationListener = new SelectionAdapter()
+      {
+        @Override
+        public void widgetSelected(SelectionEvent e)
+        {
+          float x = (float)xTransformer.getValue();
+          float y = (float)yTransformer.getValue();
+          float z = (float)zTransformer.getValue();
+
+          Transform3D transform = new Transform3D();
+          transform.set(new Vector3f(x, y, z));
+          translationGroup.setTransform(transform);
+        }
+      };
+
+      xTransformer.getSlider().addSelectionListener(translationListener);
+      yTransformer.getSlider().addSelectionListener(translationListener);
+      zTransformer.getSlider().addSelectionListener(translationListener);
+
+      final Transformer scaleTransformer = new Transformer(composite, "scale", 0.005f, 0.1f, scale);
+      scaleTransformer.getSlider().addSelectionListener(new SelectionAdapter()
+      {
+        @Override
+        public void widgetSelected(SelectionEvent e)
+        {
+          Transform3D transform = new Transform3D();
+          transform.setScale(scaleTransformer.getValue());
+          scaleGroup.setTransform(transform);
+        }
+      });
+    }
+    catch (Exception ex)
+    {
+      OM.LOG.error(ex);
+    }
+  }
+
+  @Override
+  public void dispose()
+  {
+    super.dispose();
+  }
+
+  @Override
+  public void setFocus()
+  {
+  }
+
+  /**
+   * @author Eike Stepper
+   */
+  private static class Transformer
+  {
+    private static final int MAX = 1000;
+
+    private double min;
+
+    private double range;
+
+    private Slider slider;
+
+    public Transformer(Composite parent, String text, float min, float max, double initial)
+    {
+      this.min = min;
+      range = max - min;
+
+      Label label = new Label(parent, SWT.NONE);
+      label.setText(text + ":");
+      label.setLayoutData(new GridData());
+
+      slider = new Slider(parent, SWT.HORIZONTAL);
+      slider.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+      slider.setMinimum(0);
+      slider.setMaximum(MAX);
+      setValue(initial);
+    }
+
+    public Slider getSlider()
+    {
+      return slider;
+    }
+
+    public double getValue()
+    {
+      return slider.getSelection() * range / MAX + min;
+    }
+
+    public void setValue(double value)
+    {
+      slider.setSelection((int)((value - min) * MAX / range));
+    }
+  }
+}
diff --git a/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeView.java b/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeView.java
index 59e9801..ef5f78c 100644
--- a/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeView.java
+++ b/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeView.java
@@ -155,16 +155,21 @@
     }
     catch (Exception ex)
     {
-      ex.printStackTrace();
+      System.err.println(ex.getMessage());
     }
   }
 
   @Override
   public void dispose()
   {
-    smartphoneNavigator.interrupt();
+    if (smartphoneNavigator != null)
+    {
+      smartphoneNavigator.interrupt();
+    }
+
     DescriptorView.INSTANCE.removeListener(descriptorViewListener);
     Frontend.INSTANCE.removeListener(new FrontendListener());
+
     world.dispose();
     super.dispose();
   }
diff --git a/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeWorld.java b/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeWorld.java
index d3b682b..8b6d805 100644
--- a/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeWorld.java
+++ b/org.eclipse.emf.cdo.threedee.ui/src/org/eclipse/emf/cdo/threedee/ui/ThreeDeeWorld.java
@@ -374,6 +374,11 @@
     return composite;

   }

 

+  public InfoPanel getInfoPanel()

+  {

+    return infoPanel;

+  }

+

   public void addElement(Element element)

   {

     if (!elementGroups.containsKey(element))

@@ -820,7 +825,7 @@
   /**

    * @author Eike Stepper

    */

-  private final class InfoPanel extends PlatformGeometry implements Runnable

+  public final class InfoPanel extends PlatformGeometry implements Runnable

   {

     private FontExtrusion EXTRUSION = new FontExtrusion();

 

@@ -828,7 +833,9 @@
 

     private Font3D boldFont = new Font3D(new Font("Arial", Font.BOLD, 1), EXTRUSION);

 

-    private TransformGroup transformGroup;

+    private TransformGroup translationGroup;

+

+    private TransformGroup scaleGroup;

 

     private Thread animator = new Thread(this);

 

@@ -839,7 +846,9 @@
       Transform3D translation = new Transform3D();

       translation.setTranslation(new Vector3f(-0.4f, 0.24f, -1f));

 

-      TransformGroup translationGroup = new TransformGroup(translation);

+      translationGroup = new TransformGroup(translation);

+      translationGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

+      translationGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

       addChild(translationGroup);

 

       // DirectionalLight light = new DirectionalLight();

@@ -850,15 +859,27 @@
       Transform3D scale = new Transform3D();

       scale.setScale(0.015d);

 

-      transformGroup = new TransformGroup(scale);

-      transformGroup.setCapability(ALLOW_CHILDREN_WRITE);

-      transformGroup.setCapability(ALLOW_CHILDREN_EXTEND);

-      translationGroup.addChild(transformGroup);

+      scaleGroup = new TransformGroup(scale);

+      scaleGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

+      scaleGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

+      scaleGroup.setCapability(ALLOW_CHILDREN_WRITE);

+      scaleGroup.setCapability(ALLOW_CHILDREN_EXTEND);

+      translationGroup.addChild(scaleGroup);

 

       // animator.setDaemon(true);

       // animator.start();

     }

 

+    public TransformGroup getTranslationGroup()

+    {

+      return translationGroup;

+    }

+

+    public TransformGroup getScaleGroup()

+    {

+      return scaleGroup;

+    }

+

     public synchronized void updateInfo(Object[] objects)

     {

       for (Info info : infos)

@@ -869,7 +890,7 @@
       infos = createInfos(objects);

       for (Info info : infos)

       {

-        transformGroup.addChild(info);

+        scaleGroup.addChild(info);

       }

     }