diff --git a/plugins/org.eclipse.objectteams.otdt/.classpath b/plugins/org.eclipse.objectteams.otdt/.classpath
index 304e861..9b7e6c5 100644
--- a/plugins/org.eclipse.objectteams.otdt/.classpath
+++ b/plugins/org.eclipse.objectteams.otdt/.classpath
@@ -2,6 +2,7 @@
 <classpath>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="OTRE"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/plugins/org.eclipse.objectteams.otdt/.project b/plugins/org.eclipse.objectteams.otdt/.project
index a40a654..7bcffe8 100644
--- a/plugins/org.eclipse.objectteams.otdt/.project
+++ b/plugins/org.eclipse.objectteams.otdt/.project
@@ -6,7 +6,7 @@
 	</projects>
 	<buildSpec>
 		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
+			<name>org.eclipse.objectteams.otdt.builder.OTJBuilder</name>
 			<arguments>
 			</arguments>
 		</buildCommand>
@@ -24,5 +24,6 @@
 	<natures>
 		<nature>org.eclipse.pde.PluginNature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.objectteams.otdt.OTJavaNature</nature>
 	</natures>
 </projectDescription>
diff --git a/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF
index 664f29d..70aeb3c 100644
--- a/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF
@@ -3,9 +3,12 @@
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt;singleton:=true
 Bundle-Version: 0.7.1.qualifier
+Bundle-ClassPath: otdtcoreext.jar
 Bundle-Activator: org.eclipse.objectteams.otdt.core.ext.OTDTPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
+Export-Package: org.eclipse.objectteams.otdt.core.ext,
+ org.eclipse.objectteams.otdt.core.hierarchy
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.core.resources,
  org.eclipse.jdt.core;bundle-version="[3.6.0.v_OTDT_r070,3.6.0.v_OTDT_r080)",
@@ -13,8 +16,7 @@
  org.eclipse.debug.core,
  org.eclipse.osgi,
  org.eclipse.objectteams.otequinox.branding,
- org.eclipse.objectteams.runtime;bundle-version="[0.7.0,0.8.0)"
-Bundle-ActivationPolicy: lazy
-Bundle-ClassPath: otdtcoreext.jar
-Export-Package: org.eclipse.objectteams.otdt.core.ext
+ org.eclipse.objectteams.runtime;bundle-version="[0.7.0,0.8.0)",
+ org.eclipse.objectteams.otequinox
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.objectteams.otdt/plugin.xml b/plugins/org.eclipse.objectteams.otdt/plugin.xml
index 84bc547..b1df675 100644
--- a/plugins/org.eclipse.objectteams.otdt/plugin.xml
+++ b/plugins/org.eclipse.objectteams.otdt/plugin.xml
@@ -50,4 +50,19 @@
 	 		id="OTRE"
             class="org.eclipse.objectteams.otdt.core.ext.OTREContainerInitializer"/>
    </extension>
+   <extension
+         point="org.eclipse.objectteams.otequinox.aspectBindings">
+      <aspectBinding
+            icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
+         <basePlugin
+               icon="platform:/plugin/org.eclipse.pde.ui/icons/obj16/plugin_obj.gif"
+               id="org.eclipse.jdt.core">
+         </basePlugin>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.core.hierarchy.OTTypeHierarchies"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+      </aspectBinding>
+   </extension>
 </plugin>
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/hierarchy/OTTypeHierarchies.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/hierarchy/OTTypeHierarchies.java
new file mode 100644
index 0000000..4de99fb
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/hierarchy/OTTypeHierarchies.java
@@ -0,0 +1,667 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2010 GK Software AG
+ * 
+ * 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
+ * $Id$
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	  Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.core.hierarchy;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.env.IGenericType;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.core.JavaModelStatus;
+import org.eclipse.objectteams.otdt.core.IOTType;
+import org.eclipse.objectteams.otdt.core.OTModelManager;
+
+// both base type and directly used:
+import org.eclipse.jdt.core.IType;
+
+import base org.eclipse.jdt.internal.core.BinaryType;
+import base org.eclipse.jdt.internal.core.SourceType;
+import base org.eclipse.jdt.internal.core.hierarchy.HierarchyBuilder;
+import base org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+import base org.eclipse.objectteams.otdt.core.PhantomType;
+import base org.eclipse.objectteams.otdt.internal.core.OTType;
+
+/**
+ * Adapt the regular Java TypeHierarchy as to handle implicit inheritance, too.
+ * 
+ * 
+ * @author stephan
+ */
+@SuppressWarnings("restriction")
+public team class OTTypeHierarchies {
+	
+	/** How does a given type relate to the focus type? */
+	enum FocusRelation {
+		/** a type is a subtype of the focus type. */
+		BELOW, 
+		/** a type is the focus type itself. */
+		EQUAL, 
+		/** a type is a supertype of the focus type. */
+		ABOVE, 
+		/** a type is neither sub- nor supertype of the focus type. */
+		UNRELATED;
+
+		public static FocusRelation compute(ReferenceBinding focusType, ReferenceBinding typeBinding) {
+			if (focusType.isRole())
+				focusType = focusType.getRealType();
+			if (typeBinding.isRole())
+				typeBinding = typeBinding.getRealType();
+			if (focusType.equals(typeBinding))				return EQUAL;
+			if (focusType.isCompatibleWith(typeBinding))	return ABOVE;
+			if (typeBinding.isCompatibleWith(focusType))	return BELOW;
+			return UNRELATED;
+		}
+	}
+	
+	private static final IType[] NO_TYPE = new IType[0];
+
+	// === singleton infrastructure: ===
+	
+	private static OTTypeHierarchies instance;
+	public OTTypeHierarchies() {
+		instance = this;
+	}
+	/** Get the singleton instance of this team, which was created and activated by OT/Equinox. */
+	public static OTTypeHierarchies getInstance() { return instance; }
+	
+	
+	/** 
+	 * The stateful part of this team, implemented as a nested team.
+	 */
+	protected team class OTTypeHierarchy playedBy TypeHierarchy 
+	{
+		// === "Imports" (callout) from plain TypeHierarchy: ===
+		
+		@SuppressWarnings("decapsulation") IType getFocusType() 	-> get IType focusType;
+		ConnectedType getSuperclass(IType type) 					-> IType getSuperclass(IType type);
+		ConnectedType[] getAllSuperclassesUnfiltered(IType type) 	-> IType[] getAllSuperclasses(IType type);
+		IType[] getSuperInterfaces(IType type) 						-> IType[] getSuperInterfaces(IType type);
+		IType[] getAllSuperInterfaces(IType type) 					-> IType[] getAllSuperInterfaces(IType type);
+		
+		
+		// === Adapt TypeHierarchy (callin bindings): ===
+
+		precedence unwrapping, filtering1, superlinearize; // order: outer callins unwrap and filter, inner callin performs computation
+		precedence filtering2, tsuperadding;
+
+		// --- considure implicit inheritance for some queries: ----
+		
+		// make getSuperclass() traverse the superclass linearization of the focus type:
+	superlinearize: 
+		ConnectedType getSuperclassLinearized(ConnectedType type) <- replace IType getSuperclass(IType type);
+		
+		// augment original queries to capture tsub-types, too:
+		@SuppressWarnings("decapsulation")
+		addTSubs <- replace getSubtypesForType; // adjust internal method as to capture calls from getAllSubtypes(IType), too.
+	tsuperadding:
+		addTSubs <- replace getSubclasses;
+
+		// --- filtering (duplicates and phantoms) and unwrapping (OTTypes): ---
+		
+		// make some methods aware of our phantom mode:
+	filtering1: 
+		ConnectedType[] phantomFilterWrapper() 
+		<- replace 
+			IType[] getAllClasses(), 
+			IType[] getImplementingClasses(IType type), 
+			IType[] getAllSuperclasses(IType type) 
+					when (!this.phantomMode);
+		
+		// filter intermediate results only at these top-level queries:
+	filtering2: 	
+		filterDuplicatesAndPhantoms <- replace getSubclasses, getSubtypes, getAllSubtypes, getImplementingClasses; // includes unwrapping of OTTypes
+		
+		// all top-level queries unwrap and given OTTypes:
+	unwrapping:
+		ensureJavaType <- replace getAllSuperclasses, getAllSuperInterfaces, getAllSupertypes,
+							      getCachedFlags, getExtendingInterfaces, 
+								  getSuperclass, getSuperInterfaces, getSupertypes;
+
+		/**
+		 * This role adds to ITypes the capability of connecting to all direct and indirect tsuper types,
+		 * which includes linearization of all super types (implicit & explicit). 
+		 */
+		@SuppressWarnings("abstractrelevantrole")
+		protected abstract class ConnectedType  playedBy IType 
+		{
+			/** Is this type a phantom role? */
+			protected boolean isPhantom;
+
+			/** The direct tsuper types of this type. */
+			protected ConnectedType[] directTSupers;
+
+			/** All direct & indirect tsuper classes in a linearized form. All classes in this list have the same simple name. */
+			protected List<ConnectedType> allTSupersLinearized;
+
+			/** This type's relation to the focus type. */
+			private FocusRelation focusRelation;
+			
+			// the last item in allTSupersLinearized, used as a token for switching from implicit to explicit supers
+			private ConnectedType lastTSuper = null;
+			
+			/** the root of the tsuper chain through which this connected type was reached. */
+			protected ConnectedType tsuperChainRoot;
+			
+			/** All known direct tsub types of this type. */
+			protected Set<ConnectedType> knownTSubTypes;
+
+					
+			protected ConnectedType(IType type) {
+				this.tsuperChainRoot = this;
+			}
+
+			public void init(boolean isPhantom, ConnectedType[] tsuperclassHandles, FocusRelation focusRelation) {
+				this.isPhantom = isPhantom;
+				this.directTSupers = tsuperclassHandles;
+				this.focusRelation = focusRelation;			
+			}
+			
+			/** Combine indirect tsuper classes into the list of all linearized tsuper types. */
+			@SuppressWarnings("ambiguouslowering") // method contains takes an Object argument
+			public void combineTSupers(ConnectedType focusLayerType, ConnectedType[] tsuperclassHandles) {
+				this.tsuperChainRoot = focusLayerType.tsuperChainRoot;
+				if (this.allTSupersLinearized == null)
+					this.allTSupersLinearized = new LinkedList<ConnectedType>();
+				for (ConnectedType type : tsuperclassHandles)
+					if (!this.allTSupersLinearized.contains(type))
+						this.allTSupersLinearized.add(type);
+			}
+
+			/** Get the next type in the tsuper linearization. */
+			protected ConnectedType getTSuperType() {
+				if (this.focusRelation == FocusRelation.BELOW) {
+					// only follow the path towards the focus type:
+					if (this.directTSupers != null)
+						for (ConnectedType directTSuper : this.directTSupers)
+							if (directTSuper.focusRelation == FocusRelation.EQUAL || directTSuper.focusRelation == FocusRelation.BELOW)
+								return directTSuper;
+					return null; // no tsuper leading to focus
+				}
+				// shortcut if no tsupers:
+				if (this.allTSupersLinearized == null || this.allTSupersLinearized.size() == 0)
+					return null;
+				// when starting from the focus layer return the first tsuper role:
+				if (isInFocusLayer(this))
+					return this.allTSupersLinearized.get(0);
+				// when type is contained in the list of tsuperRoles return the next tsuper role from the list
+				for (int i = 0; i < this.allTSupersLinearized.size()-1; i++)
+					if (this.allTSupersLinearized.get(i) == this)
+						return this.allTSupersLinearized.get(i+1);
+				return null; // end reached
+			}
+			
+			/** Is this the last element in the list of tsuper roles? */
+			protected boolean isLastTSuper() {
+				if (this.allTSupersLinearized == null || this.allTSupersLinearized.size() == 0) // optimize: don's store empty list?
+					return false;
+				if (this.lastTSuper == null)
+					this.lastTSuper = this.allTSupersLinearized.get(this.allTSupersLinearized.size()-1);
+				return this.lastTSuper == this;
+			}
+			
+			/** If this is a phantom type, get the real tsuper class that this is derived (copied) from. */
+			protected ConnectedType getRealTSuper() throws JavaModelException {
+				if (!isPhantom)
+					return this;
+				if (this.allTSupersLinearized != null)
+					for(ConnectedType other : this.allTSupersLinearized)
+						if (!other.isPhantom)
+							return other;
+				throw new JavaModelException(new JavaModelStatus(JavaModelStatus.ERROR, this, "no non-phantom type found in allTSupersLinearized")); //$NON-NLS-1$
+			}
+			
+			/** Get all tsuper types yet respecting phantom mode. */
+			protected ConnectedType[] getAllTSuperTypes() 
+			{
+				if (this.focusRelation == FocusRelation.BELOW && this.directTSupers != null) {
+					// special handling for types below the focus: transitively collect tsupers:
+					ConnectedType direct = getTSuperType(); // only the one path towards focus
+					if (direct == null) 
+						return new ConnectedType[0];
+					ConnectedType[] indirect = direct.getAllTSuperTypes(); // NB: recursion may enter the focus cone
+					if (indirect == null) 
+						return new ConnectedType[] {direct};
+					// merge direct and indirect:
+					int len = indirect.length;
+					ConnectedType[] result = new ConnectedType[len+1];
+					result[0] = direct;
+					System.arraycopy(indirect, 0, result, 1, len);
+					return result;
+				}
+
+				int size;
+				if (this.allTSupersLinearized != null && (size = this.allTSupersLinearized.size()) > 0) 
+				{
+					// focus level => all types from the linearization:
+					if (isInFocusLayer(this))
+						return this.allTSupersLinearized.toArray(new ConnectedType[size]);
+					
+					// not focus, search in linearization for this type ...
+					int skip = 0;
+					boolean found = false;
+					while (skip < size)
+						if (this.allTSupersLinearized.get(skip++) == this) {
+							found = true;
+							break;
+						}
+					if (found) { // .. and take the tail after this type: 
+						if (skip < size) { // if found at last pos, there's no tail
+							ConnectedType[] result = new ConnectedType[size-skip];
+							for (int i=0; skip<size;)
+								result[i++] = this.allTSupersLinearized.get(skip++);
+							return result;
+						}
+					} else {
+						System.out.println("HERE "+this);
+						// not focus type but seemingly bottom of the lattice, take all known tsupers
+						return this.allTSupersLinearized.toArray(new ConnectedType[size]);
+					}
+				}
+				return new ConnectedType[0];
+			}
+			
+			/** Register a known tsub type of this type. */
+			protected void addTSubType(ConnectedType tsub) {
+				if (this.knownTSubTypes == null)
+					this.knownTSubTypes = new HashSet<ConnectedType>();
+				this.knownTSubTypes.add(tsub);
+			}
+		
+			toString => toString; // for debugging
+
+		}
+		// binding source variant of IType
+		protected class ConnectedSourceType extends ConnectedType playedBy SourceType { /*just class binding, no details*/ }
+		
+		// binding binary variant of IType
+		protected class ConnectedBinaryType extends ConnectedType playedBy BinaryType { /*just class binding, no details*/ }
+		
+		// binding binary variant of IType
+		protected class ConnectedPhantomType extends ConnectedType playedBy PhantomType { /*just class binding, no details*/ }
+
+		// binding binary variant of IType
+		protected class ConnectedOTType extends ConnectedType playedBy OTType { /*just class binding, no details*/ }
+
+		// === start main part of nested team OTTypeHierarchy ===
+		
+		/** Should the hierarchy show phantom roles? */
+		protected boolean phantomMode;
+
+		/**
+		 * Connect the found tsuper classes into the connected type for the given type. 
+		 */
+		protected void connectTSupers(IType as ConnectedType connectedType, 
+									  boolean isPhantom, 
+									  IType as ConnectedType tsuperclassHandles[], 
+									  boolean[] arePhantoms,
+									  FocusRelation focusRelation) 
+		{
+			connectedType.init(isPhantom, tsuperclassHandles, focusRelation);
+			
+			// connect tsuperclassHandles into the appropriate ConnectedType:
+			switch (focusRelation) {
+			case EQUAL:
+				connectedType.allTSupersLinearized = new LinkedList<ConnectedType>();
+				for (int i = 0; i < tsuperclassHandles.length; i++)
+					connectedType.allTSupersLinearized.add(tsuperclassHandles[i]);
+				break;
+			case ABOVE:
+				ConnectedType focusLayerType = connectedType.tsuperChainRoot;
+				focusLayerType.combineTSupers(focusLayerType, tsuperclassHandles);
+				connectedType.allTSupersLinearized = focusLayerType.allTSupersLinearized; // share the same list
+				break;
+			case BELOW:
+				// don't merge into focus' up-chain
+				break;
+			default: // UNRELATED
+//				if (isInFocusLayer(connectedType)) {
+//					connectedType.allTSupersLinearized = new LinkedList<ConnectedType>();
+//					for (int i = 0; i < tsuperclassHandles.length; i++)
+//						connectedType.allTSupersLinearized.add(tsuperclassHandles[i]);
+//				}
+				// otherwise shouldn't be relevant?
+			}
+			// connect each in tsuperclassHandles back to the tsuperChainRoot:
+			for (int i = 0; i < tsuperclassHandles.length; i++) {
+				if (focusRelation == FocusRelation.EQUAL || focusRelation == FocusRelation.ABOVE)
+					tsuperclassHandles[i].tsuperChainRoot = connectedType.tsuperChainRoot;
+				tsuperclassHandles[i].isPhantom = arePhantoms[i];
+				// and remember the type-tsub link:
+				tsuperclassHandles[i].addTSubType(connectedType);
+			}
+		}
+
+		boolean isInFocusLayer(IType type) {
+			IType focusType = getFocusType();
+			if (type.equals(focusType))
+				return true;
+			return focusType.getParent().equals(type.getParent()); // FIXME(SH) elaborate more
+		}
+		
+		boolean isStrictlyBelowFocusType(IType type) {
+			IType focusType = getFocusType();
+			if (focusType.equals(type))
+				return false;
+			return isBelowFocusType(focusType, type);
+		}
+
+		private boolean isBelowFocusType(IType focusType, IType type) {
+			if (focusType.equals(type))
+				return true;
+			return false;
+		}
+
+		/** Given that 'type' is element of a superclass linearization return the next super in the chain. */
+		@SuppressWarnings("basecall")
+		callin ConnectedType getSuperclassLinearized(ConnectedType type) {
+			// check for tsuper type in the computed list:
+			ConnectedType tsuperType = type.getTSuperType();
+			if (tsuperType != null)
+				return tsuperType;
+			// if type is the last in the list ... 
+			if (type.isLastTSuper()) {
+				// ...we're done with tsupers, start over with super of the focus level type:
+				return base.getSuperclassLinearized(type.tsuperChainRoot);
+			}
+			return base.getSuperclassLinearized(type);
+		}
+
+		// ==== handling for phantom mode: ====
+		
+		ConnectedType[] maybeSubstitutePhantoms(ConnectedType[] roles) throws JavaModelException {
+			if (this.phantomMode)
+				return roles;
+			ConnectedType[] substituted = new ConnectedType[roles.length];
+			for (int i = 0; i < roles.length; i++)
+				substituted[i] = roles[i].getRealTSuper();
+			return substituted;
+		}
+
+		protected ConnectedType[] filterPhantomRoles(ConnectedType[] roles) {
+			ConnectedType[] substituted = new ConnectedType[roles.length];
+			int n = 0;
+			for (int i = 0; i < roles.length; i++)
+				if (!roles[i].isPhantom)
+					substituted[n++] = roles[i];
+			if (n<roles.length)
+				System.arraycopy(substituted, 0, substituted=new ConnectedType[n], 0, n);
+			return substituted;
+		}
+
+		// wrappers for use in multiple callin bindings
+		callin ConnectedType[] phantomFilterWrapper() {
+			return filterPhantomRoles(base.phantomFilterWrapper());
+		}
+		
+		callin ConnectedType[] filterDuplicatesAndPhantoms(IType type) {
+			if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+			return filterDupsAndPhants(base.filterDuplicatesAndPhantoms(type));
+		}
+
+		protected ConnectedType[] filterDupsAndPhants(ConnectedType[] unfiltered) {
+			if (unfiltered == null)
+				return unfiltered;
+			Set<ConnectedType> filtered = new HashSet<ConnectedType>();
+			for(ConnectedType type : unfiltered)
+				if (this.phantomMode || !type.isPhantom)
+					filtered.add(type);
+			return filtered.toArray(new ConnectedType[filtered.size()]);
+		}
+
+		callin void ensureJavaType(IType type) {
+			if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+			base.ensureJavaType(type);
+		}
+		
+		// ==== adjusting some subtype queries for tsubs:
+		
+		callin ConnectedType[] addTSubs(ConnectedType type) {
+			ConnectedType[] res1 = base.addTSubs(type);
+			Set<ConnectedType> tsubs = type.knownTSubTypes;
+			
+			if (tsubs == null || tsubs.size() == 0)
+				return this.phantomMode ? res1 : filterDupsAndPhants(res1);
+		
+			Set<ConnectedType> result = new HashSet<ConnectedType>();
+			result.addAll(tsubs);
+			for (ConnectedType t1 : res1)
+				result.add(t1);
+			return result.toArray(new ConnectedType[result.size()]);
+		}
+		
+	
+		// ==== queries for clients (wrapped by methods of enclosing team, see there for documentation): ====
+		
+		protected IType[] getAllTSuperTypes(IType as ConnectedType type) {
+			ConnectedType[] result = type.getAllTSuperTypes();
+			return this.phantomMode ? result : filterPhantomRoles(result);  
+				// FIXME(SH) return without intermediate local var -> CCE
+				// like: return type.getAllTSuperTypes();
+		}
+
+		protected IType[] getDirectTSupers(IType as ConnectedType type) throws JavaModelException {
+			if (type.directTSupers == null)
+				return NO_TYPE;
+			return maybeSubstitutePhantoms(type.directTSupers);
+		}
+		
+		protected IType getPlainSuperclass(IType type) throws JavaModelException {
+			try {
+				OTTypeHierarchies.this.deactivate();
+				ConnectedType result = getSuperclass(type);
+				if (this.phantomMode || result == null)
+					return result;
+				return result.getRealTSuper();
+			} finally {
+				OTTypeHierarchies.this.activate();
+			}
+		}
+		
+		// sole purpose of this wrapper: array-lowering
+		protected IType[] getAllSuperclasses(IType type) {
+			return getAllSuperclassesUnfiltered(type);
+		}
+	}
+	
+	/**
+	 * This role adapts the HierarchyBuilder in order to record information about implicit inheritance, too. 
+	 */
+	protected class OTHierarchyBuilder playedBy HierarchyBuilder {
+
+		@SuppressWarnings("decapsulation")
+		OTTypeHierarchy getHierarchy() -> get TypeHierarchy hierarchy;
+
+		connectTSupers  <- before hookableConnect;
+
+		private void connectTSupers(ReferenceBinding focusType, ReferenceBinding typeBinding, IGenericType type, IType typeHandle, boolean isPhantom, 
+									IType superclassHandle, IType[] tsuperclassHandles, boolean[] arePhantoms, IType[] superinterfaceHandles) 
+		{
+			if (tsuperclassHandles!= null) {
+				FocusRelation focusRelation = FocusRelation.compute(focusType, typeBinding);
+				getHierarchy().connectTSupers(typeHandle, isPhantom, tsuperclassHandles, arePhantoms, focusRelation);
+			}
+		}
+	}
+
+	/**
+	 * API: Query all direct and indirect implicit superclasses of the given type.
+	 * If phantomMode is set to <code>false</code> any phantom roles will be filtered from the result.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super types are queried
+	 * @return a non-null array of ordered implicit super classes
+	 * @throws JavaModelException If the tsuper linearization is corrupt
+	 */
+	public IType[] getAllTSuperTypes(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		return otHierarchy.getAllTSuperTypes(type);
+	}
+	
+	/**
+	 * API: Query all direct implicit superclasses of the given type.
+	 * If phantomMode is set to <code>false</code> any phantom roles will be translated to its real origin.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super types are queried
+	 * @return a non-null array of ordered implicit super classes
+	 * @throws JavaModelException If the tsuper linearization is corrupt
+	 */
+	public IType[] getTSuperTypes(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		return otHierarchy.getDirectTSupers(type);
+	}
+	
+	/**
+	 * API: Query all direct, implicit and explicit superclasses of the given type.
+	 * If phantomMode is set to <code>false</code> any phantom roles will be substituted with their real origin.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super types are queried
+	 * @return a non-null array of ordered super classes.
+	 * @throws JavaModelException If the tsuper linearization is corrupt
+	 */
+	public IType[] getSuperclasses(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		// have superclass (otherwise type == java.lang.Object?)
+		IType superclass = otHierarchy.getPlainSuperclass(type);
+		if (superclass == null)
+			return NO_TYPE;
+		
+		// check direct tsupers:
+		IType[] directTSupers = getTSuperTypes(otHierarchy, type);
+		if (directTSupers == null)
+			return new IType[] { superclass };
+		
+		// found both => merge
+		int count = directTSupers.length;
+		IType[] merged = new IType[count+1];
+		System.arraycopy(directTSupers, 0, merged, 0, count);
+		merged[count] = superclass;
+		return merged;
+	}
+	
+	/**
+	 * API: Query all direct and indirect, implicit and explicit superclasses of the given type.
+	 * If phantomMode is set to <code>false</code> any phantom roles will be filtered from the result.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super types are queried
+	 * @return a non-null array of ordered super classes.
+	 * @throws JavaModelException if accessing type failed
+	 */
+	public IType[] getAllSuperclasses(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (type.isInterface())
+			return NO_TYPE;
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		return otHierarchy.getAllSuperclasses(type);
+	}
+	
+	/**
+	 * API: Query the explicit superclass of the given type.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super type is queried
+	 * @return the superclass
+	 * @throws JavaModelException If the tsuper linearization is corrupt
+	 */
+	public IType getExplicitSuperclass(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		// have superclass (otherwise type == java.lang.Object?)
+		return otHierarchy.getPlainSuperclass(type);
+	}
+
+	/** Get ALL super types: classes and interfaces, explicit and implicit, direct and indirect. */
+	public IType[] getAllSupertypes(TypeHierarchy  as OTTypeHierarchy otHierarchy, IType type) {
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		IType[] superclasses = otHierarchy.getAllSuperclasses(type);
+		IType[] superinterfaces = otHierarchy.getAllSuperInterfaces(type);
+		int l1 = superclasses.length, l2 = superinterfaces.length;
+		IType[] result = new IType[l1+l2];
+		System.arraycopy(superclasses, 0, result, 0, l1);
+		System.arraycopy(superinterfaces, 0, result, l1, l2);
+		return result;
+	}
+
+	/**
+	 * API: Query the superinterfaces of the given type, plus if it's a role interface the tsuper interfaces.
+	 * tsuper's direct superinterfaces are also counted as direct interfaces.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super types are queried
+	 * @return the superinterfaces
+	 * @throws JavaModelException If the tsuper linearization is corrupt
+	 */
+	public IType[] getSuperInterfaces(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		IType[] superinterfaces = otHierarchy.getSuperInterfaces(type);
+		if (!OTModelManager.isRole(type))
+			return superinterfaces;
+		Set<IType> all = new HashSet<IType>();
+		for (IType iType : superinterfaces)
+			all.add(iType);
+		for (IType tsuperinterface : otHierarchy.getDirectTSupers(type)) {
+			if (type.isInterface()) // otherwise just traverse tsuper to find more super interfaces
+				all.add(tsuperinterface);
+			for (IType tsupersuper : otHierarchy.getSuperInterfaces(tsuperinterface))
+				all.add(tsupersuper);
+		}
+		return all.toArray(new IType[all.size()]);
+	}
+
+	/**
+	 * API: Query the superinterfaces of the given type: explicit & implicit, direct & indirect.
+	 * 
+	 * @param otHierarchy a hierarchy that has been focused on the given type
+	 * @param type        the focus type whose super types are queried
+	 * @return the superinterfaces
+	 * @throws JavaModelException If the tsuper linearization is corrupt
+	 */
+	public IType[] getAllSuperInterfaces(TypeHierarchy as OTTypeHierarchy otHierarchy, IType type) throws JavaModelException {
+		if (!OTModelManager.isRole(type))
+			return otHierarchy.getAllSuperInterfaces(type);
+		if (type instanceof IOTType) type = (IType) ((IOTType)type).getCorrespondingJavaElement();
+		Set<IType> all = new HashSet<IType>();
+		getAllSuperInterfaces2(otHierarchy, type, all);
+		return all.toArray(new IType[all.size()]);
+	}
+	// recursive helper for above
+	private void getAllSuperInterfaces2(OTTypeHierarchy otHierarchy, IType seed, Set<IType> collected) throws JavaModelException {
+		for (IType tsuperinterface : otHierarchy.getAllTSuperTypes(seed)) {
+			if (seed.isInterface()) { // otherwise just traverse tsuper to find more super interfaces
+				collected.add(tsuperinterface);
+			}
+			getAllSuperInterfaces2(otHierarchy, tsuperinterface, collected);
+		}
+		for (IType superinterface : otHierarchy.getAllSuperInterfaces(seed)) {
+			collected.add(superinterface);
+			getAllSuperInterfaces2(otHierarchy, superinterface, collected);
+		}
+	}
+	
+	/**
+	 * Configure whether the given hierarchy should consider phantom roles or not.
+	 * Depending on the query used, phantom roles will either be filtered out or replaced with their real origins.
+	 * In order for the phantom modes to be respected, the hierarchy must not be directly consulted but only
+	 * via the fassade methods of this team. 
+	 */
+	public void setPhantomMode(TypeHierarchy as OTTypeHierarchy otHierarchy, boolean mode) {
+		otHierarchy.phantomMode = mode;		
+	}
+}
