diff --git a/rosjava_benchmarks/src/main/java/org/ros/rosjava_benchmarks/TransformBenchmark.java b/rosjava_benchmarks/src/main/java/org/ros/rosjava_benchmarks/TransformBenchmark.java
index 3867329ae842722e4caff3a11c756911b9fe113e..b44eb4199d5494657c2bf662b760dd6ac91e895c 100644
--- a/rosjava_benchmarks/src/main/java/org/ros/rosjava_benchmarks/TransformBenchmark.java
+++ b/rosjava_benchmarks/src/main/java/org/ros/rosjava_benchmarks/TransformBenchmark.java
@@ -59,7 +59,7 @@ public class TransformBenchmark extends AbstractNodeMain {
         connectedNode.getTopicMessageFactory().newFromType(geometry_msgs.TransformStamped._TYPE);
     turtle2.getHeader().setFrameId("world");
     turtle2.setChildFrameId("turtle2");
-    final FrameTransformTree frameTransformTree = new FrameTransformTree(NameResolver.newRoot());
+    final FrameTransformTree frameTransformTree = new FrameTransformTree();
     connectedNode.executeCancellableLoop(new CancellableLoop() {
       @Override
       protected void loop() throws InterruptedException {
diff --git a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameName.java b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameName.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e7efc3a8a671a2cda13fac33f569bcd002da01d
--- /dev/null
+++ b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameName.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.ros.rosjava_geometry;
+
+import java.lang.String;
+
+/**
+ * Provides a simple wrapper around strings to represent
+ * frame names with backwards compatibility (pre ros hydro)
+ * catered for by ignoring graph name style leading slashes.
+ *
+ * @author d.stonier@gmail.com (Daniel Stonier)
+ */
+public class FrameName {
+    private static final String LEGACY_SEPARATOR = "/";
+    private String name;
+
+    public static FrameName of(String name) {
+        return new FrameName(name);
+    }
+
+    private FrameName(String name) {
+        this.name = stripLeadingSlash(name);
+    }
+
+    /**
+     * TF2 names (from hydro on) do not make use of leading slashes.
+     */
+    private static String stripLeadingSlash(String name) {
+        return name.replaceFirst("^/", "");
+    }
+
+    public String toString() {
+        return name;
+    }
+
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        FrameName other = (FrameName) obj;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransform.java b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransform.java
index be9616185adfbec71c91d9c9cd9a71a3da2e7162..da578513347cc616b916ca65f0cb7491c9f33c9d 100644
--- a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransform.java
+++ b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransform.java
@@ -19,19 +19,18 @@ package org.ros.rosjava_geometry;
 import com.google.common.base.Preconditions;
 
 import org.ros.message.Time;
-import org.ros.namespace.GraphName;
 
 /**
  * Describes a {@link Transform} from data in the source frame to data in the
  * target frame at a specified {@link Time}.
- * 
+ *
  * @author damonkohler@google.com (Damon Kohler)
  */
 public class FrameTransform {
 
   private final Transform transform;
-  private final GraphName source;
-  private final GraphName target;
+  private final FrameName source;
+  private final FrameName target;
   private final Time time;
 
   public static FrameTransform fromTransformStampedMessage(
@@ -40,12 +39,12 @@ public class FrameTransform {
     String target = transformStamped.getHeader().getFrameId();
     String source = transformStamped.getChildFrameId();
     Time stamp = transformStamped.getHeader().getStamp();
-    return new FrameTransform(transform, GraphName.of(source), GraphName.of(target), stamp);
+    return new FrameTransform(transform, FrameName.of(source), FrameName.of(target), stamp);
   }
 
   /**
    * Allocates a new {@link FrameTransform}.
-   * 
+   *
    * @param transform
    *          the {@link Transform} that transforms data in the {@code source}
    *          frame to data in the {@code target} frame
@@ -57,7 +56,7 @@ public class FrameTransform {
    *          the time associated with this {@link FrameTransform}, can be
    *          {@null}
    */
-  public FrameTransform(Transform transform, GraphName source, GraphName target, Time time) {
+  public FrameTransform(Transform transform, FrameName source, FrameName target, Time time) {
     Preconditions.checkNotNull(transform);
     Preconditions.checkNotNull(source);
     Preconditions.checkNotNull(target);
@@ -71,11 +70,11 @@ public class FrameTransform {
     return transform;
   }
 
-  public GraphName getSourceFrame() {
+  public FrameName getSourceFrame() {
     return source;
   }
 
-  public GraphName getTargetFrame() {
+  public FrameName getTargetFrame() {
     return target;
   }
 
diff --git a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransformTree.java b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransformTree.java
index 4f25095906d00e966be70292cf36f0e298d2f98f..7ce4eca55e5b22e517565198f414b6af08024985 100644
--- a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransformTree.java
+++ b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/FrameTransformTree.java
@@ -23,9 +23,6 @@ import com.google.common.collect.Maps;
 import geometry_msgs.TransformStamped;
 import org.ros.concurrent.CircularBlockingDeque;
 import org.ros.message.Time;
-import org.ros.namespace.GraphName;
-import org.ros.namespace.NameResolver;
-
 import java.util.Map;
 
 /**
@@ -33,7 +30,7 @@ import java.util.Map;
  * <p>
  * {@link FrameTransformTree} does not currently support time travel. Lookups
  * always use the newest {@link TransformStamped}.
- * 
+ *
  * @author damonkohler@google.com (Damon Kohler)
  * @author moesenle@google.com (Lorenz Moesenlechner)
  */
@@ -41,7 +38,6 @@ public class FrameTransformTree {
 
   private static final int TRANSFORM_QUEUE_CAPACITY = 16;
 
-  private final NameResolver nameResolver;
   private final Object mutex;
 
   /**
@@ -49,11 +45,9 @@ public class FrameTransformTree {
    * frame. Lookups by target frame or by the pair of source and target are both
    * unnecessary because every frame can only have exactly one target.
    */
-  private final Map<GraphName, CircularBlockingDeque<LazyFrameTransform>> transforms;
+  private final Map<FrameName, CircularBlockingDeque<LazyFrameTransform>> transforms;
 
-  public FrameTransformTree(NameResolver nameResolver) {
-    Preconditions.checkNotNull(nameResolver);
-    this.nameResolver = nameResolver;
+  public FrameTransformTree() {
     mutex = new Object();
     transforms = Maps.newConcurrentMap();
   }
@@ -65,51 +59,50 @@ public class FrameTransformTree {
    * Note that the tree is updated lazily. Modifications to the provided
    * {@link geometry_msgs.TransformStamped} message may cause unpredictable
    * results.
-   * 
+   *
    * @param transformStamped
    *          the {@link geometry_msgs.TransformStamped} message to update with
    */
   public void update(geometry_msgs.TransformStamped transformStamped) {
     Preconditions.checkNotNull(transformStamped);
-    GraphName resolvedSource = nameResolver.resolve(transformStamped.getChildFrameId());
+    FrameName transformName = FrameName.of(transformStamped.getChildFrameId());
     LazyFrameTransform lazyFrameTransform = new LazyFrameTransform(transformStamped);
-    add(resolvedSource, lazyFrameTransform);
+    add(transformName, lazyFrameTransform);
   }
 
   @VisibleForTesting
   void update(FrameTransform frameTransform) {
     Preconditions.checkNotNull(frameTransform);
-    GraphName resolvedSource = frameTransform.getSourceFrame();
+    FrameName source = frameTransform.getSourceFrame();
     LazyFrameTransform lazyFrameTransform = new LazyFrameTransform(frameTransform);
-    add(resolvedSource, lazyFrameTransform);
+    add(source, lazyFrameTransform);
   }
 
-  private void add(GraphName resolvedSource, LazyFrameTransform lazyFrameTransform) {
-    if (!transforms.containsKey(resolvedSource)) {
-      transforms.put(resolvedSource, new CircularBlockingDeque<LazyFrameTransform>(
+  private void add(FrameName source, LazyFrameTransform lazyFrameTransform) {
+    if (!transforms.containsKey(source)) {
+      transforms.put(source, new CircularBlockingDeque<LazyFrameTransform>(
           TRANSFORM_QUEUE_CAPACITY));
     }
     synchronized (mutex) {
-      transforms.get(resolvedSource).addFirst(lazyFrameTransform);
+      transforms.get(source).addFirst(lazyFrameTransform);
     }
   }
 
   /**
    * Returns the most recent {@link FrameTransform} for target {@code source}.
-   * 
+   *
    * @param source
    *          the frame to look up
    * @return the most recent {@link FrameTransform} for {@code source} or
    *         {@code null} if no transform for {@code source} is available
    */
-  public FrameTransform lookUp(GraphName source) {
+  public FrameTransform lookUp(FrameName source) {
     Preconditions.checkNotNull(source);
-    GraphName resolvedSource = nameResolver.resolve(source);
-    return getLatest(resolvedSource);
+    return getLatest(source);
   }
 
-  private FrameTransform getLatest(GraphName resolvedSource) {
-    CircularBlockingDeque<LazyFrameTransform> deque = transforms.get(resolvedSource);
+  private FrameTransform getLatest(FrameName source) {
+    CircularBlockingDeque<LazyFrameTransform> deque = transforms.get(source);
     if (deque == null) {
       return null;
     }
@@ -121,17 +114,17 @@ public class FrameTransformTree {
   }
 
   /**
-   * @see #lookUp(GraphName)
+   * @see #lookUp(FrameName)
    */
   public FrameTransform get(String source) {
     Preconditions.checkNotNull(source);
-    return lookUp(GraphName.of(source));
+    return lookUp(FrameName.of(source));
   }
 
   /**
    * Returns the {@link FrameTransform} for {@code source} closest to
    * {@code time}.
-   * 
+   *
    * @param source
    *          the frame to look up
    * @param time
@@ -140,16 +133,15 @@ public class FrameTransformTree {
    * @return the most recent {@link FrameTransform} for {@code source} or
    *         {@code null} if no transform for {@code source} is available
    */
-  public FrameTransform lookUp(GraphName source, Time time) {
+  public FrameTransform lookUp(FrameName source, Time time) {
     Preconditions.checkNotNull(source);
     Preconditions.checkNotNull(time);
-    GraphName resolvedSource = nameResolver.resolve(source);
-    return get(resolvedSource, time);
+    return get(source, time);
   }
 
   // TODO(damonkohler): Use an efficient search.
-  private FrameTransform get(GraphName resolvedSource, Time time) {
-    CircularBlockingDeque<LazyFrameTransform> deque = transforms.get(resolvedSource);
+  private FrameTransform get(FrameName source, Time time) {
+    CircularBlockingDeque<LazyFrameTransform> deque = transforms.get(source);
     if (deque == null) {
       return null;
     }
@@ -176,32 +168,30 @@ public class FrameTransformTree {
   }
 
   /**
-   * @see #lookUp(GraphName, Time)
+   * @see #lookUp(FrameName, Time)
    */
   public FrameTransform get(String source, Time time) {
     Preconditions.checkNotNull(source);
-    return lookUp(GraphName.of(source), time);
+    return lookUp(FrameName.of(source), time);
   }
 
   /**
    * @return the {@link FrameTransform} from source the frame to the target
    *         frame, or {@code null} if no {@link FrameTransform} could be found
    */
-  public FrameTransform transform(GraphName source, GraphName target) {
+  public FrameTransform transform(FrameName source, FrameName target) {
     Preconditions.checkNotNull(source);
     Preconditions.checkNotNull(target);
-    GraphName resolvedSource = nameResolver.resolve(source);
-    GraphName resolvedTarget = nameResolver.resolve(target);
-    if (resolvedSource.equals(resolvedTarget)) {
-      return new FrameTransform(Transform.identity(), resolvedSource, resolvedTarget, null);
+    if (source.equals(target)) {
+      return new FrameTransform(Transform.identity(), source, target, null);
     }
-    FrameTransform sourceToRoot = transformToRoot(resolvedSource);
-    FrameTransform targetToRoot = transformToRoot(resolvedTarget);
+    FrameTransform sourceToRoot = transformToRoot(source);
+    FrameTransform targetToRoot = transformToRoot(target);
     if (sourceToRoot == null && targetToRoot == null) {
       return null;
     }
     if (sourceToRoot == null) {
-      if (targetToRoot.getTargetFrame().equals(resolvedSource)) {
+      if (targetToRoot.getTargetFrame().equals(source)) {
         // resolvedSource is root.
         return targetToRoot.invert();
       } else {
@@ -209,7 +199,7 @@ public class FrameTransformTree {
       }
     }
     if (targetToRoot == null) {
-      if (sourceToRoot.getTargetFrame().equals(resolvedTarget)) {
+      if (sourceToRoot.getTargetFrame().equals(target)) {
         // resolvedTarget is root.
         return sourceToRoot;
       } else {
@@ -221,29 +211,29 @@ public class FrameTransformTree {
       // same root.
       Transform transform =
           targetToRoot.getTransform().invert().multiply(sourceToRoot.getTransform());
-      return new FrameTransform(transform, resolvedSource, resolvedTarget, sourceToRoot.getTime());
+      return new FrameTransform(transform, source, target, sourceToRoot.getTime());
     }
     // No known transform.
     return null;
   }
 
   /**
-   * @see #transform(GraphName, GraphName)
+   * @see #transform(FrameName, FrameName)
    */
   public FrameTransform transform(String source, String target) {
     Preconditions.checkNotNull(source);
     Preconditions.checkNotNull(target);
-    return transform(GraphName.of(source), GraphName.of(target));
+    return transform(FrameName.of(source), FrameName.of(target));
   }
 
   /**
-   * @param resolvedSource
+   * @param source
    *          the resolved source frame
    * @return the {@link Transform} from {@code source} to root
    */
   @VisibleForTesting
-  FrameTransform transformToRoot(GraphName resolvedSource) {
-    FrameTransform result = getLatest(resolvedSource);
+  FrameTransform transformToRoot(FrameName source) {
+    FrameTransform result = getLatest(source);
     if (result == null) {
       return null;
     }
@@ -254,8 +244,8 @@ public class FrameTransformTree {
       }
       // Now resultToParent.getSourceFrame() == result.getTargetFrame()
       Transform transform = resultToParent.getTransform().multiply(result.getTransform());
-      GraphName resolvedTarget = resultToParent.getTargetFrame();
-      result = new FrameTransform(transform, resolvedSource, resolvedTarget, result.getTime());
+      FrameName target = resultToParent.getTargetFrame();
+      result = new FrameTransform(transform, source, target, result.getTime());
     }
   }
 }
diff --git a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/Transform.java b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/Transform.java
index 3d1727deb044c56314a59755b5243978822bdc8c..85f09154efa91c34a10ee3456de49541d9258b2f 100644
--- a/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/Transform.java
+++ b/rosjava_geometry/src/main/java/org/ros/rosjava_geometry/Transform.java
@@ -19,11 +19,10 @@ package org.ros.rosjava_geometry;
 import com.google.common.annotations.VisibleForTesting;
 
 import org.ros.message.Time;
-import org.ros.namespace.GraphName;
 
 /**
  * A transformation in terms of translation, rotation, and scale.
- * 
+ *
  * @author damonkohler@google.com (Damon Kohler)
  * @author moesenle@google.com (Lorenz Moesenlechner)
  */
@@ -73,7 +72,7 @@ public class Transform {
 
   /**
    * Apply another {@link Transform} to this {@link Transform}.
-   * 
+   *
    * @param other
    *          the {@link Transform} to apply to this {@link Transform}
    * @return the resulting {@link Transform}
@@ -133,7 +132,7 @@ public class Transform {
     return result;
   }
 
-  public geometry_msgs.PoseStamped toPoseStampedMessage(GraphName frame, Time stamp,
+  public geometry_msgs.PoseStamped toPoseStampedMessage(FrameName frame, Time stamp,
       geometry_msgs.PoseStamped result) {
     result.getHeader().setFrameId(frame.toString());
     result.getHeader().setStamp(stamp);