initial commit in accordance with CQ 3784
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/.classpath b/plugins/org.eclipse.objectteams.otdt.refactoring/.classpath
new file mode 100644
index 0000000..987380a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="OTRE"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/.project b/plugins/org.eclipse.objectteams.otdt.refactoring/.project
new file mode 100644
index 0000000..ae5e613
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/.project
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.objectteams.otdt.refactoring</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.objectteams.otdt.builder.OTJBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.objectteams.otdt.OTJavaNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.objectteams.otdt.refactoring/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..649ce8b
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,16 @@
+#Sun Aug 26 11:13:53 CEST 2007
+eclipse.preferences.version=1
+org.objectteams.otdt.compiler.option.joinpoint_queries=disabled
+org.objectteams.otdt.compiler.option.scoped_keywords=enabled
+org.objectteams.otdt.compiler.problem.abstract_potential_relevant_role=warning
+org.objectteams.otdt.compiler.problem.basecall=warning
+org.objectteams.otdt.compiler.problem.binding_conventions=error
+org.objectteams.otdt.compiler.problem.decapsulation=warning
+org.objectteams.otdt.compiler.problem.deprecated_path_syntax=warning
+org.objectteams.otdt.compiler.problem.effectless_fieldaccess=warning
+org.objectteams.otdt.compiler.problem.fragile_callin=warning
+org.objectteams.otdt.compiler.problem.incomplete_build=error
+org.objectteams.otdt.compiler.problem.inferred_callout=error
+org.objectteams.otdt.compiler.problem.potential_ambiguous_playedby=warning
+org.objectteams.otdt.compiler.problem.unsafe_liftctor=warning
+org.objectteams.otdt.compiler.problem.unused_parammap=warning
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..6f87195
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: OT/J Refactoring Adaptor Plug-in
+Bundle-SymbolicName: org.eclipse.objectteams.otdt.refactoring;singleton:=true
+Bundle-Version: 1.4.0.qualifier
+Bundle-Vendor: The TOPPrax consortium
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.jdt.ui,
+ org.eclipse.jdt.core,
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.jface.text,
+ org.eclipse.ltk.core.refactoring,
+ org.eclipse.objectteams.otequinox,
+ org.eclipse.ui,
+ org.eclipse.jdt.core.manipulation;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.ltk.ui.refactoring;bundle-version="[3.4.1,4.0.0)",
+ org.eclipse.ui.editors
+Export-Package: org.eclipse.objectteams.otdt.internal.refactoring.corext.base,
+ org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod,
+ org.eclipse.objectteams.otdt.internal.refactoring.corext,
+ org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin,
+ org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin,
+ org.eclipse.objectteams.otdt.internal.refactoring.util
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.objectteams.otdt.internal.refactoring.OTRefactoringPlugin
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/build.properties b/plugins/org.eclipse.objectteams.otdt.refactoring/build.properties
new file mode 100644
index 0000000..0dc34f7
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               plugin.properties
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.properties b/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.properties
new file mode 100644
index 0000000..28e30bf
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.properties
@@ -0,0 +1,13 @@
+Refactoring.menu.label=Refac&tor
+
+Inline.callin.label=Inline Callin...
+Inline.callin.tooltip=Inline a callin-bound method
+
+ActionDefinition.inline.callin.name= InlineCallin
+ActionDefinition.inline.callin.description= Inline a callin-bound role method
+
+Extract.callin.label=Extract Callin...
+Extract.callin.tooltip=Extract a method call to a callin-bound role method
+
+ActionDefinition.extract.callin.name= ExtractCallin
+ActionDefinition.extract.callin.description= Extract a callin-bound role method
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml b/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml
new file mode 100644
index 0000000..3a5c92d
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         point="org.eclipse.objectteams.otequinox.aspectBindings">
+      <aspectBinding icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
+         <basePlugin
+               id="org.eclipse.jdt.ui"
+               icon="platform:/plugin/org.eclipse.pde.ui/icons/obj16/plugin_obj.gif">
+         </basePlugin>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.RenameAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ReorgAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.CorextAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.MoveAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.corext.rename.RolePartsUnifier"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup.PullUpAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.RenameTypeAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.MoveInstanceMethodAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pushdown.PushDownAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ActionGroupAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+      </aspectBinding>
+      <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="NONE"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup.OTTypeHierarchyAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+         <team
+               activation="NONE"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.PhantomTypeAdaptor"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+      </aspectBinding>
+   </extension>
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            description="Action set containing OT/J refactoring actions"
+            id="org.eclipse.objectteams.otdt.internal.refactoring.actionSet"
+            label="OT/J Refactor">
+<!-- Copy&Paste from JDT.UI as per https://bugs.eclipse.org/bugs/show_bug.cgi?id=15670 -->
+         <menu
+               label="%Refactoring.menu.label"
+               path="edit"
+               id="org.eclipse.jdt.ui.refactoring.menu">
+            <separator name="undoRedoGroup"/>
+            <separator name="reorgGroup"/>
+            <separator name="codingGroup"/>
+            <separator name="reorgGroup2"/>
+            <separator name="typeGroup"/>
+            <separator name="typeGroup2"/>
+            <separator name="codingGroup2"/>
+            <separator name="typeGroup3"/>
+            <separator name="scriptGroup"/>
+         </menu>
+<!-- -->
+         <action
+               class="org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin.ExtractCallinAction"
+               definitionId="org.eclipse.objectteams.otdt.refactoring.extract.callin"
+               id="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.action2"
+               label="%Extract.callin.label"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/callinbinding_obj.gif"
+               menubarPath="org.eclipse.jdt.ui.refactoring.menu/codingGroup"
+               style="push"
+               tooltip="%Extract.callin.tooltip">
+         </action>
+         <action
+			   class="org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin.InlineCallinAction"
+               definitionId="org.eclipse.objectteams.otdt.refactoring.inline.callin"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/callinbinding_obj.gif"
+               id="org.eclipse.objectteams.otdt.internal.refactoring.InlineCallin"
+               label="%Inline.callin.label"
+               menubarPath="org.eclipse.jdt.ui.refactoring.menu/codingGroup"
+               style="push">
+         </action>
+      </actionSet>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            name="%ActionDefinition.inline.callin.name"
+            description="%ActionDefinition.inline.callin.description"
+            categoryId="org.eclipse.jdt.ui.category.refactoring"
+            id="org.eclipse.objectteams.otdt.refactoring.inline.callin">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            name="%ActionDefinition.extract.callin.name"
+            description="%ActionDefinition.extract.callin.description"
+            categoryId="org.eclipse.jdt.ui.category.refactoring"
+            id="org.eclipse.objectteams.otdt.refactoring.extract.callin">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension
+            targetID="org.eclipse.objectteams.otdt.ui.OTJavaPerspective">
+         <actionSet
+               id="org.eclipse.objectteams.otdt.internal.refactoring.actionSet">
+         </actionSet>
+      </perspectiveExtension>
+   </extension>
+</plugin>
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/OTRefactoringPlugin.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/OTRefactoringPlugin.java
new file mode 100644
index 0000000..29ea596
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/OTRefactoringPlugin.java
@@ -0,0 +1,33 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2009 Stephan Herrmann
+ * 
+ * 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: OTRefactoringPlugin.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public class OTRefactoringPlugin extends AbstractUIPlugin {
+
+	public static final String PLUGIN_ID = "org.eclipse.objectteams.otdt.refactoring"; //$NON-NLS-1$
+	private static AbstractUIPlugin instance;
+	
+	public OTRefactoringPlugin() {
+		instance = this;
+	}
+
+	public static AbstractUIPlugin getInstance() {
+		return instance;
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ActionGroupAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ActionGroupAdaptor.java
new file mode 100644
index 0000000..cdf8153
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ActionGroupAdaptor.java
@@ -0,0 +1,144 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2009 Stephan Herrmann.
+ * 
+ * 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.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;
+
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.ui.actions.InlineAction;
+import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin.ExtractCallinAction;
+import org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin.InlineCallinAction;
+import org.eclipse.ui.IWorkbenchSite;
+
+import base org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
+import base org.eclipse.jdt.ui.actions.RefactorActionGroup;
+
+/**
+ * @author stephan
+ *
+ */
+@SuppressWarnings("restriction")
+public team class ActionGroupAdaptor 
+{
+	public static final String INLINE_CALLIN = "org.eclipse.objectteams.otdt.refactoring.inline.callin"; //$NON-NLS-1$
+	public static final String EXTRACT_CALLIN = "org.eclipse.objectteams.otdt.refactoring.extract.callin"; //$NON-NLS-1$
+	
+	protected team class CUEditorAdaptor playedBy CompilationUnitEditor 
+	{
+		createActions <- replace createActions;
+		callin void createActions() {
+			within (this)
+				base.createActions();
+		}
+		
+		// workaround for broken in-place lowering
+		JavaEditor getJavaEditor() { return this; }
+		
+		/** Only active during createActions() - nested in order to pass down the editor instance. */
+		protected class ActionGroupEditorTrigger playedBy RefactorActionGroup 
+		{
+			void initOTActions(SelectionDispatchAction action, ISelection selection)
+			<- after void initAction(SelectionDispatchAction action, ISelection selection, String actionDefinitionId)
+			base when (action instanceof InlineAction);
+			
+			private void initOTActions(SelectionDispatchAction action, ISelection selection) {
+				new ActionGroup(this, getJavaEditor(), selection);
+			}
+		}
+	}
+	
+	/** This trigger is globally active to register OT refactoring actions to the global refactoring menu. */
+	protected class ActionGroupGlobalTrigger playedBy RefactorActionGroup 
+	{
+		void initOTActions(SelectionDispatchAction action, ISelectionProvider provider, ISelectionProvider specialProvider, ISelection selection, String actionDefinitionId)
+		<- after void initUpdatingAction(SelectionDispatchAction action, ISelectionProvider provider, ISelectionProvider specialProvider, ISelection selection, String actionDefinitionId)
+		base when (action instanceof InlineAction);
+		
+		private void initOTActions(SelectionDispatchAction action, ISelectionProvider provider, ISelectionProvider specialProvider, ISelection selection, String actionDefinitionId) {
+			new ActionGroup(this, provider, specialProvider, selection);			
+		}
+	}
+	
+	/** This role finally adapts all registered refactoring action groups. */
+	protected class ActionGroup playedBy RefactorActionGroup 
+		base when (ActionGroupAdaptor.this.hasRole(base, ActionGroup.class))
+	{
+		@SuppressWarnings("decapsulation")
+		boolean getFBinary() -> get boolean fBinary;
+
+		@SuppressWarnings("decapsulation")
+		IWorkbenchSite getFSite() -> get IWorkbenchSite fSite;
+
+		@SuppressWarnings("decapsulation")
+		void initUpdatingAction(SelectionDispatchAction action, ISelectionProvider provider, ISelectionProvider specialProvider, ISelection selection, String actionDefinitionId)
+		-> void initUpdatingAction(SelectionDispatchAction action, ISelectionProvider provider, ISelectionProvider specialProvider, ISelection selection, String actionDefinitionId);
+		
+		SelectionDispatchAction inlineCallinAction;
+		SelectionDispatchAction extractCallinAction;
+		
+		protected ActionGroup(RefactorActionGroup group, JavaEditor editor, ISelection selection) {
+			this(group);
+
+			this.inlineCallinAction = new InlineCallinAction().new SelectionDispatchAction(editor);
+			initUpdatingAction(this.inlineCallinAction, null, null, selection, INLINE_CALLIN);
+			editor.setAction("InlineCallin", this.inlineCallinAction); //$NON-NLS-1$
+			
+			this.extractCallinAction = new ExtractCallinAction().new SelectionDispatchAction(editor);
+			initUpdatingAction(this.extractCallinAction, null, null, selection, EXTRACT_CALLIN);
+			editor.setAction("ExtractCallin", this.extractCallinAction); //$NON-NLS-1$
+		}
+
+		protected ActionGroup(RefactorActionGroup group, ISelectionProvider provider, ISelectionProvider specialProvider,ISelection selection) 
+		{
+			this(group);
+
+			this.inlineCallinAction = new InlineCallinAction().new SelectionDispatchAction(getFSite());
+			initUpdatingAction(this.inlineCallinAction, provider, specialProvider, selection, INLINE_CALLIN);
+			
+			this.extractCallinAction = new ExtractCallinAction().new SelectionDispatchAction(getFSite());
+			initUpdatingAction(this.extractCallinAction, provider, specialProvider, selection, EXTRACT_CALLIN);
+		}
+
+		void addAction(IMenuManager menu, IAction action) 
+		<- after int addAction(IMenuManager menu, IAction action)
+		base when (action instanceof InlineAction);
+		
+		
+		private void addAction(IMenuManager menu, IAction action) {
+			if (this.inlineCallinAction != null)
+				menu.add(this.inlineCallinAction);
+			if (this.extractCallinAction != null)
+				menu.add(this.extractCallinAction);
+		}
+		
+		void disposeAction(ISelectionChangedListener action, ISelectionProvider provider) 
+		<- after void disposeAction(ISelectionChangedListener action, ISelectionProvider provider)
+		base when (action instanceof InlineAction);
+		
+		
+		private void disposeAction(ISelectionChangedListener action, ISelectionProvider provider) {
+			if (this.inlineCallinAction != null)
+				provider.removeSelectionChangedListener(this.inlineCallinAction);
+			if (this.extractCallinAction != null)
+				provider.removeSelectionChangedListener(this.extractCallinAction);
+		}			
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/CorextAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/CorextAdaptor.java
new file mode 100644
index 0000000..927b11f
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/CorextAdaptor.java
@@ -0,0 +1,228 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2005, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: CorextAdaptor.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;
+
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.BaseCallMessageSend;
+import org.eclipse.jdt.core.dom.CallinMappingDeclaration;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodSpec;
+import org.eclipse.jdt.core.dom.RoleTypeDeclaration;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.search.JavaSearchScope;
+import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo;
+import org.eclipse.jdt.internal.corext.util.JdtFlags;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.objectteams.otdt.core.IOTJavaElement;
+import org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod.ExtractMethodAmbuguityMsgCreator;
+import org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod.ExtractMethodOverloadingMsgCreator;
+import org.eclipse.objectteams.otdt.internal.refactoring.corext.OTRefactoringCoreMessages;
+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;
+
+import base org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
+import base org.eclipse.jdt.internal.corext.refactoring.TypedSource;
+import base org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring;
+import base org.eclipse.jdt.internal.corext.refactoring.surround.ExceptionAnalyzer;
+
+/**
+ * @author stephan
+ *
+ */
+@SuppressWarnings("restriction")
+public team class CorextAdaptor 
+{
+	protected class TypedSource playedBy TypedSource
+	{
+		static callin boolean canCreateForType(int type){
+			return     base.canCreateForType(type) 	
+					// consider OT-specific elements
+					|| type == IOTJavaElement.TEAM
+					|| type == IOTJavaElement.ROLE
+					|| type == IOTJavaElement.CALLIN_MAPPING
+					|| type == IOTJavaElement.CALLOUT_MAPPING
+					|| type == IOTJavaElement.CALLOUT_TO_FIELD_MAPPING;
+		}
+		@SuppressWarnings("decapsulation")
+		canCreateForType <- replace canCreateForType;
+	}
+	
+	protected class ExtractMethodRefactoring playedBy ExtractMethodRefactoring 
+	{	
+		// previous version patched inline (better integration with progress monitor?
+//		public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
+//			pm.beginTask(RefactoringCoreMessages.ExtractMethodRefactoring_checking_new_name, 2); 
+//			pm.subTask(EMPTY);
+//			
+//			RefactoringStatus result= checkMethodName();
+//			result.merge(checkParameterNames());
+//			result.merge(checkVarargOrder());
+//			pm.worked(1);
+//			if (pm.isCanceled())
+//				throw new OperationCanceledException();
+//
+//			BodyDeclaration node= fAnalyzer.getEnclosingBodyDeclaration();
+//			if (node != null) {
+//				fAnalyzer.checkInput(result, fMethodName, fAST);
+//				pm.worked(1);
+//			}
+////			{ObjectTeams: also check for overloading and ambiguity in OT-subclassed elements
+//			pm.subTask("OTExtractMethodRefactoring.checking_overloading"); 
+//			result.merge(checkOverloadingAndAmbiguity(pm));
+//	//sko}		
+//			pm.done();
+//			return result;
+//		}
+		
+		
+		// let's just append this behavior:
+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus result) 
+				throws CoreException 
+		{
+			pm.beginTask(OTRefactoringCoreMessages.getString("OTExtractMethodRefactoring.checking_overloading"), 1);  //$NON-NLS-1$
+			pm.subTask(""); //$NON-NLS-1$
+			result.merge(checkOverloadingAndAmbiguity(pm));
+			pm.worked(1);
+			pm.done();
+		}
+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) 
+			<- after RefactoringStatus checkFinalConditions(IProgressMonitor pm) 
+		with {
+			pm <- pm, status <- result
+		}
+	
+		//	also check for overloading and ambiguity in OT-subclassed elements
+		private RefactoringStatus checkOverloadingAndAmbiguity(IProgressMonitor pm)
+				throws JavaModelException 
+		{
+			return RefactoringUtil.checkOverloadingAndAmbiguity(getCompilationUnit(),
+					getDestination(), getMethodName(), getParamTypes(),
+					new ExtractMethodAmbuguityMsgCreator(),
+					new ExtractMethodOverloadingMsgCreator(), pm);
+		}
+		
+		private String[] getParamTypes() {
+			List<ParameterInfo> infos = getParameterInfos();
+			if (infos.size() == 0)
+				return new String[0];
+			String[] result = new String[infos.size()];
+			Iterator<ParameterInfo> iterator = infos.iterator();
+			for (int i=0; iterator.hasNext();i++) 
+				result[i] = iterator.next().getNewTypeName();
+			
+			return result;
+		}
+
+		ICompilationUnit getCompilationUnit() -> ICompilationUnit getCompilationUnit();
+		@SuppressWarnings("decapsulation")
+		ASTNode getDestination() -> get ASTNode fDestination;
+		String getMethodName() -> String getMethodName();
+		
+		@SuppressWarnings("unchecked")
+		List<ParameterInfo> getParameterInfos() -> List getParameterInfos();
+	}
+	
+	protected class RefactoringScopeFactory playedBy RefactoringScopeFactory {
+		static void create(IJavaElement javaElement, boolean considerVisibility, IJavaSearchScope scope) 
+			throws JavaModelException 
+		{
+			if (considerVisibility & javaElement instanceof IMember) {
+				IMember member= (IMember) javaElement;
+				if (JdtFlags.isPrivate(member)) {
+					int includeMask = IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES;					
+					((JavaSearchScope)scope).add((JavaProject)javaElement.getJavaProject(), includeMask, new HashSet<IProject>());
+				}
+			}
+		}
+		void create(IJavaElement javaElement, boolean considerVisibility, IJavaSearchScope scope)
+			<- after IJavaSearchScope create(IJavaElement javaElement, boolean considerVisibility, boolean sourceReferencesOnly)
+			with {
+				javaElement        <- javaElement,
+				considerVisibility <- considerVisibility,
+				scope              <- result
+			}
+
+	}
+	
+	/** Need to analyze one more node type: BaseCallMessageSend. */
+	protected class ExceptionAnalyzer playedBy ExceptionAnalyzer
+	{
+		@SuppressWarnings("decapsulation")
+		boolean handleExceptions(IMethodBinding binding) -> boolean handleExceptions(IMethodBinding binding);
+		@SuppressWarnings("decapsulation")
+		boolean isSelected(ASTNode node) -> boolean isSelected(ASTNode node);
+				
+		boolean visit(BaseCallMessageSend node) <- replace boolean visit(BaseCallMessageSend node);
+	    @SuppressWarnings({ "basecall", "unchecked" }) // unchecked: List getBaseMappingElements()
+		callin boolean visit(BaseCallMessageSend node) 
+	    {
+			if (!isSelected(node))
+				return false;
+			
+			// find enclosing method
+			ASTNode parent= node.getParent();
+			while (parent != null && parent.getNodeType() != ASTNode.METHOD_DECLARATION)
+				parent= parent.getParent();
+			if (parent == null)
+				return false;
+			IMethodBinding method= ((MethodDeclaration)parent).resolveBinding();
+			if (method == null)
+				return false;
+			
+			// find enclosing role type
+			while (parent != null && parent.getNodeType() != ASTNode.ROLE_TYPE_DECLARATION)
+				parent= parent.getParent();
+			if (parent == null)
+				return false;
+			RoleTypeDeclaration role= (RoleTypeDeclaration)parent;
+			
+			// find all bound base methods and collect the exceptions they declare
+			boolean result= false;
+			for (CallinMappingDeclaration callinDecl: role.getCallIns()) {
+				MethodSpec roleMethod = (MethodSpec)callinDecl.getRoleMappingElement();
+				if (roleMethod.resolveBinding() == method) {
+					List<ASTNode> baseMethods= callinDecl.getBaseMappingElements(); // raw conversion
+					for (ASTNode elem : baseMethods) {
+						if (elem.getNodeType() == ASTNode.METHOD_SPEC) {
+							MethodSpec baseMethod= (MethodSpec)elem;
+							if (handleExceptions(baseMethod.resolveBinding()))
+								result= true;
+						}
+					}
+				}
+			}
+			return result;
+	    }
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/MoveAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/MoveAdaptor.java
new file mode 100644
index 0000000..a58e37d
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/MoveAdaptor.java
@@ -0,0 +1,76 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008 Technical University Berlin, Germany.
+ * 
+ * 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: MoveAdaptor.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;
+
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
+import org.eclipse.objectteams.otdt.core.IOTType;
+import org.eclipse.objectteams.otdt.core.OTModelManager;
+
+import base org.eclipse.jdt.internal.corext.refactoring.structure.MoveStaticMembersProcessor;
+
+/**
+ * Adjust rules for move static member with respect to OT/J.
+ * 
+ * @author stephan
+ * @since 1.1.7
+ */
+@SuppressWarnings("restriction")
+public team class MoveAdaptor 
+{
+	@SuppressWarnings("decapsulation")
+	protected class MoveStaticMembersProcessor playedBy MoveStaticMembersProcessor {
+
+		IType getFDestinationType() -> get IType fDestinationType;
+
+		RefactoringStatus checkDestinationType() <- replace RefactoringStatus checkDestinationType();
+		callin RefactoringStatus checkDestinationType() 
+				throws JavaModelException 
+		{
+			RefactoringStatus result= base.checkDestinationType();
+			if (result.isOK())
+				return result;
+			// check for error that is actually tolerable for roles:
+			IOTType otType= OTModelManager.getOTElement(getFDestinationType());
+			if (otType != null) {
+				if (otType.isRole()) 
+				{
+					boolean filtered= false;
+					RefactoringStatus newStatus= new RefactoringStatus();
+
+					for (RefactoringStatusEntry entry : result.getEntries())
+						if (isTolerableError(entry))							
+							filtered= true;// filter out: roles may indeed hold static members (in contrast to nested types in Java)
+						else
+							newStatus.addEntry(entry);
+
+					if (filtered)
+						return newStatus;
+				}
+			}
+			return result;
+		}
+		boolean isTolerableError(RefactoringStatusEntry entry) {
+			if (entry.isError()) 
+				return entry.getMessage().equals(RefactoringCoreMessages.MoveMembersRefactoring_static_declaration);
+			return false;
+		}
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/MoveInstanceMethodAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/MoveInstanceMethodAdaptor.java
new file mode 100644
index 0000000..97a85de
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/MoveInstanceMethodAdaptor.java
@@ -0,0 +1,69 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IOverloadingMessageCreator;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

+

+import base org.eclipse.jdt.internal.corext.refactoring.structure.MoveInstanceMethodProcessor;

+

+/**

+ * @author Johannes Gebauer

+ *

+ */

+@SuppressWarnings("restriction")

+public team class MoveInstanceMethodAdaptor {

+

+	

+	@SuppressWarnings("decapsulation")

+	protected class MoveInstanceMethodProcessor playedBy MoveInstanceMethodProcessor {

+		

+		// callouts

+		IMethod getFMethod() -> get IMethod fMethod;

+		IMethod getMethod() -> IMethod getMethod();

+		String getMethodName() -> String getMethodName();

+		IType getTargetType() -> IType getTargetType();

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus result) throws CoreException {

+			if(!result.hasFatalError())

+				result.merge(RefactoringUtil.checkForExistingRoles("Move Instance Method", getFMethod().getJavaProject(), pm));

+			pm.beginTask("Checking Overloading", 1);

+			pm.subTask(""); //$NON-NLS-1$

+			result.merge(checkOverloadingAndAmbiguity(pm));

+			pm.worked(1);

+			pm.done();

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm,

+				CheckConditionsContext context) with {

+			pm <- pm,

+			status <- result

+		}

+

+		private RefactoringStatus checkOverloadingAndAmbiguity(IProgressMonitor pm) throws JavaModelException {

+			

+			String[] paramTypes = getMethod().getParameterTypes();

+

+			return RefactoringUtil.checkOverloadingAndAmbiguity(getTargetType(), null /* targetTypeHierarchy */, getMethodName(), paramTypes,

+					new IAmbuguityMessageCreator() {

+

+						public String createAmbiguousMethodSpecifierMsg() {

+							return "Refactoring cannot be performed! There would be an ambiguous method specifier in a method binding after moving!";

+						}

+

+					}, new IOverloadingMessageCreator() {

+

+						public String createOverloadingMessage() {

+							return "Moved method will be overloaded after refactoring!";

+						}

+

+					}, pm);

+		}

+	}

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/NotSuppoertedRefactoringAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/NotSuppoertedRefactoringAdaptor.java
new file mode 100644
index 0000000..9de232e
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/NotSuppoertedRefactoringAdaptor.java
@@ -0,0 +1,125 @@
+/**

+ * 

+ */

+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IField;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.ITypeRoot;

+import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor;

+

+import base org.eclipse.jdt.internal.corext.refactoring.code.InlineConstantRefactoring;

+import base org.eclipse.jdt.internal.corext.refactoring.code.InlineMethodRefactoring;

+import base org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring;

+import base org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureProcessor;

+import base org.eclipse.jdt.internal.corext.refactoring.structure.ChangeTypeRefactoring;

+import base org.eclipse.jdt.internal.corext.refactoring.structure.ExtractClassRefactoring;

+import base org.eclipse.jdt.internal.corext.refactoring.structure.IntroduceParameterObjectProcessor;

+

+/**

+ * This team holds roles for refactorings that are not yet fully ot-aware. It adds an refactoring info status if any roles exist within the target project.   

+ * 

+ * @author Johannes Gebauer

+ * 

+ */

+@SuppressWarnings("restriction")

+public team class NotSuppoertedRefactoringAdaptor {

+	

+	protected class IntroduceIndirectionRefactoring playedBy IntroduceIndirectionRefactoring {

+		

+		IJavaProject getProject() -> IJavaProject getProject();

+		

+		private void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Introduce Indirection", getProject(),pm));

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(

+				IProgressMonitor pm) with {

+			pm <- pm,

+			status <- result

+		}

+	}

+	

+	protected class InlineMethodRefactoring playedBy InlineMethodRefactoring {

+		@SuppressWarnings("decapsulation")

+		ITypeRoot getFInitialTypeRoot() -> get ITypeRoot fInitialTypeRoot;

+

+		private void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Inline Method", getFInitialTypeRoot().getJavaProject(), pm));

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm) with {

+			pm <- pm,

+			status <- result

+		}

+	}

+	

+	protected class InlineConstantRefactoring playedBy InlineConstantRefactoring {

+		@SuppressWarnings("decapsulation")

+		IField getFField() -> get IField fField;

+

+		private void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Inline Constant", getFField().getJavaProject(), pm));

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm) with {

+			pm <- pm,

+			status <- result

+		}

+	}

+

+	protected class ExtractClassRefactoring playedBy ExtractClassRefactoring {

+		@SuppressWarnings("decapsulation")

+		ExtractClassDescriptor getFDescriptor() -> get ExtractClassDescriptor fDescriptor;

+

+		private void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Extract Class", getFDescriptor().getType().getJavaProject(), pm));

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm) with {

+			pm <- pm,

+			status <- result

+		}

+	}

+

+	 protected class ChangeSignatureProcessor playedBy ChangeSignatureProcessor {

+		@SuppressWarnings("decapsulation")

+		IMethod getFMethod() -> get IMethod fMethod;

+

+		protected void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Change Signature", getFMethod().getJavaProject(), pm));

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm,

+				CheckConditionsContext context) with {

+			pm <- pm,

+			status <- result

+		}

+	}

+	

+	protected class IntroduceParameterObjectProcessor extends ChangeSignatureProcessor playedBy IntroduceParameterObjectProcessor {

+		protected void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Introduce Parameter Object", getFMethod().getJavaProject(), pm));

+		}

+	}

+

+	protected class ChangeTypeRefactoring playedBy ChangeTypeRefactoring {

+		@SuppressWarnings("decapsulation")

+		ICompilationUnit getFCu() -> get ICompilationUnit fCu;

+

+		private void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) when(!status.hasFatalError()) {

+			status.merge(RefactoringUtil.checkForExistingRoles("Change Type", getFCu().getJavaProject(), pm));

+		}

+

+		void checkFinalConditions(IProgressMonitor pm, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm) with {

+			pm <- pm,

+			status <- result

+		}

+	}

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/PhantomTypeAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/PhantomTypeAdaptor.java
new file mode 100644
index 0000000..fe06b31
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/PhantomTypeAdaptor.java
@@ -0,0 +1,41 @@
+/**

+ * 

+ */

+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;

+

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.ITypeParameter;

+import org.eclipse.jdt.core.JavaModelException;

+

+import base org.eclipse.objectteams.otdt.core.PhantomType;

+

+/**

+ * 

+ * This team provides the implementation for some unimplemented methods in

+ * {@link PhantomType}, that would otherwise throw an

+ * <code>UnsupportedOperationException</code>. The methods are used in

+ * {@link RenameTypeAdaptor} to search for <code>PhantomType</code> references

+ * with the java search. This team should be removed if the necessary methods

+ * are implemented in the original {@link PhantomType}.

+ * 

+ * @author Johannes Gebauer

+ */

+public team class PhantomTypeAdaptor{

+	protected class PhantomType playedBy PhantomType {

+

+		IType getRealType() -> IType getRealType();

+

+		@SuppressWarnings("basecall")

+		callin ITypeParameter[] getTypeParameters() throws JavaModelException {

+			return getRealType().getTypeParameters();

+		}

+		getTypeParameters <- replace getTypeParameters;

+		

+		@SuppressWarnings("basecall")

+		callin boolean isResolved() {

+			return false;

+		}

+		isResolved <- replace isResolved;

+		

+	}

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/RenameAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/RenameAdaptor.java
new file mode 100644
index 0000000..59addc0
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/RenameAdaptor.java
@@ -0,0 +1,339 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2005, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: RenameAdaptor.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.dom.BaseCallMessageSend;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext;
+import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
+import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextChange;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;
+import org.eclipse.objectteams.otdt.internal.refactoring.adaptor.rename.RenameMethodAmbuguityMsgCreator;
+import org.eclipse.objectteams.otdt.internal.refactoring.adaptor.rename.RenameMethodOverloadingMsgCreator;
+import org.eclipse.objectteams.otdt.internal.refactoring.corext.OTRefactoringCoreMessages;
+import org.eclipse.objectteams.otdt.internal.refactoring.corext.rename.BaseCallFinder;
+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;
+
+import base org.eclipse.jdt.internal.corext.refactoring.rename.MethodChecks;
+import base org.eclipse.jdt.internal.corext.refactoring.rename.RenameVirtualMethodProcessor;
+import base org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2;
+
+/**
+ * @author stephan
+ *
+ */
+@SuppressWarnings("restriction")
+public team class RenameAdaptor 
+{
+	@SuppressWarnings("basecall")
+	protected class MethodChecks playedBy MethodChecks 
+	{
+		// dispatching some methods. Might consider collecting the dispatch and the implementation..		
+		
+		static callin IMethod getTopmostMethod(IMethod method, ITypeHierarchy typeHierarchy, IProgressMonitor monitor) 
+				throws JavaModelException 
+		{
+			return RefactoringUtil.getTopmostMethod(method, typeHierarchy, monitor);
+		}
+		getTopmostMethod <- replace getTopmostMethod;
+		
+		static callin boolean isVirtual(IMethod method) 
+				throws JavaModelException 
+		{
+			return RefactoringUtil.isVirtual(method);
+		}
+		boolean isVirtual(IMethod method) <- replace boolean isVirtual(IMethod method);
+	}
+	
+	@SuppressWarnings("decapsulation") // multiple
+	protected class RippleMethodFinder2 playedBy RippleMethodFinder2 
+	{
+		@SuppressWarnings("basecall")
+		callin void createHierarchyOfDeclarations(IProgressMonitor pm, WorkingCopyOwner owner) 
+				throws JavaModelException 
+		{
+// UNUSED orig:
+//			IRegion region= JavaCore.newRegion();
+//			for (Iterator<IMethod> iter= getFDeclarations().iterator(); iter.hasNext();) {
+//				IType declaringType= iter.next().getDeclaringType();
+//				region.add(declaringType);
+//			}
+//			fHierarchy= JavaCore.newTypeHierarchy(region, owner, pm);
+	//{ObjectTeams: use OTTypeHierarchy
+			IType declaringType= getFMethod().getDeclaringType();
+			// FIXME(SH): OTTypeHierarchy cannot be computed for regions!
+			OTTypeHierarchy hier = new OTTypeHierarchy(declaringType, true);
+			hier.refresh(pm);
+			setFHierarchy(hier);
+	//jsv}		
+		}
+		
+		static callin IMethod[] getRelatedMethods(IMethod method, IProgressMonitor monitor) 
+			throws CoreException 
+		{
+			// for combining two result arrays:
+			HashSet<IMethod> methods = new HashSet<IMethod>();
+		
+			// OT-Strategy (knows about implicit inheritance):
+			// TODO(SH): passing null-TypeHierarchy probably causes a performance penalty.
+			IMethod topMethod= RefactoringUtil.getTopmostMethod(method, null, monitor);
+			if (topMethod != null)
+				method= topMethod;
+			IMethod[] methodArray = RefactoringUtil.getOverriddenMethods(method, monitor);
+			if (methodArray != null)
+				for (IMethod m : methodArray)
+					methods.add(m);
+			
+			// Java-Strategy:
+			methodArray = base.getRelatedMethods(method, monitor);
+			if (methodArray != null)
+				for (IMethod m : methodArray)
+					methods.add(m);
+			
+			// merge results:
+			methodArray = new IMethod[methods.size()];
+			return methods.toArray(methodArray);
+		}
+		IMethod[] getRelatedMethods(IMethod method, IProgressMonitor pm)
+			<- replace IMethod[] getRelatedMethods(IMethod method, ReferencesInBinaryContext binaryRefs,
+												   IProgressMonitor pm, WorkingCopyOwner owner)
+			with { method <- method, pm <- pm, result -> result }
+		
+
+		createHierarchyOfDeclarations <- replace createHierarchyOfDeclarations;
+		void setFHierarchy(ITypeHierarchy fHierarchy) -> set ITypeHierarchy fHierarchy;
+		IMethod getFMethod() -> get IMethod fMethod;
+	}
+	/**
+	 * This class implements the adaptation of the rename virtual method
+	 * refactoring for OT/J 
+	 * (both from otdt..RenameVirtualMethodProcessor and OTRenameVirtualMethodProcessor).
+	 * 
+	 * <p>The adaptation is implemented as follows:</p>
+	 * <p>
+	 * Preconditions:
+	 * <ol>
+	 *   <li><code>checkFinalConditions(IProgressMonitor, CheckConditionsContext)
+	 *       </code>:</li>
+	 *   <ul>
+	 *     <li>An additional check has been added for cases, where a role class
+	 *         implements an interface. See the comment of this method for a more
+	 *         detailed description of the added check.</li>
+	 *     <li>For collecting all references to the target method, the <code>
+	 *         RefactoringSearchEngine</code> is used <code>(RenameMethodProcessor.
+	 *         getOccurrences(IProgressMonitor, RefactoringStatus))</code>. In
+	 *         particular, the classes <code>MatchLocatorParser</code>, <code>
+	 *         MatchLocator</code>, <code>PatternLocator</code>, <code>OrLocator
+	 *         </code>, and <code>MethodLocator</code> have been modified, in order
+	 *         to find references in callin and callout method bindings.</li>
+	 *   </ul>
+	 * </ol>
+	 * </p>
+	 * 
+	 * @author brcan
+	 */
+	@SuppressWarnings("decapsulation") // multiple!
+	protected class RenameVirtualMethodProcessor
+//			extends JavaRenameProcessor
+			playedBy RenameVirtualMethodProcessor
+	{	
+		// copied from base method
+		@SuppressWarnings("basecall")
+		callin ITypeHierarchy getCachedHierarchy(IType declaring, IProgressMonitor monitor) 
+				throws JavaModelException 
+		{
+			ITypeHierarchy cachedHierarchy = getFCachedHierarchy();
+			if (cachedHierarchy != null && declaring.equals(cachedHierarchy.getType()))
+				return cachedHierarchy;
+	//{ObjectTeams: use OTTypeHierarchy
+			//orig: fCachedHierarchy= declaring.newTypeHierarchy(new SubProgressMonitor(monitor, 1));
+			cachedHierarchy = new OTTypeHierarchy(declaring, true);
+			cachedHierarchy.refresh(monitor);
+			setFCachedHierarchy(cachedHierarchy);
+	//jsv}
+			return cachedHierarchy;
+		}
+		getCachedHierarchy <- replace getCachedHierarchy;
+		
+		ITypeHierarchy getFCachedHierarchy() -> get ITypeHierarchy fCachedHierarchy;
+		void setFCachedHierarchy(ITypeHierarchy fCachedHierarchy) -> set ITypeHierarchy fCachedHierarchy;
+
+		// communication vars for enclosing doCheckFinalConditions():
+		IProgressMonitor tmpMonitor = null;
+		String tmpErrorMsg = null;
+		/*
+		 * TODO(SH): isSpecialCase() is only invoked for interface methods. Is this the correct hook?
+		 */
+		void isOTSpecialCase () throws CoreException 
+		{
+			if (RefactoringUtil.isOTSpecialCase(getMethod(),
+					getNewElementName(),
+					true,
+					tmpMonitor))
+			{
+				tmpErrorMsg = OTRefactoringCoreMessages.getString("RenameVirtualMethodRefactoring.special_team_method"); //$NON-NLS-1$
+			}
+		}
+		 isOTSpecialCase <- after isSpecialCase;
+		/**
+	     * Provides OT-specific final condition checking and performs the
+	     * final condition checking provided by the standard Eclipse
+	     * implementation.
+	     * <p>
+	     * What:
+	     * <ol>
+	     *   <li>OT-specific final condition checking:</li>
+	     *   <ul>
+		 *     <li>The following additional checks/changes have been added:
+		 *         (1) check for overloading and ambiguous method specs.
+		 *         (2) Update base calls when renaming callin methods.
+		 *     </li>
+	     *   </ul>
+	     * </ol>
+	     * </p>
+	     */
+		callin RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext checkContext) 
+				throws CoreException 
+		{
+			tmpMonitor = pm;
+			tmpErrorMsg = null;
+			RefactoringStatus result = null;
+			try {
+				result = base.doCheckFinalConditions(pm, checkContext);
+				result.merge(checkOverloadingAndAmbiguity(pm));
+			} finally {
+				if (tmpErrorMsg != null && result != null)
+					result.addError(tmpErrorMsg);
+				tmpErrorMsg = null;
+			}
+			return result;
+		}
+		doCheckFinalConditions <- replace doCheckFinalConditions;
+	
+		//	also check for overloading and ambiguity in OT-subclassed elements
+		@SuppressWarnings("nls")
+		private RefactoringStatus checkOverloadingAndAmbiguity(IProgressMonitor pm)
+				throws JavaModelException 
+		{
+	    	IMethod newMethod = getOriginalMethod();
+	    	IType focusType = getOriginalMethod().getDeclaringType();
+	    	if (focusType.isAnnotation() || focusType.isEnum())
+	    		return new RefactoringStatus();
+	    	ICompilationUnit cu = focusType.getCompilationUnit();
+	    	String newMethodName = getNewElementName();
+			
+			try
+			{
+				return RefactoringUtil.checkOverloadingAndAmbiguity(cu,
+						focusType,
+						newMethodName,
+						getOriginalMethod().getElementName(),
+						newMethod.getParameterTypes(),
+						new RenameMethodAmbuguityMsgCreator(),
+						new RenameMethodOverloadingMsgCreator(), pm);
+			} 
+	    	catch (JavaModelException e)
+			{
+	    		//TODO(jsv): Use meaningful message and store it in the message file
+	    		RefactoringStatus result = new RefactoringStatus();
+	    		result.addError("Error while checking overloading and ambiguity");
+	    		return result;
+			}
+		}
+		
+		void addOccurrences(TextChangeManager manager, IProgressMonitor pm, RefactoringStatus status) 
+	    		throws CoreException 
+	    {
+	    	createChangeForPotentialBaseCalls(manager);
+	    }
+	    addOccurrences <- after addOccurrences;
+
+	    /**
+	     * Creates changes for base call in a callin method.
+	     * Appearance of warning or error is not possible, this method does not
+	     * return a refactoring status.
+	     */
+	    private void createChangeForPotentialBaseCalls(TextChangeManager changeManager)
+	    {
+	        Set<IMethod> methodsToRename = getMethodsToRename();
+	        
+	        for (Iterator<IMethod> methods = methodsToRename.iterator(); methods.hasNext();)
+	        {
+	            IMethod currentMethod =  methods.next();
+	            MethodDeclaration methodDeclaration = null;
+	    		try
+	    		{
+	    		    if (!Flags.isCallin(currentMethod.getFlags()))
+	    		    {
+	    		        continue;
+	    		    }
+	    			methodDeclaration = RefactoringUtil.getMethodDeclaration(currentMethod);
+	    		} 
+	        	catch (JavaModelException ex)
+	        	{
+	        	    JavaPlugin.logErrorMessage("Problems while searching DOM AST representation of a method"); //$NON-NLS-1$
+	        	    continue;
+	    		}
+	        	
+	        	BaseCallFinder baseCallFinder = new BaseCallFinder();
+	        	methodDeclaration.accept(baseCallFinder);
+	        	BaseCallMessageSend[] baseCalls = baseCallFinder.getResult();
+	        	
+	        	for (int idx = 0;idx < baseCalls.length; idx++)
+	        	{
+	        	    ICompilationUnit cu = currentMethod.getCompilationUnit();
+	        	    TextChange textChange = changeManager.get(cu);
+	        	    
+	        	    String editName = OTRefactoringCoreMessages.getString(
+	        	            "OTRenameVirtualMethodProcessor.update_base_call_occurrence"); //$NON-NLS-1$
+	        	    TextChangeCompatibility.addTextEdit(textChange, editName,
+	        	            new ReplaceEdit(baseCalls[idx].getName().getStartPosition(),
+	        	                    baseCalls[idx].getName().getLength(),
+	        	                    getNewElementName()));
+	        	}
+	        }
+	    }
+	  
+		IMethod getOriginalMethod()  	  -> IMethod getOriginalMethod();
+		String  getNewElementName()       -> String  getNewElementName();
+		@SuppressWarnings({ "unchecked", "rawtypes" })
+		Set<IMethod> getMethodsToRename() -> Set     getMethodsToRename();
+		IMethod getMethod() 		      -> IMethod getMethod();
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/RenameTypeAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/RenameTypeAdaptor.java
new file mode 100644
index 0000000..ce068e5
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/RenameTypeAdaptor.java
@@ -0,0 +1,730 @@
+/**

+ * 

+ */

+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;

+

+import java.text.MessageFormat;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.LinkedHashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.IClassFile;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.IPackageFragment;

+import org.eclipse.jdt.core.IPackageFragmentRoot;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.internal.corext.refactoring.Checks;

+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;

+import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;

+import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;

+import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;

+import org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange;

+import org.eclipse.jdt.internal.corext.refactoring.changes.RenamePackageChange;

+import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;

+import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;

+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

+import org.eclipse.jdt.internal.corext.util.Messages;

+import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;

+import org.eclipse.ltk.core.refactoring.Change;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.TextChange;

+import org.eclipse.ltk.core.refactoring.TextFileChange;

+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;

+import org.eclipse.text.edits.ReplaceEdit;

+import org.eclipse.objectteams.otdt.core.IOTType;

+import org.eclipse.objectteams.otdt.core.IRoleType;

+import org.eclipse.objectteams.otdt.core.OTModelManager;

+import org.eclipse.objectteams.otdt.core.PhantomType;

+import org.eclipse.objectteams.otdt.core.TypeHelper;

+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;

+

+import base org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;

+

+

+

+/**

+ * @author Johannes Gebauer

+ * 

+ */

+@SuppressWarnings({"restriction","rawtypes","decapsulation"})

+public team class RenameTypeAdaptor {

+

+	protected class RenameTypeProcessor playedBy RenameTypeProcessor {

+		

+		private static final String ICONFINED = "IConfined"; //$NON-NLS-1$

+		private static final String CONFINED = "Confined"; //$NON-NLS-1$

+		private static final String ILOWERABLE = "ILowerable"; //$NON-NLS-1$

+

+		private IPackageFragment fRoleDirectory;

+		private IType[] fImplicitRelatedTypes;

+		private IType[] fImplicitRelatedPhantomTypes;

+		private OTTypeHierarchy fOTTypeHierarchy;

+		private boolean fTypeToRenameIsRole;

+		private String fCachedNewElementName;

+		private JavaModelException fCachedException;

+		

+		// ======= callouts =======

+		LinkedHashMap getFPreloadedElementToName() -> get LinkedHashMap fPreloadedElementToName;

+		void setFPreloadedElementToName(LinkedHashMap preloadedElementToName) -> set LinkedHashMap fPreloadedElementToName;

+		IType getFType() -> get IType fType;

+		void setFType(IType type) -> set IType fType;

+		String getNewElementLabel() -> String getNewElementLabel();

+		TextChangeManager getFChangeManager() -> get TextChangeManager fChangeManager;

+		SearchResultGroup[]  getFReferences() -> get SearchResultGroup[]  fReferences;

+		void setFReferences(SearchResultGroup[] fReferences) -> set SearchResultGroup[]  fReferences;

+		String getNewElementName() -> String getNewElementName();	

+		boolean getUpdateSimilarDeclarations() -> boolean getUpdateSimilarDeclarations();

+		int getFRenamingStrategy() -> get int fRenamingStrategy;

+		int getFCachedRenamingStrategy() -> get int fCachedRenamingStrategy;

+		boolean getFCachedRenameSimilarElements() -> get boolean fCachedRenameSimilarElements;

+		RefactoringStatus getFCachedRefactoringStatus() -> get RefactoringStatus fCachedRefactoringStatus;

+		String getFCachedNewName() -> get String fCachedNewName;

+		void setFPreloadedElementToNameDefault(LinkedHashMap fPreloadedElementToNameDefault) -> set LinkedHashMap fPreloadedElementToNameDefault;

+		LinkedHashMap getFPreloadedElementToNameDefault() -> get LinkedHashMap fPreloadedElementToNameDefault;

+		void setFPreloadedElementToSelection(Map fPreloadedElementToSelection) -> set Map fPreloadedElementToSelection;

+		Map getFPreloadedElementToSelection() -> get Map fPreloadedElementToSelection;

+		void setFFinalSimilarElementToName(Map fFinalSimilarElementToName) -> set Map fFinalSimilarElementToName;

+		Map getFFinalSimilarElementToName() -> get Map fFinalSimilarElementToName;

+		

+		

+		callin RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException{

+			initializeOTInformations(pm);

+			

+			// Java conditions:

+			RefactoringStatus jdtStatus = base.doCheckFinalConditions(pm, context);

+			if(jdtStatus.hasFatalError()){

+				return jdtStatus;

+			}

+			

+			// throw a cached exception that could not be thrown earlier

+			if(fCachedException != null){

+				throw fCachedException;

+			}

+			

+			// OT conditions:

+			if(Flags.isTeam(getFType().getFlags())){

+				if(fRoleDirectory != null){

+					jdtStatus.merge(checkForConflictingRoleDirectoryName(fRoleDirectory));

+				}

+			}

+			

+			// Special Conditions for Roles

+			if(fTypeToRenameIsRole){

+				jdtStatus.merge(checkForRoleOverriding(pm));

+			    jdtStatus.merge(checkRenameForImplicitRelatedTypes(getFType(), fOTTypeHierarchy, pm));

+			}

+			

+			pm.done();

+			return jdtStatus;

+			

+		}

+

+		doCheckFinalConditions <- replace doCheckFinalConditions;

+

+		private void initializeOTInformations(IProgressMonitor pm) throws JavaModelException {

+			// Do not initialize again if the preconditions have not changed.

+			// OT informations depend on the type and the new element name.

+			if(fOTTypeHierarchy != null && fOTTypeHierarchy.getFocusType() == getFType() 

+			   &&  getNewElementName().equals(fCachedNewElementName)){

+				return;

+			}

+

+			fCachedNewElementName = getNewElementName();

+			fOTTypeHierarchy = new OTTypeHierarchy(getFType(), getFType().getJavaProject(), true);

+			fOTTypeHierarchy.refresh(pm);

+			findImplicitRelatedTypes(getFType(), fOTTypeHierarchy, null);

+			fTypeToRenameIsRole = TypeHelper.isRole(getFType().getFlags());

+			if(Flags.isTeam(getFType().getFlags())){

+				fRoleDirectory = getRoleDirectoryForTeam(getFType());

+			}

+			fCachedException = null;

+		}

+		

+		/**

+		 * Adds implicit related Types references to the jdt references, that contain only the focus type references. 

+		 * 

+		 */

+		@SuppressWarnings({ "basecall", "unchecked", "rawtypes" })

+		callin  RefactoringStatus initializeReferences(IProgressMonitor monitor) throws JavaModelException, OperationCanceledException{

+

+			// Do not search again if the preconditions have not changed.

+			// This check is a copy of RenameTypeProcessor.initializeReferences(),

+			// to prevent multiple processing of the implicit related types.

+			if (getFReferences() != null && (getNewElementName().equals(getFCachedNewName())) && (getFCachedRenameSimilarElements() == getUpdateSimilarDeclarations())

+					&& (getFCachedRenamingStrategy() == getFRenamingStrategy()))

+				return getFCachedRefactoringStatus();

+

+			// The ot informations may have not been initialized if the wizard computes the references for a preview.

+			initializeOTInformations(monitor);

+

+			//jdt strategy

+			RefactoringStatus jdtStatus = base.initializeReferences(monitor);

+

+			// cache the original focus type and found jdt references

+			IType originalFocusType = getFType();

+			SearchResultGroup[] jdtReferences = getFReferences();

+

+			// cache the resources for the renaming of similar named elements

+			LinkedHashMap originalPreloadedElementToName = getFPreloadedElementToName();

+			Map originalPreloadedElementToSelection = getFPreloadedElementToSelection();

+			LinkedHashMap originalPreloadedElementToNameDefault = getFPreloadedElementToNameDefault();

+

+			// initialize data structures for the ot references and similar named elements

+			ArrayList<SearchResultGroup> otReferences = new ArrayList<SearchResultGroup>();

+			LinkedHashMap otPreloadedElementToName = new LinkedHashMap();

+			Map otPreloadedElementToSelection = new HashMap();

+			LinkedHashMap otPreloadedElementToNameDefault = new LinkedHashMap();

+

+			try{

+				// find references for implicit related types

+				for (int i = 0; i < fImplicitRelatedTypes.length; i++) {

+					setFType(fImplicitRelatedTypes[i]);

+					setFReferences(null);

+					

+					jdtStatus.merge(base.initializeReferences(monitor));

+					

+					// add all references of the implicit related type

+					otReferences.addAll(Arrays.asList(getFReferences()));

+					

+					// add all similar name references of the implicit related type to the maps

+					otPreloadedElementToName.putAll(getFPreloadedElementToName());

+					otPreloadedElementToSelection.putAll(getFPreloadedElementToSelection());

+					otPreloadedElementToNameDefault.putAll(getFPreloadedElementToNameDefault());

+				}

+				

+				//TODO: UnsupportedOperationException in PhantomType(the PhantomTypeAdaptor provides a quick fix)

+				within(new PhantomTypeAdaptor()){

+					// find references for implicit related phantom types

+					for (int i = 0; i < fImplicitRelatedPhantomTypes.length; i++) {

+						setFType(fImplicitRelatedPhantomTypes[i]);

+						setFReferences(null);

+						

+						jdtStatus.merge(base.initializeReferences(monitor));

+						

+						// add all references of the implicit related type

+						otReferences.addAll(Arrays.asList(getFReferences()));

+						

+						// add all similar name references of the implicit related type to the maps

+						otPreloadedElementToName.putAll(getFPreloadedElementToName());

+						otPreloadedElementToSelection.putAll(getFPreloadedElementToSelection());

+						otPreloadedElementToNameDefault.putAll(getFPreloadedElementToNameDefault());

+					}

+				}

+			}finally{

+				// ensure that the original focus type is reset after processing the implicit type references

+				setFType(originalFocusType);

+				

+				// combine the ot references with the jdt references

+				otReferences.addAll(Arrays.asList(jdtReferences));

+				setFReferences(otReferences.toArray(new SearchResultGroup[otReferences.size()]));

+				

+				// combine and set the maps for the similar named elements 

+				originalPreloadedElementToName.putAll(otPreloadedElementToName);

+				setFPreloadedElementToName(originalPreloadedElementToName);

+				originalPreloadedElementToSelection.putAll(otPreloadedElementToSelection);

+				setFPreloadedElementToSelection(originalPreloadedElementToSelection);

+				originalPreloadedElementToNameDefault.putAll(otPreloadedElementToNameDefault);

+				setFPreloadedElementToNameDefault(originalPreloadedElementToNameDefault);

+					

+			}

+			return jdtStatus;

+		}

+		initializeReferences <- replace initializeReferences;

+		

+		private RefactoringStatus checkRenameForImplicitRelatedTypes(IType type, OTTypeHierarchy otTypeHierarchy, IProgressMonitor pm) throws CoreException {

+			RefactoringStatus status = new RefactoringStatus();

+			for (int i = 0; i < fImplicitRelatedTypes.length; i++) {

+				status.merge(checkShadowingInEnclosingTeams(fImplicitRelatedTypes[i]));

+			}

+			for (int i = 0; i < fImplicitRelatedPhantomTypes.length; i++) {

+				status.merge(checkShadowingInEnclosingTeams(fImplicitRelatedPhantomTypes[i]));

+			}

+			return status;

+		}

+

+		private void findImplicitRelatedTypes(IType type, OTTypeHierarchy otTypeHierarchy, IProgressMonitor pm) throws JavaModelException {

+			IType topmostType = findTopMostType(type, otTypeHierarchy);

+			OTTypeHierarchy topmostTypeHierarchy = new OTTypeHierarchy(topmostType, topmostType.getJavaProject(), true);

+			topmostTypeHierarchy.refresh(pm);

+			

+			ArrayList<IType> relatedTypes = new ArrayList<IType>();

+			relatedTypes.addAll(Arrays.asList(topmostTypeHierarchy.getAllTSubtypes(topmostType)));

+

+			// exchange the topmost type with the given type

+			if(!topmostType.equals(type)){

+				relatedTypes.remove(type);

+				relatedTypes.add(topmostType);

+			}

+			

+			fImplicitRelatedTypes = relatedTypes.toArray(new IType[relatedTypes.size()]);

+			

+			// search the implicit related phantom types

+			topmostTypeHierarchy.setPhantomMode(true);

+			ArrayList<IType> relatedPhantomTypes = new ArrayList<IType>();

+			relatedPhantomTypes.addAll(Arrays.asList(topmostTypeHierarchy.getAllTSubtypes(topmostType)));

+			relatedPhantomTypes.removeAll(relatedTypes);

+			relatedPhantomTypes.remove(type);

+			fImplicitRelatedPhantomTypes = relatedPhantomTypes.toArray(new IType[relatedPhantomTypes.size()]);

+

+		}

+

+		/**

+		 * Finds the topmost declaration of a Role Type in the implicit type hierarchy.

+		 * Returns the type itself, if it does not have any implicit super types.

+		 * 

+		 * @param type the role type to start the search

+		 * @param otTypeHierarchy for the type

+		 * @return the topmost Role Type for the given type

+		 */

+		private IType findTopMostType(IType type, OTTypeHierarchy otTypeHierarchy) {

+			IType[] superTypes = otTypeHierarchy.getAllTSuperTypes(type);

+			for (int i = 0; i < superTypes.length; i++) {

+				if(otTypeHierarchy.getAllTSuperTypes(superTypes[i]).length == 0){

+					return superTypes[i];

+				}

+			}

+			return type;

+		}

+

+		private void addTypeDeclarationUpdate(TextChangeManager manager, IType type) throws CoreException {

+			String name = RefactoringCoreMessages.RenameTypeRefactoring_update;

+			int typeNameLength = type.getElementName().length();

+			ICompilationUnit cu = type.getCompilationUnit();

+			TextChangeCompatibility.addTextEdit(manager.get(cu), name, new ReplaceEdit(type.getNameRange().getOffset(), typeNameLength, getNewElementName()));

+			

+

+		}

+		

+		private void createChanges(IProgressMonitor pm) throws JavaModelException, CoreException{

+			pm.beginTask("Create changes for implicit type declarations", fImplicitRelatedTypes.length);

+			pm.subTask(""); //$NON-NLS-1$

+			if(fTypeToRenameIsRole){

+				for (int i = 0; i < fImplicitRelatedTypes.length; i++) {

+					addTypeDeclarationUpdate(getFChangeManager(), fImplicitRelatedTypes[i]);

+					pm.worked(1);

+				}

+			}

+			pm.done();

+		}

+		createChanges <- after createChanges;

+		

+		callin Change createChange(IProgressMonitor monitor) throws CoreException{

+

+			IType typeToRename = getFType();

+		

+			// save the compilation units of the implicit related type declarations

+			if(fTypeToRenameIsRole){

+				for (int i = 0; i < fImplicitRelatedTypes.length; i++) {

+					IType type = fImplicitRelatedTypes[i];

+					if (getFChangeManager().containsChangesIn(type.getCompilationUnit())) {

+						TextChange textChange = getFChangeManager().get(type.getCompilationUnit());

+						if (textChange instanceof TextFileChange) {

+							((TextFileChange) textChange).setSaveMode(TextFileChange.FORCE_SAVE);

+						}

+					}

+				}

+			}

+			

+			// create the jdt change

+			Change jdtChange = base.createChange(monitor);

+			

+			

+			if(Flags.isTeam(typeToRename.getFlags())){

+				// a role directory exists

+				if(fRoleDirectory != null){

+					// rename the directory to the new team name

+					RenamePackageChange renameRoleFolderChange= new RenamePackageChange( fRoleDirectory, typeToRename.getPackageFragment().getElementName() + "." + getNewElementName(),  false);

+					((DynamicValidationRefactoringChange)jdtChange).add(renameRoleFolderChange);

+				}	

+			}

+			

+			

+			if(fTypeToRenameIsRole){

+				

+				// Update the compilation unit name if the role is declared in a role file

+				for (int i = 0; i < fImplicitRelatedTypes.length; i++) {

+					IType type = fImplicitRelatedTypes[i];

+					

+					if(isRoleFile(type)){

+						String renamedCUName = JavaModelUtil.getRenamedCUName(type.getCompilationUnit(), getNewElementName());

+						((DynamicValidationRefactoringChange)jdtChange).add(new RenameCompilationUnitChange(type.getCompilationUnit(), renamedCUName));

+					}

+				}

+			}

+			return jdtChange;

+		}

+		createChange <- replace createChange;

+		

+		

+		callin RefactoringStatus checkNewElementName(String newName){

+			RefactoringStatus jdtStatus = base.checkNewElementName(newName);

+			if(fTypeToRenameIsRole){

+				jdtStatus.merge(checkNewRoleName(newName));

+			}

+			return jdtStatus;

+		}

+		

+		checkNewElementName <- replace checkNewElementName;

+		

+		/**

+		 * If a regular type is renamed it must be checked if any existing roles would shadow the renamed type.

+		 * Role types are separately handled in <code>checkShadowingInEnclosingTeams()</code>.

+		 */

+		callin RefactoringStatus checkRoleTypesInPackage() throws CoreException{

+			RefactoringStatus jdtStatus = base.checkRoleTypesInPackage();

+			

+			if(jdtStatus == null){

+				jdtStatus = new RefactoringStatus();

+			}

+

+			IType[] types = getAllTypesInPackage(getFType().getPackageFragment());

+			for(int i = 0; i < types.length; i++){

+				IType type = types[i];

+				if(TypeHelper.isTeam(type.getFlags())){

+					IType[] roles = getAllRoles(type);

+					for (int j = 0; j < roles.length; j++) {

+						IType role = roles[j];

+						if(role.getElementName().equals(getNewElementName())){

+							String msg = Messages.format("A role type named ''{0}'' exists in ''{1}'' and would shadow the renamed type (OTLD �1.4(a)).", new String[] { getNewElementName(),

+									type.getFullyQualifiedName('.') });

+							jdtStatus.addError(msg, JavaStatusContext.create(role));

+						}

+					}

+				}

+			}

+			

+			return jdtStatus;

+		}

+		

+		checkRoleTypesInPackage <- replace checkTypesInPackage when(!fTypeToRenameIsRole);

+		

+		

+		/**

+		 * Roles need a more detailed analysis for name conflicts, that includes all roles of the enclosing team.

+		 * 

+		 */

+		@SuppressWarnings("basecall")

+		callin RefactoringStatus checkTypesInCompilationUnit(){

+			RefactoringStatus status = new RefactoringStatus();

+			try {

+				status.merge(checkForExistingRoles(getFType()));

+				status.merge(checkShadowingInEnclosingTeams(getFType()));

+				return status;

+			} catch (JavaModelException e) {

+				// cache the exception to throw it later

+				fCachedException = e;

+				return status;

+			}

+		}

+		

+		checkTypesInCompilationUnit <- replace checkTypesInCompilationUnit when(fTypeToRenameIsRole);

+		

+		// helper

+

+		/**

+		 * Checks if the given role name is invalid because it is already used for OT specific interfaces.

+		 * 

+		 * @param newRoleName the new role name

+		 * @return a <Code>RefactoringStatus</Code> that may signal an invalid role name

+		 */

+		private RefactoringStatus checkNewRoleName(String newRoleName) {

+			RefactoringStatus status = new RefactoringStatus();

+			// prevent invalid role names that are used for OT specific interfaces

+			if(newRoleName.equals(CONFINED)

+				|| newRoleName.equals(ICONFINED)

+				|| newRoleName.equals(ILOWERABLE))

+			{

+				status.addFatalError(RefactoringCoreMessages.RenameTypeRefactoring_choose_another_name);

+			}

+			return status;

+		}

+		

+		/**

+		 * Checks if the new role name causes implicit overriding in super and sub teams.

+		 * 

+		 * @return the <code>RefactoringStatus</code> indicating implicit overriding

+		 * @throws JavaModelException if the creation of a type hierarchy for the enclosing team failed

+		 */

+		private RefactoringStatus checkForRoleOverriding(IProgressMonitor pm) throws JavaModelException {

+			Assert.isTrue(fTypeToRenameIsRole);

+			

+			IOTType otElement = OTModelManager.getOTElement(getFType());

+			IOTType enclosingTeam = ((IRoleType)otElement).getTeam();

+			

+			pm.beginTask("Check Overriding", 1);

+			pm.subTask(""); //$NON-NLS-1$

+			RefactoringStatus status = new RefactoringStatus();

+			try{

+				// search for implicit overriding of inherited roles

+				IType[] roles = TypeHelper.getInheritedRoleTypes(enclosingTeam);

+				for (int i = 0; i < roles.length; i++) {

+					IType currRole = roles[i];

+					if(currRole.getElementName().equals(getNewElementName())){

+						String msg = Messages.format("The renamed role type would override the inherited role type ''{0}''.",

+								new String[] { currRole.getFullyQualifiedName('.') });

+						status.addError(msg, JavaStatusContext.create(currRole));

+						return status;

+					}

+				}

+				

+				

+				// search for implicit overriding in the subtypes of the enclosing team

+				OTTypeHierarchy teamHierarchy = new OTTypeHierarchy(enclosingTeam, enclosingTeam.getJavaProject(), true);

+				teamHierarchy.refresh(pm);

+				IType[] subtypes = teamHierarchy.getAllSubtypes(enclosingTeam);

+				for (int i = 0; i < subtypes.length; i++) {

+					IType[] declaredRoles = getDeclaredRoles(subtypes[i]);

+					

+					for (int j = 0; j < declaredRoles.length; j++) {

+						IType currRole = declaredRoles[j];

+						if(currRole.getElementName().equals(getNewElementName())){

+							String msg = Messages.format("The renamed role type would be overridden by role type ''{0}''.",

+									new String[] { currRole.getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(currRole));

+							return status;

+						}

+					}

+				}

+				return status;

+			}finally{

+				pm.worked(1);

+				pm.done();

+			}

+		}

+

+		/**

+		 * Checks if a package with the new team name already exists.

+		 * 

+		 * @param roleDirectory

+		 * @return

+		 * @throws JavaModelException

+		 */

+		private RefactoringStatus checkForConflictingRoleDirectoryName(IPackageFragment roleDirectory) throws JavaModelException {

+			IJavaElement[] packages= ((IPackageFragmentRoot)roleDirectory.getParent()).getChildren();

+			for (int i = 0;  i < packages.length; i++) {

+				if(packages[i].getElementName().equals(getFType().getPackageFragment().getElementName() + "." + getNewElementName())){

+					String msg = MessageFormat.format("The new team name ''{0}'' collides with the package ''{1}'', therefore a renaming of the role directory ''{2}'' is impossible.", new Object[]{getFType().getElementName(), packages[i].getElementName(), roleDirectory.getElementName()});

+					return RefactoringStatus.createErrorStatus(msg);

+				}

+			}

+			return null;

+		}

+

+		/**

+		 * Checks for name conflicts within the enclosing team of the given role. Returns an <code>

+		 * ERROR</code> <code>RefactoringStatus</code> if a role with the new name would shadow or would be shadowed by the new name.

+		 * 

+		 * @param roleType the role to be checked

+		 * @return the <code>RefactoringStatus</code> indicating shadowing issues with other roles

+		 * @throws JavaModelException

+		 */

+		private RefactoringStatus checkShadowingInEnclosingTeams(IType roleType) throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			if(!TypeHelper.isRole(roleType.getFlags())){

+				return status;

+			}

+			

+			IType outerTeam = getTeam(roleType);

+			IType directEnclosingTeam = outerTeam;

+			

+			// Search for nested roles in the direct enclosing team that would shadow the renamed role type

+			IType[] allRoles = TypeHelper.getAllRoleTypes(directEnclosingTeam);

+			for (int i = 0; i < allRoles.length; i++) {

+				if(allRoles[i].equals(OTModelManager.getOTElement(roleType))){

+					// skip the renamed role type because it is already checked in the base's method checkEnclosedTypes()

+					continue;

+				}

+				IType[] nestedRoles = getAllRoles(allRoles[i]);

+				for (int j = 0; j < nestedRoles.length; j++) {

+					IType role = nestedRoles[j];

+					if(role.getElementName().equals(getNewElementName())){

+						String msg = Messages.format("The role type ''{0}'' would shadow the renamed type (OTLD �1.4(a))."

+								, new String[] { BasicElementLabels.getJavaElementName(role.getFullyQualifiedName('.')) });

+						status.addError(msg, JavaStatusContext.create(role));

+					}

+				}

+			}

+			

+			// If the enclosing team is a role itself recursively search role names that could be shadowed by the renamed role type

+			while(TypeHelper.isRole(outerTeam.getFlags())){

+				outerTeam = getTeam(outerTeam);

+				IRoleType[] outerRoles = TypeHelper.getAllRoleTypes(outerTeam);

+				for (int i = 0; i < outerRoles.length; i++) {

+					if(outerRoles[i].equals(OTModelManager.getOTElement(directEnclosingTeam))){

+						// skip the direct enclosing team, because this is checked in the base's method checkEnclosingTypes()

+						continue;

+					}

+					IType role = outerRoles[i];

+					if(role.getElementName().equals(getNewElementName())){

+						String msg = Messages.format("The renamed role type would shadow the visible type ''{0}'' (OTLD �1.4(a))."

+								, new String[] { BasicElementLabels.getJavaElementName(role.getFullyQualifiedName('.')) });

+						status.addError(msg, JavaStatusContext.create(role));

+					}

+				}

+			}

+			

+			return status;

+		}

+		

+		private RefactoringStatus checkForExistingRoles(IType roleType) throws JavaModelException{

+			RefactoringStatus status = new RefactoringStatus();

+			if(!TypeHelper.isRole(roleType.getFlags())){

+				return status;

+			}

+			

+			// For the direct enclosing team all declared roles have to be checked

+			IType enclosingTeam = getTeam(roleType);

+			IType[] declaredRoles = getDeclaredRoles(enclosingTeam);

+			for (int i = 0; i < declaredRoles.length; i++) {

+				IOTType otElement = OTModelManager.getOTElement(declaredRoles[i]);

+				if(otElement instanceof IRoleType){

+					IRoleType role = (IRoleType) otElement;

+					if(role.getElementName().equals(getNewElementName())){

+						String msg = Messages.format(RefactoringCoreMessages.RenameTypeRefactoring_member_type_exists, new String[] { getNewElementLabel(),

+								BasicElementLabels.getJavaElementName(role.getTeam().getFullyQualifiedName('.')) });

+						status.addError(msg, JavaStatusContext.create(role));

+					}

+				}

+			}		

+			return status;

+		}

+

+		private IType getTeam(IType roleType) {

+			IType enclosingTeam;

+			IOTType otElement;

+			if(roleType instanceof PhantomType){

+				enclosingTeam = (IType) ((PhantomType)roleType).getParent();

+			}else{

+				otElement = OTModelManager.getOTElement(roleType);

+				enclosingTeam = ((IRoleType)otElement).getTeam();

+			}

+			

+			return enclosingTeam;

+		}

+

+		/**

+		 * Checks if the given type is implemented in its own file as a top level type.

+		 * @param roleType to be checked

+		 * @return <code>true</code> if the role is implemented in its own file.

+		 */

+		private boolean isRoleFile(IType roleType) {

+			String name = JavaCore.removeJavaLikeExtension(roleType.getCompilationUnit().getElementName());

+			if (!(Checks.isTopLevel(roleType) && name.equals(roleType.getElementName())))

+				return false;

+			return true;

+		}

+

+		private IPackageFragment getRoleDirectoryForTeam(IType enclosingTeam) throws JavaModelException{

+			// role directories can only be present for teams that are top level elements

+			if(!Checks.isTopLevel(enclosingTeam)){

+				return null;

+			}

+			

+			// search for role directory

+			IPackageFragment  fragment = enclosingTeam.getPackageFragment();

+			if(fragment.hasSubpackages()){

+				IJavaElement[] packages= ((IPackageFragmentRoot)fragment.getParent()).getChildren();

+				for (int i = 0; i < packages.length; i++) {

+					String name = packages[i].getElementName();

+					String fragmentName = fragment.getElementName();

+					// role directory found

+					if(name.equals(fragmentName + "." + enclosingTeam.getElementName())){

+						return (IPackageFragment)packages[i];

+					}

+				}

+			}

+			// no role directory found

+			return null;

+		}

+

+		/**

+		 * Searches all types within the given package, including binary and source declarations.

+		 * 

+		 * @param pack the package fragment to search in

+		 * @return the found types

+		 */

+		private IType[] getAllTypesInPackage(IPackageFragment pack) throws JavaModelException{

+			IJavaElement[] children = pack.getChildren();

+			

+			ArrayList<IType> types = new ArrayList<IType>();

+			for(int i = 0; i < children.length; i++){

+				IJavaElement child = children[i];

+				

+				if(child instanceof IClassFile){

+					types.add(((IClassFile)child).getType());

+				}

+				

+				if(child instanceof ICompilationUnit){

+					types.addAll(Arrays.asList(((ICompilationUnit)child).getTypes()));

+				}

+			}

+			return types.toArray(new IType[types.size()]);

+		}

+

+		/**

+		 * Searches recursively all roles in a team.

+		 */

+		private IType[] getAllRoles(IType enclosingTeam) throws JavaModelException{

+			if(Flags.isTeam(enclosingTeam.getFlags())){

+				ArrayList<IType> result = new ArrayList<IType>();

+				ArrayList<IType> roles = new ArrayList<IType>();

+				roles.addAll(Arrays.asList(TypeHelper.getAllRoleTypes(enclosingTeam)));

+				for (Iterator<IType> iterator = roles.iterator(); iterator.hasNext();) {

+					IType roleType = (IType) iterator.next();

+					result.addAll(Arrays.asList(getAllRoles(roleType)));

+				}

+				result.addAll(roles);

+				return result.toArray(new IType[result.size()]);

+			}else{

+				return new IType[0];

+			}

+		}

+		

+		/**

+		 * Finds all declared roles for the given team, including inline and external role file declarations.

+		 * 

+		 * @param teamType the team to search in

+		 * @return the found roles

+		 */

+		private IType[] getDeclaredRoles(IType teamType) throws JavaModelException{

+			if(!TypeHelper.isTeam(teamType.getFlags())){

+				return new IType[0];

+			}

+			

+			ArrayList<IType> allRoles = new ArrayList<IType>();

+			IOTType otElement = OTModelManager.getOTElement(teamType);

+			// add inline declared roles

+			allRoles.addAll(Arrays.asList(otElement.getInnerTypes()));

+			// add the found role files

+			allRoles.addAll(Arrays.asList(getRoleFilesForTeam(teamType)));

+			

+			return allRoles.toArray(new IType[allRoles.size()]);

+		}

+		

+		/**

+		 * Finds all role file types for the given teamType.

+		 * 

+		 * @param teamType the team

+		 * @return all found role file types

+		 */

+		private IType[] getRoleFilesForTeam(IType teamType) throws JavaModelException{

+			IPackageFragment roleDirectory = getRoleDirectoryForTeam(teamType);

+			IType[] roleFileTypes = new IType[0];

+			if(roleDirectory != null){

+				roleFileTypes = getAllTypesInPackage(roleDirectory);

+			}

+			return roleFileTypes;

+		}

+	}

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ReorgAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ReorgAdaptor.java
new file mode 100644
index 0000000..9bb230a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ReorgAdaptor.java
@@ -0,0 +1,199 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2007 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: CallinMappingDeclaration.java 16313 2007-09-22 19:32:10Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.ISourceReference;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.AbstractMethodMappingDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.CallinMappingDeclaration;
+import org.eclipse.jdt.core.dom.CalloutMappingDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
+import org.eclipse.objectteams.otdt.core.ICallinMapping;
+import org.eclipse.objectteams.otdt.core.ICalloutMapping;
+import org.eclipse.objectteams.otdt.core.ICalloutToFieldMapping;
+import org.eclipse.objectteams.otdt.core.IOTJavaElement;
+import org.eclipse.objectteams.otdt.core.IOTType;
+import org.eclipse.objectteams.otdt.internal.refactoring.corext.OTRefactoringCoreMessages;
+
+import base org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgPolicyFactory.SubCuElementReorgPolicy;
+import base org.eclipse.jdt.internal.corext.refactoring.reorg.ReadOnlyResourceFinder;
+import base org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
+import base org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
+
+/**
+ * The team adapts classes from corext.refactoring.{reorg,structure}.
+ * See also the role file OTASTNodeSearchUtil, which belongs to this team
+ * in order to facilitate access to state role methods.
+ * 
+ * @author stephan
+ *
+ */
+@SuppressWarnings({ "restriction", "decapsulation" })
+public team class ReorgAdaptor 
+{
+	protected class SubCuElementReorgPolicy playedBy SubCuElementReorgPolicy 
+	{
+		
+		// ========= Callouts: =========
+		abstract void copyMemberToDestination(IMember member, CompilationUnitRewrite targetRewriter, CompilationUnit sourceCuNode, CompilationUnit targetCuNode, BodyDeclaration newMember) 
+				throws JavaModelException;
+		copyMemberToDestination -> copyMemberToDestination;
+		
+		abstract static String getUnindentedSource(ISourceReference sourceReference) 
+				throws JavaModelException;
+		getUnindentedSource -> getUnindentedSource;
+
+		IJavaElement getJavaElementDestination() -> IJavaElement getJavaElementDestination();
+
+		// ======== Overrides =========
+		
+		// this callin dispatches on the element being moved:
+		copyToDestination <- replace copyToDestination;
+		@SuppressWarnings("basecall")
+		callin void copyToDestination(IJavaElement element, CompilationUnitRewrite targetRewriter, CompilationUnit sourceCuNode, CompilationUnit targetCuNode) 
+			throws CoreException 
+		{
+			AbstractMethodMappingDeclaration newMapping= null;
+			IMember mapping= null;
+			switch(element.getElementType()){
+			// treat OT java model elements					
+			case IOTJavaElement.CALLIN_MAPPING:
+				mapping= (IMember)element;
+				newMapping= (CallinMappingDeclaration)targetRewriter.getASTRewrite().createStringPlaceholder(getUnindentedSource(mapping), ASTNode.CALLIN_MAPPING_DECLARATION);					
+				break;
+			case IOTJavaElement.CALLOUT_MAPPING:
+				mapping= (IMember)element;
+				newMapping= (CalloutMappingDeclaration)targetRewriter.getASTRewrite().createStringPlaceholder(getUnindentedSource(mapping), ASTNode.CALLOUT_MAPPING_DECLARATION);
+				break;
+			case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
+				mapping= (IMember)element;
+				newMapping= (CalloutMappingDeclaration)targetRewriter.getASTRewrite().createStringPlaceholder(getUnindentedSource(mapping), ASTNode.CALLOUT_MAPPING_DECLARATION);
+				break;
+			case IOTJavaElement.TEAM:
+			case IOTJavaElement.ROLE:
+				element= ((IOTType)element).getCorrespondingJavaElement();
+				// fall through with real java element
+			default:
+				base.copyToDestination(element, targetRewriter, sourceCuNode, targetCuNode);
+				return;
+			}
+			// callout which is again callin-intercepted:
+			copyMemberToDestination(mapping, targetRewriter, sourceCuNode, targetCuNode, newMapping);
+		}
+		
+		// this callin dispatches on the DnD-target:
+		getDestinationNode <- replace getDestinationNode;
+		@SuppressWarnings("basecall")
+		callin ASTNode getDestinationNode(IJavaElement destination, CompilationUnit target) 
+				throws JavaModelException 
+		{
+			switch (destination.getElementType()) {
+				case IOTJavaElement.CALLIN_MAPPING:
+					return OTASTNodeSearchUtil.getCallinMappingDeclarationNode((ICallinMapping)destination, target);
+				case IOTJavaElement.CALLOUT_MAPPING:
+					return OTASTNodeSearchUtil.getCalloutMappingDeclarationNode((ICalloutMapping)destination, target);
+				case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
+					return OTASTNodeSearchUtil.getCalloutToFieldMappingDeclarationNode((ICalloutToFieldMapping)destination, target);
+				case IOTJavaElement.TEAM:
+				case IOTJavaElement.ROLE:
+					destination = (((IOTType)destination).getCorrespondingJavaElement());
+					// fall through with real java element
+				default:
+					return base.getDestinationNode(destination, target);
+			}
+		}
+	}
+	
+	protected class ReadOnlyResourceFinder playedBy ReadOnlyResourceFinder 
+	{
+		@SuppressWarnings("basecall")
+		static callin boolean hasReadOnlyResourcesAndSubResources(IJavaElement javaElement)
+			throws CoreException 
+		{
+			switch(javaElement.getElementType()){
+			// consider OT-specific elements
+			case IOTJavaElement.TEAM:
+			case IOTJavaElement.ROLE:
+			case IOTJavaElement.CALLIN_MAPPING:
+			case IOTJavaElement.CALLOUT_MAPPING:
+			case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
+				return false;
+			default:
+				return base.hasReadOnlyResourcesAndSubResources(javaElement);
+			}
+		}
+		boolean hasReadOnlyResourcesAndSubResources(IJavaElement javaElement)
+			<- replace boolean hasReadOnlyResourcesAndSubResources(IJavaElement javaElement);
+	}
+	
+	final static int[] OT_MEMBERS = new int[]{IOTJavaElement.CALLIN_MAPPING, IOTJavaElement.CALLOUT_MAPPING, IOTJavaElement.CALLOUT_TO_FIELD_MAPPING};
+	
+	/** Patch a few hard coded switch statements in ReorgUtils. */
+	protected class ReorgUtils playedBy ReorgUtils {
+
+		boolean hasOnlyExpectedOrOTTypes(int[] types) <- replace boolean hasOnlyElementsOfType(IJavaElement[] javaElements, int[] types)
+			with { types <- types }
+		static callin boolean hasOnlyExpectedOrOTTypes(int[] types) {
+			// pseudo switch: base uses set comparison.
+			if (types[0] == IJavaElement.FIELD) {
+				// when expecting fields also accept ot members:
+				int l= types.length;
+				int[] newTypes = new int[l+OT_MEMBERS.length];
+				System.arraycopy(types, 0, newTypes, 0, l);
+				System.arraycopy(OT_MEMBERS, 0, newTypes, l, OT_MEMBERS.length);
+				return base.hasOnlyExpectedOrOTTypes(newTypes);
+			}
+			return base.hasOnlyExpectedOrOTTypes(types);
+		}
+
+		
+		String createNamePattern(IJavaElement element) 
+			<- replace String createNamePattern(IJavaElement element);
+		@SuppressWarnings("basecall")
+		static callin String createNamePattern(IJavaElement element)
+			throws JavaModelException
+		{
+			switch (element.getElementType()) {
+			case IOTJavaElement.TEAM:
+				return OTRefactoringCoreMessages.getString("ReorgUtils.21"); //$NON-NLS-1$
+			case IOTJavaElement.ROLE:
+				return OTRefactoringCoreMessages.getString("ReorgUtils.23"); //$NON-NLS-1$
+			case IOTJavaElement.CALLOUT_MAPPING:
+				return OTRefactoringCoreMessages.getString("ReorgUtils.24"); //$NON-NLS-1$
+			case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
+				return OTRefactoringCoreMessages.getString("ReorgUtils.25"); //$NON-NLS-1$
+			case IOTJavaElement.CALLIN_MAPPING:
+				return OTRefactoringCoreMessages.getString("ReorgUtils.26"); //$NON-NLS-1$
+			default:
+				return base.createNamePattern(element); 
+			}
+		}		
+
+		// createNameArguments now uses JavaElementLabels.getElementLabel()
+		// nothing to adapt in ReorgUtils.
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ReorgAdaptor/OTASTNodeSearchUtil.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ReorgAdaptor/OTASTNodeSearchUtil.java
new file mode 100644
index 0000000..cdef086
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/ReorgAdaptor/OTASTNodeSearchUtil.java
@@ -0,0 +1,113 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2005, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: OTASTNodeSearchUtil.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+team package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ReorgAdaptor;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CallinMappingDeclaration;
+import org.eclipse.jdt.core.dom.CalloutMappingDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.RoleTypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.objectteams.otdt.core.ICallinMapping;
+import org.eclipse.objectteams.otdt.core.ICalloutMapping;
+import org.eclipse.objectteams.otdt.core.ICalloutToFieldMapping;
+import org.eclipse.objectteams.otdt.core.IOTJavaElement;
+import org.eclipse.objectteams.otdt.core.TypeHelper;
+
+/**
+ * @author stephan
+ *
+ */
+@SuppressWarnings("restriction")
+public class OTASTNodeSearchUtil  playedBy ASTNodeSearchUtil 
+{
+	@SuppressWarnings("basecall")
+	static callin ASTNode[] getDeclarationNodes(IJavaElement element, CompilationUnit cuNode) 
+		throws JavaModelException 
+	{
+		switch(element.getElementType()){
+		// consider OT-specific elements
+        case IOTJavaElement.TEAM:
+            return new ASTNode[] { getTypeDeclarationNode((IType)element, cuNode) };
+        case IOTJavaElement.ROLE:
+            IType roleType = (IType)element;
+            if (TypeHelper.isTeam(roleType.getFlags()))
+                return new ASTNode[] { getTypeDeclarationNode((IType)element, cuNode) };
+            return new ASTNode[] { getRoleTypeDeclarationNode((IType)element, cuNode) };
+        case IOTJavaElement.CALLOUT_MAPPING:
+            return new ASTNode[] { getCalloutMappingDeclarationNode((ICalloutMapping)element, cuNode) };
+        case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
+            return new ASTNode[] { getCalloutToFieldMappingDeclarationNode((ICalloutToFieldMapping)element, cuNode) };        
+        case IOTJavaElement.CALLIN_MAPPING:
+            return new ASTNode[] { getCallinMappingDeclarationNode((ICallinMapping)element, cuNode) };
+        default:
+        	return base.getDeclarationNodes(element, cuNode);
+		}
+	}
+	getDeclarationNodes <- replace getDeclarationNodes;
+	
+	// === get OT-specific node types
+    static ASTNode getRoleTypeDeclarationNode(
+            IType type,
+            CompilationUnit cuNode) throws JavaModelException
+    {
+        return ASTNodes.getParent(getNameNode(type, cuNode), RoleTypeDeclaration.class);
+    }
+    protected static ASTNode getCalloutMappingDeclarationNode(
+            ICalloutMapping calloutMapping,
+            CompilationUnit cuNode) throws JavaModelException
+    {
+        ASTNode nameNode = getNameNode(calloutMapping, cuNode);
+        if (nameNode.getNodeType() == ASTNode.CALLOUT_MAPPING_DECLARATION)
+        	return nameNode; // short mapping: nameRange is the whole mapping
+		return ASTNodes.getParent(nameNode, CalloutMappingDeclaration.class);
+    }
+    protected static ASTNode getCalloutToFieldMappingDeclarationNode(
+            ICalloutToFieldMapping calloutToFieldMapping,
+            CompilationUnit cuNode) throws JavaModelException
+    {
+        ASTNode nameNode = getNameNode(calloutToFieldMapping, cuNode);
+        if (nameNode.getNodeType() == ASTNode.CALLOUT_MAPPING_DECLARATION)
+			return nameNode; // short mapping: nameRange is the whole mapping
+        return ASTNodes.getParent(nameNode, CalloutMappingDeclaration.class);
+    }
+    protected static ASTNode getCallinMappingDeclarationNode(
+            ICallinMapping callinMapping,
+            CompilationUnit cuNode) throws JavaModelException
+    {
+        ASTNode nameNode = getNameNode(callinMapping, cuNode);
+        if (nameNode.getNodeType() == ASTNode.CALLIN_MAPPING_DECLARATION)
+        	return nameNode; // short mapping: nameRange is the whole mapping
+		return ASTNodes.getParent(nameNode, CallinMappingDeclaration.class);
+    }
+    
+    abstract static ASTNode getNameNode(IMember iMember, CompilationUnit cuNode) throws JavaModelException;
+    @SuppressWarnings("decapsulation")
+	getNameNode -> getNameNode;
+	
+	abstract static TypeDeclaration getTypeDeclarationNode(IType iType, CompilationUnit cuNode) throws JavaModelException;
+	getTypeDeclarationNode -> getTypeDeclarationNode;
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/extractmethod/ExtractMethodAmbuguityMsgCreator.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/extractmethod/ExtractMethodAmbuguityMsgCreator.java
new file mode 100644
index 0000000..44b6c71
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/extractmethod/ExtractMethodAmbuguityMsgCreator.java
@@ -0,0 +1,17 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod;

+

+import org.eclipse.objectteams.otdt.internal.refactoring.corext.OTRefactoringCoreMessages;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator;

+

+public class ExtractMethodAmbuguityMsgCreator implements IAmbuguityMessageCreator {

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator#createAmbiguousMethodSpecifierMsg()

+	 */

+	public String createAmbiguousMethodSpecifierMsg() {

+		return OTRefactoringCoreMessages.getString("OTExtractMethodRefactoring.ambiguous_method_specifier"); //$NON-NLS-1$

+	}

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/extractmethod/ExtractMethodOverloadingMsgCreator.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/extractmethod/ExtractMethodOverloadingMsgCreator.java
new file mode 100644
index 0000000..8b29413
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/extractmethod/ExtractMethodOverloadingMsgCreator.java
@@ -0,0 +1,17 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod;

+

+import org.eclipse.objectteams.otdt.internal.refactoring.corext.OTRefactoringCoreMessages;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IOverloadingMessageCreator;

+

+public class ExtractMethodOverloadingMsgCreator implements IOverloadingMessageCreator {

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.objectteams.otdt.refactoring.util.IOverloadingMessageCreator#createOverloadingMessage()

+	 */

+	public String createOverloadingMessage() {

+		return OTRefactoringCoreMessages.getString("OTExtractMethodRefactoring.overloading"); //$NON-NLS-1$

+	}

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/OTTypeHierarchyAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/OTTypeHierarchyAdaptor.java
new file mode 100644
index 0000000..08637a7
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/OTTypeHierarchyAdaptor.java
@@ -0,0 +1,35 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup;

+

+import org.eclipse.jdt.core.IType;

+

+import base org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;

+

+/**

+ * @author Johannes Gebauer

+ * 

+ *         This team is by default deactivated. It can be activated to suppress

+ *         the <code>UnsupportedOperationException</code> on

+ *         {@link OTTypeHierarchy#getSuperclass(IType)}. The adaptor is useful

+ *         to reuse jdt functionality that is not aware of multiple

+ *         superclasses.

+ */

+@SuppressWarnings("restriction")

+public team class OTTypeHierarchyAdaptor {

+

+	/**

+	 * Prevents {@link OTTypeHierarchy#getSuperclass(IType)} calls on

+	 * OTTypeHierarchies to avoid an <code>UnsupportedOperationException</code>.

+	 */

+	public class OTTypeHierarchyRole playedBy OTTypeHierarchy {

+		IType getExplicitSuperclass(IType type) -> IType getExplicitSuperclass(IType type);

+

+		@SuppressWarnings("basecall")

+		callin IType getSuperclass(IType type) {

+			return this.getExplicitSuperclass(type);

+		}

+

+		getSuperclass <- replace getSuperclass;

+

+	}

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java
new file mode 100644
index 0000000..dc25779
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java
@@ -0,0 +1,548 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup;

+

+import java.text.MessageFormat;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collections;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.NullProgressMonitor;

+import org.eclipse.core.runtime.SubProgressMonitor;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.IField;

+import org.eclipse.jdt.core.IMember;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.ITypeHierarchy;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.core.dom.IMethodBinding;

+import org.eclipse.jdt.core.dom.MethodDeclaration;

+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

+import org.eclipse.jdt.core.search.IJavaSearchConstants;

+import org.eclipse.jdt.core.search.IJavaSearchScope;

+import org.eclipse.jdt.core.search.MethodDeclarationMatch;

+import org.eclipse.jdt.core.search.SearchEngine;

+import org.eclipse.jdt.core.search.SearchMatch;

+import org.eclipse.jdt.core.search.SearchParticipant;

+import org.eclipse.jdt.core.search.SearchPattern;

+import org.eclipse.jdt.core.search.SearchRequestor;

+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;

+import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;

+import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;

+import org.eclipse.jdt.internal.corext.refactoring.structure.TypeVariableMaplet;

+import org.eclipse.jdt.internal.corext.util.Messages;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;

+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+import org.eclipse.objectteams.otdt.core.ICalloutMapping;

+import org.eclipse.objectteams.otdt.core.ICalloutToFieldMapping;

+import org.eclipse.objectteams.otdt.core.IMethodMapping;

+import org.eclipse.objectteams.otdt.core.IOTType;

+import org.eclipse.objectteams.otdt.core.IOTTypeHierarchy;

+import org.eclipse.objectteams.otdt.core.OTModelManager;

+import org.eclipse.objectteams.otdt.core.TypeHelper;

+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;

+import org.eclipse.objectteams.otdt.internal.core.RoleType;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IOverloadingMessageCreator;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

+

+import base org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor;

+import base org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor.PullUpAstNodeMapper;

+import base org.eclipse.jdt.internal.ui.refactoring.PullUpMethodPage;

+import base org.eclipse.jdt.internal.ui.refactoring.PullUpMethodPage.PullUpHierarchyContentProvider;

+
+/**

+ * @author Johannes Gebauer

+ * 

+ */

+@SuppressWarnings({ "restriction", "decapsulation" }) // private base classes

+public team class PullUpAdaptor {

+

+	public team class PullUpRefactoringProcessorRole playedBy PullUpRefactoringProcessor {

+		

+		@SuppressWarnings("rawtypes")

+		void setFCachedSkippedSuperTypes(Set fCachedSkippedSuperTypes) -> set Set fCachedSkippedSuperTypes;

+		@SuppressWarnings("rawtypes")

+		Set getFCachedSkippedSuperTypes() -> get Set fCachedSkippedSuperTypes;

+		IMember[] getMembersToDelete(IProgressMonitor monitor) -> IMember[] getMembersToDelete(IProgressMonitor monitor);

+		IMethod[] getFDeletedMethods() -> get IMethod[] fDeletedMethods;

+		IMember[] getFMembersToMove() -> get IMember[] fMembersToMove;

+

+		/**

+		 * Pure Gateway.

+		 */

+		public class PullUpAstNodeMapper playedBy PullUpAstNodeMapper{

+			@SuppressWarnings("decapsulation")

+			protected PullUpAstNodeMapper(final CompilationUnitRewrite sourceRewriter, final CompilationUnitRewrite targetRewriter, final ASTRewrite rewrite, final IType type, final TypeVariableMaplet[] mapping, final IMethodBinding enclosing) {

+				base(sourceRewriter, targetRewriter,

+						rewrite, type, mapping,

+						enclosing);

+			}

+		}

+		

+		private ITypeHierarchy _destinationOTTypeHierachy;

+

+		// callouts

+		IType getDestinationType() -> IType getDestinationType();

+		IMember[] getMembersToMove() -> IMember[] getMembersToMove();

+		IType getDeclaringType() -> IType getDeclaringType();

+		ITypeHierarchy getDestinationTypeHierarchy(IProgressMonitor pm) -> ITypeHierarchy getDestinationTypeHierarchy(IProgressMonitor pm);

+		

+		private void checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context, RefactoringStatus status) throws CoreException {

+			

+			status.merge(checkForAspectBindings(pm));

+			status.merge(checkOverloadingAndAmbiguity(pm));

+			status.merge(checkOverriding(pm));

+			if(TypeHelper.isRole(getDeclaringType().getFlags())){

+				status.merge(checkDestinationForOTElements());

+				status.merge(checkShadowingFieldInImplicitHierarchy(pm));

+			}

+		}

+		

+		void checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm,

+				CheckConditionsContext context) with {

+			pm <- pm,

+			context <- context,

+			status <- result

+		}

+

+		private RefactoringStatus checkShadowingFieldInImplicitHierarchy(IProgressMonitor pm) throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			if(!TypeHelper.isRole(getDestinationType().getFlags())){

+				return status;

+			}

+			

+			OTTypeHierarchy hier = (OTTypeHierarchy)getDestinationTypeHierarchy(pm);

+			ArrayList<IType> implicitSubRoles = new ArrayList<IType>();

+			implicitSubRoles.addAll(Arrays.asList(hier.getAllTSubtypes(getDestinationType())));

+			

+			// remove the subtypes of the declaring type

+			implicitSubRoles.removeAll(Arrays.asList(hier.getAllTSubtypes(getDeclaringType())));

+			

+			pm.beginTask("Checking Shadowing", implicitSubRoles.size());

+			pm.subTask(""); //$NON-NLS-1$

+			

+			for (int i = 0; i < getFMembersToMove().length; i++) {

+				IMember element = getFMembersToMove()[i];

+				if(element instanceof IField){

+					IField field = (IField) element;

+					for (IType type : implicitSubRoles) {

+						IField shadowingField = RefactoringUtil.fieldIsShadowedInType(field.getElementName(), field.getTypeSignature(), type);

+						if(shadowingField != null){

+							

+							ArrayList<IMember> membersToDelete = new ArrayList<IMember>();

+							membersToDelete.addAll(Arrays.asList(getMembersToDelete(pm)));

+							// do not indicate shadowing by deleted fields as an error

+							if(!membersToDelete.contains(shadowingField)) {

+								String msg = Messages.format("The pulled up field ''{0}'' would be shadowed in ''{1}''.", new String[] { field.getElementName(),

+										type.getFullyQualifiedName('.') });

+								status.addFatalError(msg, JavaStatusContext.create(shadowingField));

+							}

+							

+						}

+						pm.worked(1);

+						// do not repeat errors in hierarchy

+						if(status.hasFatalError()){

+							pm.done();

+							return status;

+						}

+					}

+				}

+			}

+			pm.done();

+			return status;

+			

+		}

+		

+		private RefactoringStatus checkDestinationForOTElements() throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			for (int i = 0; i < getFMembersToMove().length; i++) {

+				IMember element = getFMembersToMove()[i];

+				if (element instanceof IMethod){

+					IMethod method = (IMethod)element;

+					// callin methods can only be moved to roles

+					if(Flags.isCallin(method.getFlags()) && !TypeHelper.isRole(getDestinationType().getFlags())){

+						String msg = Messages.format("The callin method ''{0}'' can only be moved to a role (OTJLD �4.2.(d)).", new String[] { method.getElementName() });

+						status.addFatalError(msg, JavaStatusContext.create(method));

+					}

+				}

+			}

+			return status;

+		}

+		

+		private RefactoringStatus checkOverloadingAndAmbiguityInType(IProgressMonitor pm, IType type) throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			ITypeHierarchy hier = getDestinationTypeHierarchy(pm);

+			for (int i = 0; i < getFMembersToMove().length; i++) {

+				IMember element = getFMembersToMove()[i];

+				if (element instanceof IMethod){

+					final IMethod method = (IMethod)element;

+					String[] paramTypes = method.getParameterTypes();

+					status.merge(RefactoringUtil.checkOverloadingAndAmbiguity(type, hier, method.getElementName(), paramTypes,

+							new IAmbuguityMessageCreator() {

+

+						public String createAmbiguousMethodSpecifierMsg() {

+							return "Refactoring cannot be performed! There would be an ambiguous method specifier in a method binding after moving!";

+						}

+

+					}, new IOverloadingMessageCreator() {

+

+						public String createOverloadingMessage() {

+							String msg = Messages.format("The pulled up method ''{0}'' would be overloaded after refactoring.", new String[] { method.getElementName()});

+							return msg;

+						}

+

+					}, pm));

+				}

+			}

+			return status;

+		}

+		

+		private RefactoringStatus checkOverloadingAndAmbiguity(IProgressMonitor pm) throws JavaModelException {

+			

+			ITypeHierarchy destinationTypeHierarchy = getDestinationTypeHierarchy(pm);

+			IType[] subtypes = destinationTypeHierarchy.getAllSubtypes(getDestinationType());

+			

+			pm.beginTask("Checking Overloading", subtypes.length + 1);

+			pm.subTask(""); //$NON-NLS-1$

+			

+			RefactoringStatus status = new RefactoringStatus();

+			

+			// check overloading in destination type

+			status.merge(checkOverloadingAndAmbiguityInType(pm, getDestinationType()));

+			

+			pm.worked(1);

+			

+			// do not repeat errors in hierarchy

+			if(status.hasFatalError()){

+				pm.done();

+				return status;

+			}

+			

+			// check overloading in subtypes of the destination type

+			for (int i = 0; i < subtypes.length; i++) {

+				status.merge(checkOverloadingAndAmbiguityInType(pm, subtypes[i]));

+				

+				pm.worked(1);

+				

+				// do not repeat errors in hierarchy

+				if(status.hasFatalError()){

+					pm.done();

+					return status;

+				}

+			}

+			pm.done();

+			return status;

+		}

+		

+		private RefactoringStatus checkOverriding(IProgressMonitor pm) throws JavaModelException{

+			RefactoringStatus status = new RefactoringStatus();

+			

+			ITypeHierarchy hier = getDestinationTypeHierarchy(pm);

+			ArrayList<IType> allSubTypes = new ArrayList<IType>();

+			allSubTypes.addAll(Arrays.asList(hier.getAllSubtypes(getDestinationType())));

+			

+			// remove the subtypes of the declaring type

+			allSubTypes.removeAll(Arrays.asList(hier.getAllSubtypes(getDeclaringType())));

+			

+			pm.beginTask("Checking Overriding", allSubTypes.size());

+			pm.subTask(""); //$NON-NLS-1$

+			

+			for (int i = 0; i < getFMembersToMove().length; i++) {

+				IMember element = getFMembersToMove()[i];

+				if(element instanceof IMethod){

+					IMethod method = (IMethod) element;

+					for (IType type : allSubTypes) {

+						IMethod overridingMethod = methodIsOverriddenInType(method.getElementName(), method.getParameterTypes(), type);

+						if(overridingMethod != null){

+							

+							ArrayList<IMember> membersToMove = new ArrayList<IMember>();

+							membersToMove.addAll(Arrays.asList(getMembersToMove()));

+							ArrayList<IMember> membersToDelete = new ArrayList<IMember>();

+							membersToDelete.addAll(Arrays.asList(getMembersToDelete(pm)));

+							// do not indicate overriding for deleted/moved methods as an error

+							if(!membersToMove.contains(overridingMethod) && !membersToDelete.contains(overridingMethod)) {

+								String msg = Messages.format("The pulled up method ''{0}'' would be overridden in ''{1}''.", new String[] { method.getElementName(),

+										type.getFullyQualifiedName('.') });

+								status.addError(msg, JavaStatusContext.create(overridingMethod));

+							}

+							

+						}

+						pm.worked(1);

+						// do not repeat errors in hierarchy

+						if(status.hasError()){

+							pm.done();

+							return status;

+						}

+					}

+				}

+			}

+			pm.done();

+			return status;

+		}

+		

+		private IMethod methodIsOverriddenInType(String methodName, String[] paramTypes, IType type){

+			IMethod method = type.getMethod(methodName, paramTypes);

+			if(method.exists()){

+				return method;

+			}

+			return null;

+		}

+		

+		

+		/**

+		 * Searches for aspect bindings that reference members to be moved.

+		 * @return The refactoring status contains warnings if any referencing aspect bindings exist.

+		 */

+		private RefactoringStatus checkForAspectBindings(IProgressMonitor monitor) throws CoreException {

+			// search all references for the members to be moved

+			IMember[] membersToMove = getMembersToMove();

+			final HashMap<IMember,Set<SearchMatch>> references= new HashMap<IMember,Set<SearchMatch>>();

+			IJavaSearchScope scope= SearchEngine.createWorkspaceScope();

+			for (int i = 0; i < membersToMove.length; i++) {

+				final IMember member = membersToMove[i];

+				// may not be able to access return type, but IGNORE_RETURN_TYPE is only effective with ALL_OCCURRENCES:

+				int limitTo = IJavaSearchConstants.ALL_OCCURRENCES|IJavaSearchConstants.IGNORE_RETURN_TYPE;

+				SearchPattern pattern= SearchPattern.createPattern(member, limitTo, SearchPattern.R_EXACT_MATCH);

+				SearchEngine engine= new SearchEngine();

+				engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant()}, scope, new SearchRequestor() {

+					public void acceptSearchMatch(SearchMatch match) throws CoreException {

+						if (   match.getAccuracy() == SearchMatch.A_ACCURATE

+							&& !match.isInsideDocComment()

+							&& !(match instanceof MethodDeclarationMatch)) // limit to references despite ALL_OCCURRENCES above:

+						{

+							if(references.get(member) == null){

+								Set<SearchMatch> refSet = new HashSet<SearchMatch>();

+								refSet.add(match);

+								references.put(member, refSet);

+							}else{

+								references.get(member).add(match);

+							}

+						}

+					}

+				}, monitor);

+			}

+			

+			// search the matches for aspect bindings

+			RefactoringStatus status = new RefactoringStatus();

+			for (int i = 0; i < membersToMove.length; i++) {

+				IMember member = membersToMove[i];

+				Set<SearchMatch> refSet = references.get(member);

+				if(refSet == null){

+					continue;

+				}

+				for (SearchMatch match : refSet) {

+					Object element= match.getElement();

+					if (element instanceof ICalloutMapping) {

+						ICalloutMapping mapping = (ICalloutMapping) element;

+						if(mapping.getBoundBaseMethod().equals(member)){

+							addAspectBindingWarning(member, status, mapping);

+						}

+					}

+					if (element instanceof ICalloutToFieldMapping) {

+						ICalloutToFieldMapping mapping = (ICalloutToFieldMapping) element;

+						if(mapping.getBoundBaseField().equals(member)){

+							addAspectBindingWarning(member, status, mapping);

+						}

+					}

+					if (element instanceof ICallinMapping) {

+						ICallinMapping mapping = (ICallinMapping) element;

+						for (int j = 0; j < mapping.getBoundBaseMethods().length; j++) {

+							if(mapping.getBoundBaseMethods()[i].equals(member)){

+								addAspectBindingWarning(member, status, mapping);

+								break;

+							}

+						}

+					}	

+				}

+			}

+			return status;

+		}

+		

+		/**

+		 * Adds a warning to the given refactoring status that notifies the user about existing aspect bingings.

+		 * 

+		 * @param member the member to be pulled up.

+		 * @param status the refactoring status, where the warning should be added.

+		 * @param mapping the method mapping that causes the warning.

+		 */

+		private void addAspectBindingWarning(IMember member, RefactoringStatus status,IMethodMapping mapping){

+			status.addEntry(new RefactoringStatusEntry(RefactoringStatus.WARNING,

+					MessageFormat.format("Pulled up member ''{0}'' is referenced in an aspect binding by ''{1}''",

+							new Object[]{member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName()})));

+		

+		}

+		

+		/**

+		 * Adds implicit role super types for roles. Candidate types are the possible super types,

+		 * that are available as the destination type.

+		 */

+		callin IType[] getCandidateTypes(final RefactoringStatus status, final IProgressMonitor monitor) throws JavaModelException{

+			RefactoringStatus jdtStatus = new RefactoringStatus();

+			IType[] jdtCandidates = base.getCandidateTypes(jdtStatus, monitor);

+			final IType declaring= getDeclaringType();

+			// try to get the corresponding OTType that is represented in the declaring type

+			IOTType otType = OTModelManager.getOTElement(declaring);

+			if(otType != null && otType instanceof RoleType){

+				RoleType role = (RoleType) otType;

+				IType[] otSuperTypes = role.newOTTypeHierarchy(monitor).getAllSupertypes(declaring);

+				List<IType> list = new ArrayList<IType>();

+				int binary = 0;

+				for (int i = 0; i < otSuperTypes.length; i++) {

+					IType type = otSuperTypes[i];

+					if(OTModelManager.hasOTElementFor(otSuperTypes[i])){

+						IOTType otSuperType = OTModelManager.getOTElement(type);

+						if(otSuperType instanceof RoleType && type != null && type.exists() && !type.isReadOnly() && !type.isBinary()){

+							list.add(type);

+						}else if(type.isBinary()){

+							binary += 1;

+						}

+					}

+				}

+				if(!list.isEmpty()){

+					if(jdtStatus.hasFatalError()){

+						if (otSuperTypes.length == binary)

+							status.addFatalError(RefactoringCoreMessages.PullUPRefactoring_no_all_binary);

+					}else{

+						status.merge(jdtStatus);

+					}

+					Collections.reverse(list);

+					list.addAll(0,Arrays.asList(jdtCandidates));

+					return list.toArray(new IType[list.size()]);

+				}

+			}

+			status.merge(jdtStatus);

+			return jdtCandidates;

+		}

+

+		getCandidateTypes <- replace getCandidateTypes;

+		

+		

+		

+		/**

+		 * Prevents callin methods from visibility adjustments.

+		 */

+		callin boolean needsVisibilityAdjustment(final IMember member, final boolean references, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {

+			boolean result = base.needsVisibilityAdjustment(member, references, monitor, status);

+			if(Flags.isCallin(member.getFlags())){

+				return false;

+			}else{

+				return result;

+			}

+		}

+		

+		needsVisibilityAdjustment <- replace needsVisibilityAdjustment;

+			

+		/**

+		 * Replaces the jdt hierarchy with the ot hierarchy. 

+		 */

+		@SuppressWarnings("basecall")

+		callin ITypeHierarchy getDestinationOTTypeHierarchy() throws JavaModelException {

+					if(_destinationOTTypeHierachy != null && _destinationOTTypeHierachy.getType().equals(getDestinationType())){

+						return _destinationOTTypeHierachy;

+					}else{

+						if(OTModelManager.hasOTElementFor(getDestinationType())){

+							_destinationOTTypeHierachy = OTModelManager.getOTElement(getDestinationType()).newOTTypeHierarchy(new NullProgressMonitor());

+						}else{

+							_destinationOTTypeHierachy = base.getDestinationOTTypeHierarchy();

+						}

+						return _destinationOTTypeHierachy;

+					}

+		}

+		

+		getDestinationOTTypeHierarchy <- replace getDestinationTypeHierarchy;

+		

+		/**

+		 * Prevents {@link OTTypeHierarchy#getSuperclass(IType)} calls on OTTypeHierarchies to avoid an

+		 *  <code>UnsupportedOperationException</code>.

+		 */

+		callin void copyBodyOfPulledUpMethod(

+				final CompilationUnitRewrite sourceRewrite,

+				final CompilationUnitRewrite targetRewrite, final IMethod method,

+				final MethodDeclaration oldMethod,

+				final MethodDeclaration newMethod,

+				final TypeVariableMaplet[] mapping, final IProgressMonitor monitor)

+				throws JavaModelException {

+			within(new OTTypeHierarchyAdaptor()){

+				base.copyBodyOfPulledUpMethod(sourceRewrite, targetRewrite, method, oldMethod, newMethod, mapping, monitor);

+			}

+		}

+		copyBodyOfPulledUpMethod <- replace copyBodyOfPulledUpMethod;

+		

+		/**

+		 * Prevents {@link OTTypeHierarchy#getSuperclass(IType)} calls on OTTypeHierarchies to avoid an

+		 *  <code>UnsupportedOperationException</code>.

+		 */

+		@SuppressWarnings({"unchecked", "rawtypes" })

+		callin Set getSkippedSuperTypes(final IProgressMonitor monitor) throws JavaModelException {

+			if(Flags.isRole(getDestinationType().getFlags())){

+				// do not add implicit skipped super types twice

+				if (getFCachedSkippedSuperTypes() != null && getDestinationTypeHierarchy(new SubProgressMonitor(monitor, 1)).getType().equals(getDestinationType()))

+					return base.getSkippedSuperTypes(monitor);

+				

+				// calculate implicit skipped super types

+				final IOTTypeHierarchy otHierarchy = (IOTTypeHierarchy) getDestinationTypeHierarchy(new SubProgressMonitor(monitor, 1));

+				List<IType> subtypes = Arrays.asList(otHierarchy.getAllTSubtypes(getDestinationType()));

+				List<IType> superTypes = Arrays.asList(otHierarchy.getAllTSuperTypes(getDeclaringType()));

+				Set<IType> skippedImplicitTypes = new HashSet();

+				

+				// intersect super types and sub types

+				for (IType type : superTypes) {

+					if(subtypes.contains(type)){

+						skippedImplicitTypes.add(type);

+					}

+				}

+

+				within(new OTTypeHierarchyAdaptor()){

+					// calculate explicit skipped supoer types

+					base.getSkippedSuperTypes(monitor);

+					// add implicit skipped super types

+					getFCachedSkippedSuperTypes().addAll(skippedImplicitTypes);

+					return getFCachedSkippedSuperTypes();

+				}

+			}else{

+				within(new OTTypeHierarchyAdaptor()){

+					return base.getSkippedSuperTypes(monitor);

+				}

+			}

+		}

+		getSkippedSuperTypes <- replace getSkippedSuperTypes;

+	}

+	

+	public class PullUpHierarchyContentProvider playedBy PullUpHierarchyContentProvider{

+		/**

+		 * Prevents {@link OTTypeHierarchy#getSuperclass(IType)} calls on OTTypeHierarchies to avoid an

+		 *  <code>UnsupportedOperationException</code>.

+		 */

+		callin Object getParent(final Object element) {

+			within(new OTTypeHierarchyAdaptor()){	

+				return base.getParent(element);

+			}

+		}

+		getParent <- replace getParent;

+

+	}

+	

+	public class PullUpMethodPage playedBy PullUpMethodPage{

+		/**

+		 * Prevents {@link OTTypeHierarchy#getSuperclass(IType)} calls on OTTypeHierarchies to avoid an

+		 *  <code>UnsupportedOperationException</code>.

+		 */

+		callin void checkAllParents(final IType parent) {

+			within(new OTTypeHierarchyAdaptor()){				

+				base.checkAllParents(parent);

+			}

+		}

+		checkAllParents <- replace checkAllParents;

+

+	}

+}

+

+

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pushdown/PushDownAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pushdown/PushDownAdaptor.java
new file mode 100644
index 0000000..2f2bad2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pushdown/PushDownAdaptor.java
@@ -0,0 +1,408 @@
+/**

+ * 

+ */

+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pushdown;

+

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Set;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.IField;

+import org.eclipse.jdt.core.IMember;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.ITypeHierarchy;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.core.search.IJavaSearchConstants;

+import org.eclipse.jdt.core.search.IJavaSearchScope;

+import org.eclipse.jdt.core.search.SearchEngine;

+import org.eclipse.jdt.core.search.SearchMatch;

+import org.eclipse.jdt.core.search.SearchParticipant;

+import org.eclipse.jdt.core.search.SearchPattern;

+import org.eclipse.jdt.core.search.SearchRequestor;

+import org.eclipse.jdt.internal.core.ResolvedSourceMethod;

+import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;

+import org.eclipse.jdt.internal.corext.refactoring.structure.PushDownRefactoringProcessor.MemberActionInfo;

+import org.eclipse.jdt.internal.corext.util.Messages;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+import org.eclipse.objectteams.otdt.core.ICalloutMapping;

+import org.eclipse.objectteams.otdt.core.ICalloutToFieldMapping;

+import org.eclipse.objectteams.otdt.core.OTModelManager;

+import org.eclipse.objectteams.otdt.core.PhantomType;

+import org.eclipse.objectteams.otdt.core.TypeHelper;

+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IOverloadingMessageCreator;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

+

+import base org.eclipse.jdt.internal.corext.refactoring.structure.PushDownRefactoringProcessor;

+

+/**

+ * @author Johannes Gebauer

+ * 

+ */

+@SuppressWarnings("restriction")

+public team class PushDownAdaptor {

+	

+	@SuppressWarnings("decapsulation") // base class is final

+	protected class PushDownRefactoringProcessor playedBy PushDownRefactoringProcessor {

+		

+		MemberActionInfo[] getAbstractDeclarationInfos() -> MemberActionInfo[] getAbstractDeclarationInfos();

+		// callouts

+		IType[] getAbstractDestinations(IProgressMonitor arg0) -> IType[] getAbstractDestinations(IProgressMonitor arg0);

+		IMember[] getMembersToMove() -> IMember[] getMembersToMove();

+		IType getDeclaringType() -> IType getDeclaringType();

+		ITypeHierarchy getHierarchyOfDeclaringClass(IProgressMonitor pm) -> ITypeHierarchy getHierarchyOfDeclaringClass(IProgressMonitor pm);

+

+		private ITypeHierarchy fDeclaringTypeHierachy;

+		

+		private void checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context, RefactoringStatus status) throws CoreException {

+			

+			status.merge(checkForDirectPhantomSubRoles(pm));

+			status.merge(checkForAspectBindings(pm));

+			status.merge(checkShadowingFieldInImplicitHierarchy(pm));

+			IType[] subclasses = getAbstractDestinations(pm);

+			for (int i = 0; i < subclasses.length; i++) {

+				status.merge(checkOverriding(subclasses[i],pm));

+			}

+			status.merge(checkOverloadingAndAmbiguity(pm));

+		}

+		

+

+		void checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context, RefactoringStatus status) <- after RefactoringStatus checkFinalConditions(IProgressMonitor pm,

+				CheckConditionsContext context) with {

+			pm <- pm,

+			context <- context,

+			status <- result

+		}

+		

+		private RefactoringStatus checkShadowingFieldInImplicitHierarchy(IProgressMonitor pm) throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			

+			ITypeHierarchy hier = getHierarchyOfDeclaringClass(pm);

+			ArrayList<IType> subTypes = new ArrayList<IType>();

+			subTypes.addAll(Arrays.asList(hier.getSubtypes(getDeclaringType())));

+			

+			pm.beginTask("Checking Shadowing", subTypes.size());

+			pm.subTask(""); //$NON-NLS-1$

+			

+			for (int i = 0; i < getMembersToMove().length; i++) {

+				IMember element = getMembersToMove()[i];

+				if(element instanceof IField){

+					IField field = (IField) element;

+					for (IType type : subTypes) {

+						

+						// shadowing fields is just forbidden in implicit hierarchies

+						if(TypeHelper.isRole(type.getFlags())){

+							OTTypeHierarchy implicitHierarchy = new OTTypeHierarchy(type, type.getJavaProject(), false);

+							implicitHierarchy.refresh(pm);

+							IType[] implicitSuperTypes = implicitHierarchy.getAllTSuperTypes(type);

+							

+							for (int j = 0; j < implicitSuperTypes.length; j++) {

+								IType implicitSuperType = implicitSuperTypes[i];

+								IField shadowingField = RefactoringUtil.fieldIsShadowedInType(field.getElementName(), field.getTypeSignature(), implicitSuperType);

+								if(shadowingField != null){

+									

+									String msg = Messages.format("The pushed down field ''{0}'' would be shadowed in ''{1}''.", new String[] { field.getElementName(),

+											implicitSuperType.getFullyQualifiedName('.') });

+									status.addError(msg, JavaStatusContext.create(shadowingField));

+									

+								}

+							}

+						}

+						pm.worked(1);

+						// do not repeat errors in hierarchy

+						if(status.hasError()){

+							pm.done();

+							return status;

+						}

+					}

+				}

+			}

+			pm.done();

+			return status;

+			

+		}

+		

+		/**

+		 * Searches for aspect bindings that reference members to be moved.

+		 * @return The refactoring status contains errors if the pushed down members are not visible in existing bidnings after refactoring.

+		 */

+		@SuppressWarnings("restriction")

+		private RefactoringStatus checkForAspectBindings(IProgressMonitor monitor) throws CoreException {

+			// search all references for the members to be moved

+			IMember[] membersToMove = getMembersToMove();

+			final HashMap<IMember,Set<SearchMatch>> references= new HashMap<IMember,Set<SearchMatch>>();

+			IJavaSearchScope scope= SearchEngine.createWorkspaceScope();

+			for (int i = 0; i < membersToMove.length; i++) {

+				final IMember member = membersToMove[i];

+				SearchPattern pattern= SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchPattern.R_EXACT_MATCH);

+				SearchEngine engine= new SearchEngine();

+				engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant()}, scope, new SearchRequestor() {

+					public void acceptSearchMatch(SearchMatch match) throws CoreException {

+						if (match.getAccuracy() == SearchMatch.A_ACCURATE && !match.isInsideDocComment()){

+							if(references.get(member) == null){

+								Set<SearchMatch> refSet = new HashSet<SearchMatch>();

+								refSet.add(match);

+								references.put(member, refSet);

+							}else{

+								references.get(member).add(match);

+							}

+						}

+					}

+				}, monitor);

+			}

+			

+			// search the matches for aspect bindings

+			RefactoringStatus status = new RefactoringStatus();

+			for (int i = 0; i < membersToMove.length; i++) {

+				IMember member = membersToMove[i];

+				

+				// do not search for aspect bindings if an abstract declaration remains

+				if(leavesAbstractMethod(member)){

+					continue;

+				}

+				

+				Set<SearchMatch> refSet = references.get(member);

+				if(refSet == null){

+					continue;

+				}

+				for (SearchMatch match : refSet) {

+					Object element= match.getElement();

+					if (element instanceof ICalloutMapping) {

+						ICalloutMapping mapping = (ICalloutMapping) element;

+						if(mapping.getBoundBaseMethod().equals(member)){

+							String msg = Messages.format("The pushed down method ''{0}'' is referenced in a callout method binding in ''{1}'' and will not be visible after refactoring.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						} else if(mapping.getRoleMethod() != null && mapping.getRoleMethod().equals(member)){

+							String msg = Messages.format("The pushed down method ''{0}'' is bound in a callout method binding in ''{1}''.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						}else{

+							// TODO find a better way to analyze references in parameter mappings

+							String msg = Messages.format("The pushed down member ''{0}'' is referenced in a callout parameter mapping in ''{1}'' and will not be visible after refactoring.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						}

+					}

+					if (element instanceof ICalloutToFieldMapping) {

+						ICalloutToFieldMapping mapping = (ICalloutToFieldMapping) element;

+						if(mapping.getBoundBaseField().equals(member)){

+							String msg = Messages.format("The pushed down field ''{0}'' is referenced in a callout to field binding in ''{1}'' and will not be visible after refactoring.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						} else if(mapping.getRoleMethod() != null && mapping.getRoleMethod().equals(member)){

+							String msg = Messages.format("The pushed down method ''{0}'' is bound in a callout to field binding in ''{1}''.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						}else{

+							// TODO find a better way to analyze references in parameter mappings

+							String msg = Messages.format("The pushed down member ''{0}'' is referenced in a callout to field value mapping in ''{1}'' and will not be visible after refactoring.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						}

+					}

+					if (element instanceof ICallinMapping) {

+						ICallinMapping mapping = (ICallinMapping) element;

+						boolean baseMethodFound = false;

+						for (int j = 0; j < mapping.getBoundBaseMethods().length; j++) {

+							if(mapping.getBoundBaseMethods()[i].equals(member)){

+								String msg = Messages.format("The pushed down method ''{0}'' is referenced in a callin method binding in ''{1}'' and will not be visible after refactoring.",

+										new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+								status.addError(msg, JavaStatusContext.create(mapping));

+								baseMethodFound = true;

+								break;

+							}

+						}

+						

+						if(baseMethodFound){

+							continue;

+						}

+						

+						if(mapping.getRoleMethod().equals(member)){

+							String msg = Messages.format("The pushed down method ''{0}'' is bound in a callin method binding in ''{1}'' and will not be visible after refactoring.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						} else {

+							// TODO find a better way to analyze references in parameter mappings

+							String msg = Messages.format("The pushed down member ''{0}'' is referenced in a callin parameter mapping in ''{1}'' and will not be visible after refactoring.",

+									new String[] { member.getElementName(), mapping.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(mapping));

+						}

+					}

+					

+					if (element instanceof ResolvedSourceMethod) {

+						ResolvedSourceMethod method = (ResolvedSourceMethod) element;

+						// References in the declaring type are checked by the base

+						if(!method.getDeclaringType().equals(getDeclaringType())){

+							String msg = Messages.format("Pushed down member ''{0}'' is referenced by ''{1}''.",

+									new String[] { member.getElementName(), method.getDeclaringType().getFullyQualifiedName('.') });

+							status.addError(msg, JavaStatusContext.create(method));

+						}

+					}

+				}

+			}

+			return status;

+		}

+

+		@SuppressWarnings("restriction")

+		private boolean leavesAbstractMethod(IMember member) throws JavaModelException {

+			MemberActionInfo[] methodsToBeDeclaredAbstract = getAbstractDeclarationInfos();

+			for (int j = 0; j < methodsToBeDeclaredAbstract.length; j++) {

+				if(methodsToBeDeclaredAbstract[j].getMember() == member){

+					return true;

+				}

+			}

+			return false;

+		}

+		

+		private RefactoringStatus checkForDirectPhantomSubRoles(IProgressMonitor pm) throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			ITypeHierarchy hier = getHierarchyOfDeclaringClass(pm);

+			

+			if(hier instanceof OTTypeHierarchy){

+				OTTypeHierarchy otHier = (OTTypeHierarchy)hier;

+				otHier.setPhantomMode(true);

+				IType[] subTypes = otHier.getSubtypes(getDeclaringType());

+				for (int i = 0; i < subTypes.length; i++) {

+					IType subType = subTypes[i];

+					if(subType instanceof PhantomType){

+						String msg = Messages.format("An implicit sub role of ''{0}'' is a phantom role, therefore the pushed down members cannot be moved to ''{1}''.", new String[] { getDeclaringType().getFullyQualifiedName('.'), subType.getFullyQualifiedName('.') });

+						status.addError(msg, JavaStatusContext.create(subType));

+					}

+				}

+				otHier.setPhantomMode(false);

+			}

+			return status;

+		}

+		

+		/**

+		 * Checks if the pushed down method overrides an implicitly inherited method.

+		 * 

+		 * @param type the type to check overriding in

+		 * @param pm the progress monitor

+		 * @return the <code>RefactoringStatus</code> indicating overriding

+		 * @throws JavaModelException 

+		 */

+		private RefactoringStatus checkOverriding(IType type ,IProgressMonitor pm) throws JavaModelException{

+			RefactoringStatus status = new RefactoringStatus();

+			

+			// only roles inherit implicitly

+			if(TypeHelper.isRole(type.getFlags())){

+				

+				IMember[] membersToPushDown = getMembersToMove();

+				

+				// create the ot hierarchy to check implicit super types

+				OTTypeHierarchy hierarchy = new OTTypeHierarchy(type, type.getJavaProject(), false);

+				hierarchy.refresh(pm);

+				IType[] superRoles = hierarchy.getTSuperTypes(type);

+				

+				pm.beginTask("Checking Overriding", superRoles.length);

+				pm.subTask(""); //$NON-NLS-1$

+				

+				for (int i = 0; i < superRoles.length; i++) {

+					IType superRole = superRoles[i];

+					// do not search in the declaring type to avoid finding the pushed down method itself

+					if(!superRole.equals(getDeclaringType())){

+						for (int j = 0; j < membersToPushDown.length; j++) {

+							// check only the pushed down methods

+							if(membersToPushDown[j] instanceof IMethod){

+								IMethod pushedDownMethod = (IMethod) membersToPushDown[j];

+								IMethod overriddenMethod = superRole.getMethod(pushedDownMethod.getElementName(), pushedDownMethod.getParameterTypes());

+								if(overriddenMethod.exists()){

+									String msg = Messages.format("The pushed down method ''{0}'' would override the implicitly inherited method ''{1}''.", new String[] { pushedDownMethod.getElementName(), overriddenMethod.getDeclaringType().getFullyQualifiedName('.') + "." + overriddenMethod.getElementName()});

+									status.addError(msg, JavaStatusContext.create(overriddenMethod));

+								}

+							}

+						}

+					}

+					pm.worked(1);

+				}

+			}

+			pm.done();

+			return status;

+		}

+		

+		private RefactoringStatus checkOverloadingAndAmbiguityInType(IProgressMonitor pm, IType type) throws JavaModelException {

+			RefactoringStatus status = new RefactoringStatus();

+			ITypeHierarchy hier = getHierarchyOfDeclaringClass(pm);

+			for (int i = 0; i < getMembersToMove().length; i++) {

+				IMember element = getMembersToMove()[i];

+				

+				// overloading can only be caused by private methods

+				if (Flags.isPrivate(element.getFlags()) && element instanceof IMethod){

+					final IMethod method = (IMethod)element;

+					String[] paramTypes = method.getParameterTypes();

+					status.merge(RefactoringUtil.checkOverloadingAndAmbiguity(type, hier, method.getElementName(), paramTypes,

+							new IAmbuguityMessageCreator() {

+

+						public String createAmbiguousMethodSpecifierMsg() {

+							return "Refactoring cannot be performed! There would be an ambiguous method specifier in a method binding after moving!";

+						}

+

+					}, new IOverloadingMessageCreator() {

+

+						public String createOverloadingMessage() {

+							String msg = Messages.format("The pushed down method ''{0}'' would be overloaded after refactoring.", new String[] { method.getElementName()});

+							return msg;

+						}

+

+					}, pm));

+				}

+			}

+			return status;

+		}

+		

+		private RefactoringStatus checkOverloadingAndAmbiguity(IProgressMonitor pm) throws JavaModelException {

+			

+			IType[] subtypes = getAbstractDestinations(pm);

+			

+			pm.beginTask("Checking Overloading", subtypes.length);

+			pm.subTask(""); //$NON-NLS-1$

+			

+			RefactoringStatus status = new RefactoringStatus();

+			

+			// check overloading in subtypes of the destination type

+			for (int i = 0; i < subtypes.length; i++) {

+				status.merge(checkOverloadingAndAmbiguityInType(pm, subtypes[i]));

+				pm.worked(1);

+				

+			}

+			pm.done();

+			return status;

+		}

+		

+		

+		/**

+		 * Replaces the jdt hierarchy with the ot hierarchy. 

+		 * @throws JavaModelException 

+		 */

+		@SuppressWarnings("basecall")

+		callin ITypeHierarchy getOTHierarchyOfDeclaringClass(IProgressMonitor monitor) throws JavaModelException  {

+			try {

+				if (fDeclaringTypeHierachy != null)

+					return fDeclaringTypeHierachy;

+				if(OTModelManager.hasOTElementFor(getDeclaringType())){

+					fDeclaringTypeHierachy = OTModelManager.getOTElement(getDeclaringType()).newOTTypeHierarchy(monitor);

+				}else{

+					fDeclaringTypeHierachy = base.getOTHierarchyOfDeclaringClass(monitor);

+				}

+				return fDeclaringTypeHierachy;

+			} finally {

+				monitor.done();

+			}

+		}

+		

+		getOTHierarchyOfDeclaringClass <- replace getHierarchyOfDeclaringClass;

+		

+	}

+ 

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/rename/RenameMethodAmbuguityMsgCreator.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/rename/RenameMethodAmbuguityMsgCreator.java
new file mode 100644
index 0000000..7178797
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/rename/RenameMethodAmbuguityMsgCreator.java
@@ -0,0 +1,16 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.rename;

+

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator;

+

+public class RenameMethodAmbuguityMsgCreator implements IAmbuguityMessageCreator {

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.objectteams.otdt.refactoring.util.IAmbuguityMessageCreator#createAmbiguousMethodSpecifierMsg()

+	 */

+	public String createAmbiguousMethodSpecifierMsg() {

+		return "Refactoring cannot be performed! There would be an ambiguous method specifier in a method binding after renaming!";

+	}

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/rename/RenameMethodOverloadingMsgCreator.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/rename/RenameMethodOverloadingMsgCreator.java
new file mode 100644
index 0000000..181450b
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/rename/RenameMethodOverloadingMsgCreator.java
@@ -0,0 +1,16 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.adaptor.rename;

+

+import org.eclipse.objectteams.otdt.internal.refactoring.util.IOverloadingMessageCreator;

+

+public class RenameMethodOverloadingMsgCreator implements IOverloadingMessageCreator {

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.objectteams.otdt.refactoring.util.IOverloadingMessageCreator#createOverloadingMessage()

+	 */

+	public String createOverloadingMessage() {

+		return "Renamed method will be overloaded after refactoring!";

+	}

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/OTRefactoringCoreMessages.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/OTRefactoringCoreMessages.java
new file mode 100644
index 0000000..e48b59a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/OTRefactoringCoreMessages.java
@@ -0,0 +1,80 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2005, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: OTRefactoringCoreMessages.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.corext;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This utility class is a part of the OT/J refactoring adaptation.
+ * It contains some helper methods in order to retrieve message
+ * strings from a resource bundle.
+ * 
+ * @author brcan
+ */
+public class OTRefactoringCoreMessages
+{
+	private static final String RESOURCE_BUNDLE = OTRefactoringCoreMessages.class.getName();
+
+	private static ResourceBundle _resourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+	private OTRefactoringCoreMessages()
+	{
+	    //no instance
+	}
+
+	public static String getString(String key)
+	{
+		try
+		{
+			return _resourceBundle.getString(key);
+		}
+		catch (MissingResourceException e)
+		{
+			return key;
+		}
+	}
+	
+	public static String getFormattedString(String key, Object arg)
+	{
+		try
+		{
+			return MessageFormat.format(_resourceBundle.getString(key), new Object[] { arg });
+		}
+		catch (MissingResourceException e)
+		{
+			return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+		}	
+	}
+		
+	public static String getFormattedString(String key, Object[] args)
+	{
+		try
+		{
+			return MessageFormat.format(_resourceBundle.getString(key), args);
+		}
+		catch (MissingResourceException e)
+		{
+			return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+		}	
+	}	
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/base/OTRefactoringStatusCodes.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/base/OTRefactoringStatusCodes.java
new file mode 100644
index 0000000..03dc529
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/base/OTRefactoringStatusCodes.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2005, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: OTRefactoringStatusCodes.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+// renamed to "basis" due to incompatibilities with OT/J keyword "base"
+package org.eclipse.objectteams.otdt.internal.refactoring.corext.base;
+
+/**
+ * This utility class is a part of the OT/J refactoring adaptation.
+ * It contains OT refactoring related status/error codes.
+ * 
+ * @author brcan
+ */
+public class OTRefactoringStatusCodes
+{
+	private OTRefactoringStatusCodes()
+	{
+	    //no instance
+	}
+
+    public static final int PRIVATE_FIELD_ACCESS = 1; // FIXME(SH): unused
+    public static final int PROTECTED_FIELD_ACCESS = 2; // FIXME(SH): unused
+    public static final int PACKAGE_VISIBLE_FIELD_ACCESS = 3; // FIXME(SH): unused
+    public static final int AMBIGUOUS_METHOD_SPECIFIER = 4;
+    public static final int ROLE_METHOD_OVERRIDES_MOVED_METHOD = 5; // FIXME(SH): unused
+    public static final int BASE_METHOD_OVERRIDES_MOVED_METHOD = 6; // FIXME(SH): unused
+    public static final int MOVED_METHOD_IS_OVERRIDDEN_IN_REGULAR_SUBCLASS = 7; // FIXME(SH): unused
+    public static final int DUPLICATE_METHOD_IN_NEW_RECEIVER = 8;
+    public static final int CANNOT_MOVE_PRIVATE = 9;
+    public static final int OVERLOADING = 10;
+    
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/refactoring.properties b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/refactoring.properties
new file mode 100644
index 0000000..8822c00
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/refactoring.properties
@@ -0,0 +1,79 @@
+###############################################################################
+# This file is part of "Object Teams Development Tooling"-Software
+#
+# Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
+# for its Fraunhofer Institute for Computer Architecture and Software
+# Technology (FIRST), Berlin, Germany and Technical University Berlin,
+# Germany.
+#
+# 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
+#
+# Please visit http://www.eclipse.org/objectteams for updates and contact.
+#
+# Contributors:
+# Fraunhofer FIRST - Initial API and implementation
+# Technical University Berlin - Initial API and implementation
+###############################################################################
+
+# OT refactor menu
+OTRefactorMenu.label = Refac&tor (OT/J)
+
+# OT refactorings
+# ExtractMethodRefactoring
+OTExtractMethodRefactoring.name = Extract Method {0} in {1}
+OTExtractMethodRefactoring.not_a_base_class = Refactoring cannot be performed! Selected statements are not part of a regular OO-class!
+OTExtractMethodRefactoring.checking_overloading = Checking overloading
+OTExtractMethodRefactoring.overloading = Extracted method will be overloaded after refactoring!
+OTExtractMethodRefactoring.ambiguous_method_specifier = Refactoring cannot be performed! There would be an ambiguous method specifier in a method binding after extracting!
+
+# RenameTypeRefactoring
+OTRenameTypeRefactoring.role_type = Role type declared inside ''{0}'' is named {1}!
+OTRenameTypeRefactoring.nested_team_type = Nested team type declared inside ''{0}'' is named {1}!
+
+# RenameMethodRefactoring
+OTRenameVirtualMethodProcessor.not_a_base_class = Refactoring cannot be performed! Selected method is not a member of a regular OO-class!
+OTRenameNonVirtualMethodProcessor.not_a_base_class = Refactoring cannot be performed! Selected method is not a member of a regular OO-class!
+OTRenameVirtualMethodProcessor.update_base_call_occurrence = Update base call occurrence
+
+RenameVirtualMethodRefactoring.special_team_method=A Team implements this interface. You cannot use a special team method name
+
+# RenameFieldRefactoring
+OTRenameFieldProcessor.not_a_base_class = Refactoring cannot be performed! Selected field is not a member of a regular OO-class!
+
+# MoveStaticMembersRefactoring
+OTMoveStaticMembersProcessor.not_a_base_class = Refactoring cannot be performed! Selected method is not a member of a regular OO-class!
+
+# MoveInstanceMethodRefactoring
+OTMoveInstanceMethodRefactoring.not_a_base_class = Refactoring cannot be performed! Selected method is not a member of a regular OO-class!
+
+# visibility checks
+OTInstanceMethodMover.no_private_methods = Refactoring cannot be performed! Selected method is declared private!
+# field access/assignment checks
+OTInstanceMethodMover.method_accesses_private_field = Target method accesses a private field of the enclosing type and shall be moved to outside of this enclosing type (the new receiver is not the type of the field)!
+OTInstanceMethodMover.method_accesses_protected_field = Target method accesses a protected field of the enclosing type and shall be moved to a class in a different package (the new receiver is not the type of the field)!
+OTInstanceMethodMover.method_accesses_package_visible_field = Target method accesses a package-visible field of the enclosing type and shall be moved to a class in a different package (the new receiver is not the type of the field)!
+# overriding checks
+OTInstanceMethodMover.role_method_overrides_moved_method = Moved method would be overridden by a role method after moving!
+OTInstanceMethodMover.base_method_overrides_moved_method = Moved method would be overridden by a base method after moving!
+OTInstanceMethodMover.moved_method_is_overridden_in_regular_subclass = Moved method would be overridden in a regular subclass of the new receiver after moving!
+# ambiguity checks
+OTInstanceMethodMover.ambiguous_role_method_specifier_in_callin = There would be an ambiguous role method specifier in a callin method binding after moving!
+OTInstanceMethodMover.ambiguous_base_method_specifier_in_callin = There would be an ambiguous base method specifier in a callin method binding after moving!
+OTInstanceMethodMover.ambiguous_role_method_specifier_in_callout = There would be an ambiguous role method specifier in a callout method binding after moving!
+OTInstanceMethodMover.ambiguous_base_method_specifier_in_callout = There would be an ambiguous base method specifier in a callout method binding after moving!
+# duplicate checks
+OTInstanceMethodMover.duplicate_method_in_new_receiver = There already exists a method with the same name and the same parameters in the new receiver!
+
+# Reorg (cut, copy&paste, delete)
+ReorgUtils.21 = team ''{0}''
+ReorgUtils.22 = nested team ''{0}''
+ReorgUtils.23 = role ''{0}''
+ReorgUtils.24 = callout binding ''{0}''
+ReorgUtils.25 = callout to field binding ''{0}''
+ReorgUtils.26 = callin binding ''{0}''
+
+#Organize imports
+OrganizeImportsAction.label = Or&ganize Imports (OT/J)
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/BaseCallFinder.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/BaseCallFinder.java
new file mode 100644
index 0000000..c1e7431
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/BaseCallFinder.java
@@ -0,0 +1,50 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2005, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: BaseCallFinder.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.corext.rename;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.BaseCallMessageSend;
+
+/**
+ * @author svacina
+ * @version $Id: BaseCallFinder.java 23473 2010-02-05 19:46:08Z stephan $
+ * DOM AST Visitor for searching base calls in AST nodes
+ */
+public class BaseCallFinder extends ASTVisitor
+{
+    private ArrayList<BaseCallMessageSend> _result = null;
+    public BaseCallFinder()
+    {
+        _result = new ArrayList<BaseCallMessageSend>();
+    }
+    public boolean visit(BaseCallMessageSend node)
+    {
+        _result.add(node);
+        return false;
+    }
+    
+    public BaseCallMessageSend[] getResult()
+    {
+        return _result.toArray(new BaseCallMessageSend[_result.size()]);
+    }
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/RippleMethodFinder.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/RippleMethodFinder.java
new file mode 100644
index 0000000..5fdac85
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/RippleMethodFinder.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation 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
+ * $Id: RippleMethodFinder.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Fraunhofer FIRST - extended API and implementation
+ *     Technical University Berlin - extended API and implementation
+ *******************************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.corext.rename;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.corext.refactoring.Checks;
+import org.eclipse.jdt.internal.corext.refactoring.rename.MethodChecks;
+import org.eclipse.jdt.internal.corext.util.JdtFlags;
+import org.eclipse.objectteams.otdt.core.TypeHelper;
+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;
+
+//FIXME(SH): can we avoid this copy??
+//{OT_COPY_PASTE: Copy of class org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder
+//Reason: necessary OT-specific adaptations made 
+/**
+ * This class is used to find methods along the 'ripple'. When you rename a
+ * method that is declared in an interface, you must also rename its
+ * implementations. But because of multiple interface inheritance you have to go
+ * up and down the hierarchy to collect all the methods.
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "restriction"})
+public class RippleMethodFinder {
+	
+	private RippleMethodFinder(){
+		//no instances
+	}
+	
+	/**
+	 * Finds all methods along the 'ripple'.
+	 * 
+	 * @param method an {@link IMethod} which must be "most abstract",
+	 * 		i.e. it must not override or implement another method
+	 * @param pm a {@link IProgressMonitor}
+	 * @param owner a {@link WorkingCopyOwner}, or <code>null</code>
+	 * @return the ripple methods
+	 * @throws JavaModelException if something is wrong with <code>method</code> or its ripple.
+	 */
+	public static IMethod[] getRelatedMethods(IMethod method, IProgressMonitor pm, WorkingCopyOwner owner) throws JavaModelException {
+		try{
+			if (! MethodChecks.isVirtual(method) && ! method.getDeclaringType().isInterface())
+				return new IMethod[]{method};
+			return getAllRippleMethods(method, pm, owner);
+		} finally{
+			pm.done();
+		}	
+	}
+	
+	/*
+	 * We use the following algorithm to find methods to rename:
+	 * Input: type T, method m
+	   Assumption: No supertype of T declares m
+	   Output: variable result contains the list of types that declared the method to be renamed 
+
+	 	result:= empty set // set of types that declare methods to rename
+ 		visited:= empty set //set of already visited types
+	 	q:= empty queue //queue of types to visit
+	 	q.insert(T) 
+
+		while (!q.isEmpty()){
+			t:= q.remove();
+			//assert(t is an interface or declares m as virtual)
+			//assert(!visited.contains(t))
+			visited.add(t);
+			result.add(t);
+			forall: i in: t.subTypes do: 
+				if ((! visited.contains(i)) && (i declares m)) result.add(i);
+			forall: i in: t.subTypes do:
+				q.insert(x) 
+					where x is any type satisfying the followowing:
+					a. x is a supertype of i
+					b. x is an interface and declares m or
+					    x declares m as a virtual method
+					c. no supertype of x is an interface that declares m and
+					    no supertype of x is a class that declares m as a virtual method
+					d. ! visited.contains(x)
+					e. ! q.contains(x)
+		}
+	 */
+	private static IMethod[] getAllRippleMethods(IMethod method, IProgressMonitor pm, WorkingCopyOwner owner) throws JavaModelException {
+		pm.beginTask("", 4); //$NON-NLS-1$
+		Set result= new HashSet();
+		Set visitedTypes= new HashSet();
+		List methodQueue= new ArrayList();
+		Set hierarchies= new HashSet();
+		methodQueue.add(method);
+		while (! methodQueue.isEmpty()){
+			IMethod m= (IMethod)methodQueue.remove(0);
+			
+			/* must check for binary - otherwise will go all the way on all types
+			 * happens on toString() for example */  
+			if (m.isBinary())
+				continue; 
+			IType type= m.getDeclaringType();
+			Assert.isTrue(! visitedTypes.contains(type), "! visitedTypes.contains(type)"); //$NON-NLS-1$
+			Assert.isTrue(type.isInterface() || declaresAsVirtual(type, method), "second condition"); //$NON-NLS-1$
+			
+			visitedTypes.add(type);
+			result.add(m);
+			
+			IType[] subTypes= getAllSubtypes(pm, owner, type, hierarchies);
+			for (int i= 0; i < subTypes.length; i++){
+				if (!visitedTypes.contains(subTypes[i])){ 
+					IMethod subTypeMethod= Checks.findSimilarMethod(m, subTypes[i]);
+					if (subTypeMethod != null)
+						result.add(subTypeMethod);
+				}	
+			}
+			
+			for (int i= 0; i < subTypes.length; i++){
+				IMethod toAdd= findAppropriateMethod(owner, visitedTypes, methodQueue, subTypes[i], method, new NullProgressMonitor());
+				if (toAdd != null)
+					methodQueue.add(toAdd);
+			}
+			if (pm.isCanceled())
+				throw new OperationCanceledException();
+		}
+		return (IMethod[]) result.toArray(new IMethod[result.size()]);
+	}
+	
+	private static IType[] getAllSubtypes(IProgressMonitor pm, WorkingCopyOwner owner, IType type, Set cachedHierarchies) throws JavaModelException {
+		//first, try in the cached hierarchies
+		for (Iterator iter= cachedHierarchies.iterator(); iter.hasNext();) {
+			ITypeHierarchy hierarchy= (ITypeHierarchy) iter.next();
+			if (hierarchy.contains(type))
+				return hierarchy.getAllSubtypes(type);
+		}
+		SubProgressMonitor subPm= new SubProgressMonitor(pm, 1);
+		ITypeHierarchy hierarchy= newTypeHierarchy(type, owner, subPm);
+		cachedHierarchies.add(hierarchy);
+		return hierarchy.getAllSubtypes(type);
+	}
+	
+	private static IMethod findAppropriateMethod(WorkingCopyOwner owner, Set visitedTypes, List methodQueue, IType type, IMethod method, IProgressMonitor pm) throws JavaModelException{
+		pm.beginTask("analyzing hierarchy", 1); // Note(SH): jdt.ui's externalized string has been removed
+		IType[] superTypes= newSupertypeHierarchy(type, owner, new SubProgressMonitor(pm, 1)).getAllSupertypes(type);
+		for (int i= 0; i< superTypes.length; i++){
+			IType t= superTypes[i];
+			if (visitedTypes.contains(t))
+				continue;
+			IMethod found= Checks.findSimilarMethod(method, t);	
+			if (found == null)
+				continue;
+			if (! declaresAsVirtual(t, method))	
+				continue;	
+			if (methodQueue.contains(found))	
+				continue;
+			return getTopMostMethod(owner, visitedTypes, methodQueue, method, t, new NullProgressMonitor());	
+		}
+		return null;
+	}
+	
+	private static IMethod getTopMostMethod(WorkingCopyOwner owner, Set visitedTypes, List methodQueue, IMethod method, IType type, IProgressMonitor pm)throws JavaModelException{
+		pm.beginTask("", 1); //$NON-NLS-1$
+		IMethod methodInThisType= Checks.findSimilarMethod(method, type);
+		Assert.isTrue(methodInThisType != null);
+		IType[] superTypes= newSupertypeHierarchy(type, owner, new SubProgressMonitor(pm, 1)).getAllSupertypes(type);
+		for (int i= 0; i < superTypes.length; i++){
+			IType t= superTypes[i];
+			if (visitedTypes.contains(t))
+				continue;
+			IMethod found= Checks.findSimilarMethod(method, t);	
+			if (found == null)
+				continue;
+			if (! declaresAsVirtual(t, method))	
+				continue;
+			if (methodQueue.contains(found))	
+				continue;
+			return getTopMostMethod(owner, visitedTypes, methodQueue, method, t, new NullProgressMonitor());
+		}
+		return methodInThisType;
+	}
+	
+	private static boolean declaresAsVirtual(IType type, IMethod m) throws JavaModelException{
+		IMethod found= Checks.findSimilarMethod(m, type);
+		if (found == null)
+			return false;
+		if (JdtFlags.isStatic(found))	
+			return false;
+		if (JdtFlags.isPrivate(found) 
+//{ObjectTeams: ObjectTeams: private rolemethod is also virtual  
+				&& !TypeHelper.isRole(type.getFlags())
+//jsv)			
+				)
+			return false;	
+		return true;	
+	}
+	
+	//---
+	
+	private static ITypeHierarchy newTypeHierarchy(IType type, WorkingCopyOwner owner, IProgressMonitor pm) throws JavaModelException {
+//{ObjectTeams: create OTTypeHierarchy
+		OTTypeHierarchy hier = new OTTypeHierarchy(type, type.getJavaProject(),true);
+		hier.refresh(pm);
+		return hier;
+		//orig
+		//if (owner == null)
+		//	return type.newTypeHierarchy(pm);
+		//else
+		//	return type.newTypeHierarchy(owner, pm);
+//jsv}
+	}
+
+	private static ITypeHierarchy newSupertypeHierarchy(IType type, WorkingCopyOwner owner, IProgressMonitor pm) throws JavaModelException {
+//{ObjectTeams: create OTTypeHierarchy
+		OTTypeHierarchy hier = new OTTypeHierarchy(type, type.getJavaProject(),false);
+		hier.refresh(pm);
+		return hier;
+		//orig:
+		//if (owner == null)
+		//	return type.newSupertypeHierarchy(pm);
+		//else
+		//	return type.newSupertypeHierarchy(owner, pm);
+//jsv}	
+	}
+}
+//jsv}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/RolePartsUnifier.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/RolePartsUnifier.java
new file mode 100644
index 0000000..5d31651
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/corext/rename/RolePartsUnifier.java
@@ -0,0 +1,50 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2009 Stephan Herrmann.
+ * 
+ * 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: RolePartsUnifier.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Stephan Herrmann
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.corext.rename;
+
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+
+import base org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder.BindingFinder;
+
+/**
+ * Help the refactoring implementation to compare role bindings by
+ * uniformly using the interface part.
+ * 
+ * @author stephan
+ * @since 1.3.1
+ */
+@SuppressWarnings({ "restriction", "decapsulation" }) // base class BindingFinder
+public team class RolePartsUnifier {
+        protected class BindingFinder playedBy BindingFinder {
+
+                IBinding getDeclaration(IBinding binding) <- replace IBinding getDeclaration(IBinding binding);
+
+                static callin IBinding getDeclaration(IBinding binding) {
+                        IBinding decl = base.getDeclaration(binding);
+                        if (decl instanceof ITypeBinding) {
+                                ITypeBinding typeBinding = (ITypeBinding)decl;
+                                if (typeBinding.isClass() && typeBinding.isRole()) {
+                                        ITypeBinding ifcPart = typeBinding.getIfcPart();
+                                        if (ifcPart != null)
+                                                return ifcPart;
+                                }
+                        }
+                        return decl;
+                }               
+        }
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/AbstractCallinRefactoringAction.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/AbstractCallinRefactoringAction.java
new file mode 100644
index 0000000..72d6596
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/AbstractCallinRefactoringAction.java
@@ -0,0 +1,166 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2009 Stephan Herrmann.
+ * 
+ * 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: InlineCallinAction.java 23045 2009-11-15 21:17:24Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaTextSelection;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * Common part of refactoring actions affecting calling bindings.
+ * 
+ * @author stephan
+ * @since 1.4.0
+ */
+@SuppressWarnings("restriction")
+public abstract class AbstractCallinRefactoringAction extends Action {
+
+	/** 
+	 * This class defines the common stateful part of {@link AbstractCallinRefactoringAction} and 
+	 * {@link AbstractCallinRefactoringAction.SelectionDispatchAction}. 
+	 */
+	protected abstract class CallinRefactoringActionCommon extends SelectionActionCommon
+	{
+		public CallinRefactoringActionCommon(JavaEditor editor) {
+			super(editor);
+		}
+		
+		public CallinRefactoringActionCommon(IWorkbenchWindow window) {
+			super(window);
+		}
+
+		public boolean isRefactoringAvailable() throws JavaModelException {
+			if (   fJavaElement != null 
+			  	&& fJavaElement.exists() 
+			  	&& fJavaElement.isStructureKnown()
+			  	&& fJavaElement instanceof IMethod) 
+			{
+				IMethod method = (IMethod)fJavaElement;
+				return    !method.isConstructor() 
+					   && !method.getDeclaringType().isAnnotation();				
+			}
+			return false;
+		}
+	}
+	
+	/** Provide the respective refactoring action to view context menus (editor, package explorer, outline ...) */
+	public class SelectionDispatchAction extends org.eclipse.jdt.ui.actions.SelectionDispatchAction 
+	{	
+		CallinRefactoringActionCommon common;
+		
+		public SelectionDispatchAction(IWorkbenchSite site) {
+			super(site);
+			common = createRefactoringActionCommon(site.getWorkbenchWindow());
+			init();
+		}
+		
+		public SelectionDispatchAction(JavaEditor editor) {
+			super(editor.getEditorSite());
+			common = createRefactoringActionCommon(editor);
+			init();
+		}
+
+		void init() {
+			setText(commandName);
+			setToolTipText(commandTooltip);
+			setEnabled(true); // further checking in run().
+		}
+
+		@Override
+		public void selectionChanged(JavaTextSelection javaTextSelection) {
+			try {
+				common.selectionChanged(javaTextSelection);
+				setEnabled(common.isRefactoringAvailable());
+			} catch (CoreException ce) {
+				setEnabled(false);
+			}
+		}
+		
+		@Override
+		public void selectionChanged(IStructuredSelection selection) {
+			try {
+				common.selectionChanged(selection);
+				setEnabled(common.isRefactoringAvailable());
+			} catch (JavaModelException e) {
+				setEnabled(false);
+			}
+		}
+		
+		@Override
+		public void selectionChanged(ITextSelection selection) {
+			// ignore useless selection, let above methods prevail; further checks in run().
+		}
+	
+		@Override
+		public void run() {
+			common.run();
+		}
+	}
+	
+	// =========== Start AbstractCallinRefactoringAction ===========
+
+	CallinRefactoringActionCommon common;
+	
+	final protected String commandTooltip;
+	final protected String commandName;
+	
+	protected AbstractCallinRefactoringAction(String commandName, String commandTooltip) {
+		this.commandName = commandName;
+		this.commandTooltip = commandTooltip;
+	}
+
+	public void init(IWorkbenchWindow window) {
+		common = createRefactoringActionCommon(window);
+	}
+
+	abstract protected CallinRefactoringActionCommon createRefactoringActionCommon(IWorkbenchWindow window);
+	abstract protected CallinRefactoringActionCommon createRefactoringActionCommon(JavaEditor editor);
+
+	public void dispose() {
+		// Do nothing
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+		try {
+			if (selection instanceof IStructuredSelection) {
+				common.selectionChanged((IStructuredSelection)selection);
+				action.setEnabled(common.isRefactoringAvailable());
+			} else if (selection instanceof JavaTextSelection) {
+				common.selectionChanged((JavaTextSelection) selection);
+				action.setEnabled(common.isRefactoringAvailable());
+			} else {
+				common.clearJavaElement();
+				action.setEnabled(true); // further checks in run().
+			}
+		} catch (JavaModelException exception) {
+			action.setEnabled(false);
+		}
+	}
+
+	public void run(IAction action) {
+		common.run();
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/SelectionActionCommon.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/SelectionActionCommon.java
new file mode 100644
index 0000000..82f325b
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/SelectionActionCommon.java
@@ -0,0 +1,102 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2009 Stephan Herrmann.
+ * 
+ * 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.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaTextSelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * Common super class for actions that depend on the selection and need to be provided by several mechanisms.
+ * @author stephan
+ */
+@SuppressWarnings("restriction")
+public abstract class SelectionActionCommon {
+
+	protected IJavaElement fJavaElement;
+	protected JavaEditor fEditor;
+	protected IWorkbenchWindow fWindow;
+
+	public SelectionActionCommon(JavaEditor editor) {
+		this.fEditor = editor;
+	}
+	
+	public SelectionActionCommon(IWorkbenchWindow window) {
+		this.fWindow = window;
+	}
+	
+	public void selectionChanged(IStructuredSelection selection) {
+		Object[] elements = selection.toArray();
+		filterElements(elements);
+	}
+
+	public void selectionChanged(JavaTextSelection javaTextSelection) throws JavaModelException {
+		IJavaElement[] elements= javaTextSelection.resolveElementAtOffset();
+		filterElements(elements);
+	}
+
+	/** 
+	 * Given some selected elements figure out whether this is a valid selection for the current action,
+	 * and store the java element that {@link #run()} should operate on in the field {@link #fJavaElement}.
+	 * 
+	 * @param elements the elements of either a structured selection, a java text selection or 
+	 * 		the result of {@link SelectionConverter#codeResolve(JavaEditor)}.
+	 */
+	protected abstract void filterElements(Object[] elements);
+
+	public void clearJavaElement() {
+		this.fJavaElement = null;
+	}
+	
+	/** Finish initialization and trigger running the action. */
+	public void run() {
+		prepareRun();
+		doRun();
+	}
+	
+	/** This method performs those operations that are to costly to do during selectionChange. */
+	protected void prepareRun() {
+		// try to fill in missing info:
+		if (this.fJavaElement == null) {
+			// fetch the method from the editor:
+			JavaEditor javaEditor = this.fEditor;
+			if (javaEditor == null) 
+				try {
+					javaEditor = (JavaEditor)this.fWindow.getActivePage().getActiveEditor();
+				} catch (ClassCastException cce) { /* nop */ }
+			if (javaEditor != null)
+				try {
+					IJavaElement[] elements = SelectionConverter.codeResolve(javaEditor);
+					filterElements(elements);
+				} catch (JavaModelException e) {
+					this.fJavaElement = null;
+				}
+		}
+		if (this.fWindow == null && this.fEditor != null)
+			// fetch the window from the editor:
+			this.fWindow = this.fEditor.getSite().getWorkbenchWindow();
+	}
+
+	/** 
+	 * Implementation for running the refactoring action.
+	 */
+	protected abstract void doRun();
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinAction.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinAction.java
new file mode 100644
index 0000000..78cd2ee
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinAction.java
@@ -0,0 +1,74 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin;

+

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;

+import org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.AbstractCallinRefactoringAction;

+import org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.AbstractCallinRefactoringAction.SelectionDispatchAction;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.IWorkbenchWindowActionDelegate;

+

+/**

+ * Action classes for the extract callin refactoring:

+ * <ul>

+ * <li>The toplevel class provides the action to the main menu bar (registered via plugin.xml).</li>

+ * <li>Inherited nested class {@link SelectionDispatchAction} provides the action to context menus of all views.</li>

+ * <li>Nested class {@link ExtractCallinActionCommon} implements the shared stateful part of both actions.</li>

+ * </ul>

+ */

+@SuppressWarnings("restriction")

+public class ExtractCallinAction extends AbstractCallinRefactoringAction implements IWorkbenchWindowActionDelegate 

+{

+	/** 

+	 * Fill inherited class {@link CallinRefactoringActionCommon} with details.

+	 */

+	class ExtractCallinActionCommon extends CallinRefactoringActionCommon

+	{

+		ExtractCallinActionCommon(JavaEditor editor) {

+			super(editor);

+		}

+		

+		ExtractCallinActionCommon(IWorkbenchWindow window) {

+			super(window);

+		}

+

+		protected void filterElements(Object[] elements) {

+			this.fJavaElement = null;

+			if (elements == null || elements.length != 1)

+				return;

+			else if (elements[0] instanceof IMethod)

+				this.fJavaElement = (IMethod) elements[0];

+		}

+

+		protected void doRun() {

+			if (fJavaElement != null && fWindow != null) {

+				try {

+					new RefactoringWizardOpenOperation(

+							new ExtractCallinWizard(

+									new ExtractCallinRefactoring((IMethod)fJavaElement), 

+									"Extract Callin"

+							)

+					).run(fWindow.getShell(), "Extract Callin");

+				} catch (InterruptedException exception) {

+					// Do nothing

+				}

+			} else {

+				MessageDialog.openInformation(null, "Extract Callin", "Operation unavailable on the current selection. Select a callin-bound role method or a callin method binding");

+			}		

+		}

+	}

+

+	// =========== Start ExtractCallinAction ===========

+	public ExtractCallinAction() {

+		super("Extract Callin ...", "Extract a callin binding and method.");

+	}

+	

+	protected CallinRefactoringActionCommon createRefactoringActionCommon(IWorkbenchWindow window) {

+		return new ExtractCallinActionCommon(window);

+	}

+

+	protected CallinRefactoringActionCommon createRefactoringActionCommon(JavaEditor editor) {

+		return new ExtractCallinActionCommon(editor);

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinInputPage.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinInputPage.java
new file mode 100644
index 0000000..2d28b5a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinInputPage.java
@@ -0,0 +1,247 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin;

+

+import java.util.List;

+

+import org.eclipse.jdt.core.IType;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.events.ModifyEvent;

+import org.eclipse.swt.events.ModifyListener;

+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.Button;

+import org.eclipse.swt.widgets.Combo;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Group;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.swt.widgets.Text;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+import org.eclipse.objectteams.otdt.core.IRoleType;

+

+public class ExtractCallinInputPage extends UserInputWizardPage {

+

+

+	private Text fNameField;

+	

+	private Combo fTypeCombo;

+

+	private Button fReferenceButton;

+

+	private List<IRoleType> fCandidateRoles;

+

+	private ExtractCallinRefactoring fRefactoring;

+

+	private Group fExtractMode;

+

+	private Button fReplaceRadio;

+

+	private Button fBeforeRadio;

+

+	private Button fAfterRadio;

+

+	private Button fRemove;

+	

+

+	public ExtractCallinInputPage(String name) {

+		super(name);

+	}

+

+	public void createControl(Composite parent) {

+		initializeDialogUnits(parent);

+		fRefactoring = (ExtractCallinRefactoring) getRefactoring();

+		Composite result = new Composite(parent, SWT.NONE);

+

+		setControl(result);

+

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 2;

+		result.setLayout(layout);

+

+		Label label = new Label(result, SWT.NONE);

+		label.setText("&Role method name:");

+

+		fNameField = createNameField(result);

+		

+		// Role Selection

+		label = new Label(result, SWT.NONE);

+		label.setText("&Target role:");

+

+		Composite composite = new Composite(result, SWT.NONE);

+		

+		fCandidateRoles = fRefactoring.getCandidateRoles();

+		

+		layout = new GridLayout();

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		layout.numColumns = 1;

+		composite.setLayout(layout);

+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+

+		fTypeCombo = createTypeCombo(composite);

+		fTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		

+		for (IRoleType role : fCandidateRoles) {

+			final String comboLabel = role.getFullyQualifiedName('.');

+			fTypeCombo.add(comboLabel);

+		}

+		fTypeCombo.select(fCandidateRoles.size() - 1);

+		

+		

+		createRadioButtonGroup(result);

+

+		fReferenceButton = new Button(result, SWT.CHECK);

+		fReferenceButton.setEnabled(true);

+		fReferenceButton.setText("&Delete extracted base method");

+		fReferenceButton.addSelectionListener(new SelectionAdapter() {

+			

+		@Override

+		public void widgetSelected(SelectionEvent event) {

+				fRefactoring.setDeleteBaseMethod(fReferenceButton.getSelection());

+			}

+		});

+		

+		

+		GridData data = new GridData(GridData.FILL_HORIZONTAL);

+		data.horizontalSpan = 2;

+		data.verticalIndent = 2;

+		fReferenceButton.setLayoutData(data);

+

+		fNameField.setText(fRefactoring.getBaseMethod().getElementName());

+		fTypeCombo.setText(fRefactoring.getBaseMethod().getDeclaringType().getFullyQualifiedName());

+

+		fNameField.addModifyListener(new ModifyListener() {

+

+			public void modifyText(ModifyEvent event) {

+				handleInputChanged();

+			}

+		});

+

+		fReferenceButton.addSelectionListener(new SelectionAdapter() {

+

+			@Override

+			public void widgetSelected(SelectionEvent event) {

+				fRefactoring.setDeleteBaseMethod(fReferenceButton.getSelection());

+			}

+		});

+

+		fTypeCombo.addModifyListener(new ModifyListener() {

+

+			public void modifyText(ModifyEvent event) {

+				handleInputChanged();

+			}

+		});

+

+		fNameField.setFocus();

+		fNameField.selectAll();

+		fBeforeRadio.setEnabled(fRefactoring.isExtractBeforeAvailable());

+		fAfterRadio.setEnabled(fRefactoring.isExtractAfterAvailable());

+		handleInputChanged();

+		fReferenceButton.setSelection(fRefactoring.isDeleteBaseMethod());

+	}

+

+	private void createRadioButtonGroup(Composite result) {

+		fExtractMode = new Group(result, SWT.NONE);

+		GridData data = new GridData(GridData.FILL_HORIZONTAL);

+		data.horizontalSpan = 2;

+		data.verticalIndent = 2;

+		fExtractMode.setLayoutData(data);

+		fExtractMode.setLayout(new GridLayout());

+		fExtractMode.setText("Extract Mode");

+

+		fReplaceRadio = new Button(fExtractMode, SWT.RADIO);

+		fReplaceRadio.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		fReplaceRadio.setText("R&eplace");

+		fReplaceRadio.setSelection(true);

+		fRefactoring.setMappingKind(ICallinMapping.KIND_REPLACE);

+		fReplaceRadio.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent event) {

+				if (((Button) event.widget).getSelection()) {

+					fRefactoring.setMappingKind(ICallinMapping.KIND_REPLACE);

+					fRemove.setEnabled(true);

+					handleInputChanged();

+				}

+			}

+		});

+		fRemove = new Button(fExtractMode, SWT.CHECK);

+		data = new GridData(GridData.FILL_HORIZONTAL);

+		data.horizontalIndent = convertWidthInCharsToPixels(3);

+		fRemove.setLayoutData(data);

+		fRemove.setText("&Copy base method code");

+		fRemove.setSelection(fRefactoring.isCopyBaseMethod());

+		fRemove.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				fRefactoring.setCopyBaseMethod(((Button) e.widget).getSelection());

+				handleInputChanged();

+			}

+		});

+

+		fBeforeRadio = new Button(fExtractMode, SWT.RADIO);

+		fBeforeRadio.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		fBeforeRadio.setText("&Before");

+		fBeforeRadio.setSelection(false);

+		fBeforeRadio.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent event) {

+				fRemove.setEnabled(false);

+				if (((Button) event.widget).getSelection()){

+					fRefactoring.setMappingKind(ICallinMapping.KIND_BEFORE);

+					handleInputChanged();

+				}

+			}

+		});

+

+		fAfterRadio = new Button(fExtractMode, SWT.RADIO);

+		fAfterRadio.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		fAfterRadio.setText("&After");

+		fAfterRadio.setSelection(false);

+		fAfterRadio.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent event) {

+				fRemove.setEnabled(false);

+				if (((Button) event.widget).getSelection()){

+					fRefactoring.setMappingKind(ICallinMapping.KIND_AFTER);

+					handleInputChanged();

+				}

+			}

+		});

+	}

+

+	private Text createNameField(Composite result) {

+		Text field = new Text(result, SWT.SINGLE | SWT.LEFT | SWT.BORDER);

+		field.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		return field;

+	}

+

+	private Combo createTypeCombo(Composite composite) {

+		Combo combo = new Combo(composite, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);

+		combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		combo.setVisibleItemCount(4);

+		return combo;

+	}

+

+	void handleInputChanged() {

+		fReferenceButton.setEnabled(fRefactoring.getMappingKind() != ICallinMapping.KIND_REPLACE);

+		fRefactoring.setRoleType(getSelectedRole());

+		

+		RefactoringStatus status = new RefactoringStatus();

+		fRefactoring.setRoleMethodName(fNameField.getText());

+		status.merge(fRefactoring.checkRoleMethodName());

+

+		setPageComplete(!status.hasError());

+		int severity = status.getSeverity();

+		String message = status.getMessageMatchingSeverity(severity);

+		if (severity >= RefactoringStatus.INFO) {

+			setMessage(message, severity);

+		} else {

+			setMessage("", NONE); //$NON-NLS-1$

+		}

+	}

+	

+	public IType getSelectedRole() {

+		final int index = fTypeCombo.getSelectionIndex();

+		if (index >= 0)

+			return fCandidateRoles.get(index);

+		return null;

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinRefactoring.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinRefactoring.java
new file mode 100644
index 0000000..1a18d7e
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinRefactoring.java
@@ -0,0 +1,774 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin;

+

+import java.text.MessageFormat;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.core.runtime.SubProgressMonitor;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.JavaConventions;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.core.dom.AST;

+import org.eclipse.jdt.core.dom.ASTNode;

+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;

+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;

+import org.eclipse.jdt.core.dom.BaseCallMessageSend;

+import org.eclipse.jdt.core.dom.Block;

+import org.eclipse.jdt.core.dom.CallinMappingDeclaration;

+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;

+import org.eclipse.jdt.core.dom.CompilationUnit;

+import org.eclipse.jdt.core.dom.Expression;

+import org.eclipse.jdt.core.dom.ExpressionStatement;

+import org.eclipse.jdt.core.dom.IBinding;

+import org.eclipse.jdt.core.dom.IExtendedModifier;

+import org.eclipse.jdt.core.dom.IMethodBinding;

+import org.eclipse.jdt.core.dom.ITypeBinding;

+import org.eclipse.jdt.core.dom.MethodDeclaration;

+import org.eclipse.jdt.core.dom.MethodInvocation;

+import org.eclipse.jdt.core.dom.MethodSpec;

+import org.eclipse.jdt.core.dom.Modifier;

+import org.eclipse.jdt.core.dom.Name;

+import org.eclipse.jdt.core.dom.NodeFinder;

+import org.eclipse.jdt.core.dom.ParameterMapping;

+import org.eclipse.jdt.core.dom.SimpleName;

+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;

+import org.eclipse.jdt.core.dom.Statement;

+import org.eclipse.jdt.core.dom.ThisExpression;

+import org.eclipse.jdt.core.dom.Type;

+import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;

+import org.eclipse.jdt.core.dom.rewrite.ASTNodeCreator;

+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;

+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;

+import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRewriteUtil;

+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;

+import org.eclipse.ltk.core.refactoring.Change;

+import org.eclipse.ltk.core.refactoring.CompositeChange;

+import org.eclipse.ltk.core.refactoring.Refactoring;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.TextFileChange;

+import org.eclipse.text.edits.MultiTextEdit;

+import org.eclipse.text.edits.TextEdit;

+import org.eclipse.text.edits.TextEditGroup;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+import org.eclipse.objectteams.otdt.core.IRoleType;

+import org.eclipse.objectteams.otdt.internal.core.AbstractCalloutMapping;

+import org.eclipse.objectteams.otdt.internal.core.CalloutMapping;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

+

+@SuppressWarnings("restriction")

+public class ExtractCallinRefactoring extends Refactoring {

+

+	private Map<ICompilationUnit, TextFileChange> fChanges = null;

+	

+	private boolean fDeleteBaseMethod;

+

+	private CompilationUnit fRootBase;

+

+	private AST fBaseAST;

+

+	private ICompilationUnit fBaseCUnit;

+

+	private ICompilationUnit fRoleCUnit;

+

+	private CompilationUnit fRootRole;

+

+	private AST fRoleAST;

+

+	private IType fRoleType;

+

+	private TextFileChange fBaseTextFileChange;

+

+	private TextFileChange fRoleTextFileChange;

+

+	private List<ICallinMapping> fBoundCallinMappings;

+

+	private String fRoleMethodName;

+

+	private IType fBaseType;

+

+	private ASTRewrite fBaseRewrite;

+

+	private int fMappingKind;

+	

+	private boolean fCopyBaseMethod;

+

+	private IMethod fBaseMethod;

+

+	private List<IRoleType> fBoundRoles;

+

+	private IMethod fExtractedBaseMethod;

+

+	private MethodDeclaration fBaseMethodDeclaration;

+

+	private ASTRewrite fRoleRewrite;

+

+	private ImportRewrite fRoleImportRewriter;

+

+	private MethodInvocation fExtractedMethodInvocation;

+

+	private ImportRewrite fBaseImportRewriter;

+	

+	public ExtractCallinRefactoring() {

+		fCopyBaseMethod = true;

+	}

+

+	public ExtractCallinRefactoring(IMethod baseMethod) {

+		this();

+		fBaseMethod = baseMethod;

+	}

+

+	public ExtractCallinRefactoring(IMethod baseMethod, IType role, int mappingKind) {

+		this(baseMethod);

+		fRoleType = role;

+		fMappingKind = mappingKind;

+	}

+

+	public List<IRoleType> getCandidateRoles() {

+		return fBoundRoles;

+	}

+	

+	public void setRoleType(IType role) {

+		fRoleType = role;

+	}

+	

+	public void setCopyBaseMethod(boolean copyBaseMethod) {

+		fCopyBaseMethod = copyBaseMethod;

+	}

+	

+	public void setMappingKind(int mappingKind) {

+		fMappingKind = mappingKind;

+	}

+	

+	public int getMappingKind() {

+		return fMappingKind;

+	}

+

+	public void setChanges(Map<ICompilationUnit, TextFileChange> fChanges) {

+		this.fChanges = fChanges;

+	}

+

+	public Map<ICompilationUnit, TextFileChange> getChanges() {

+		return fChanges;

+	}

+

+	public IMethod getBaseMethod() {

+		return fBaseMethod;

+	}

+	

+	public boolean isCopyBaseMethod() {

+		return fCopyBaseMethod;

+	}

+

+	public boolean isDeleteBaseMethod() {

+		return fDeleteBaseMethod;

+	}

+

+	public void setDeleteBaseMethod(boolean deleteRoleMethod) {

+		fDeleteBaseMethod = deleteRoleMethod;

+	}

+

+	public RefactoringStatus checkInitialConditions(IProgressMonitor monitor) throws CoreException, OperationCanceledException {

+		RefactoringStatus status= new RefactoringStatus();

+		try {

+			monitor.beginTask("Checking preconditions...", 1);

+			if (fBaseMethod == null) {

+				status.merge(RefactoringStatus.createFatalErrorStatus("Method has not been specified."));

+			} else if (!fBaseMethod.exists()) {

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' does not exist.", new Object[] { fBaseMethod

+						.getElementName() })));

+			}else if (fBaseMethod.isBinary()){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' is declared in a binary class file.", new Object[] { fBaseMethod

+						.getElementName() })));

+			}else if (fBaseMethod.isReadOnly()){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' is declared in a read-only class file.", new Object[] { fBaseMethod

+						.getElementName() })));

+			} else if (!fBaseMethod.getCompilationUnit().isStructureKnown()) {

+					status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Compilation unit ''{0}'' contains compile errors.",

+							new Object[] { fBaseMethod.getCompilationUnit().getElementName() })));

+			} else if (Flags.isAbstract(fBaseMethod.getFlags())){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' is abstract, cannot extract.", new Object[] { fBaseMethod

+						.getElementName() })));

+			} else if (fBaseMethod instanceof AbstractCalloutMapping){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' is an callout method and cannot be extracted.", new Object[] { fBaseMethod

+						.getElementName() })));

+			}else{ 

+					status.merge(initialize(monitor));

+			}

+		} finally {

+			monitor.done();

+		}

+		return status;

+	}	

+	

+	private RefactoringStatus initialize(IProgressMonitor monitor) {

+		RefactoringStatus status = new RefactoringStatus();

+		try {

+				fRoleMethodName = fBaseMethod.getElementName();

+				fBaseType = fBaseMethod.getDeclaringType();

+				fBaseCUnit = fBaseType.getCompilationUnit();

+

+				if (fRootBase == null) {

+					fRootBase = RefactoringASTParser.parseWithASTProvider(fBaseCUnit, true, new SubProgressMonitor(monitor, 99));

+				}

+				fBaseImportRewriter = StubUtility.createImportRewrite(fRootBase, true);

+				fBaseMethodDeclaration = RefactoringUtil.methodToDeclaration(fBaseMethod, fRootBase);

+				

+				fBaseAST = fRootBase.getAST();

+				

+				fBoundRoles = findCandidateRoles();

+			if (fBoundRoles.size() == 0) {

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("The declaring type ''{0}'' is not bound by a role.",

+						new Object[] { fBaseType.getElementName() })));

+			}

+			

+			

+			

+		} catch (CoreException e) {

+			status.merge(createCouldNotParseStatus());

+		}

+		if (status.hasFatalError()) {

+			return status;

+		}

+		return status;

+	}

+	

+	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {

+

+		RefactoringStatus status = new RefactoringStatus();

+

+		if (fRoleType == null) {

+			status.merge(RefactoringStatus.createFatalErrorStatus("No target role selected."));

+		}else if (!fRoleType.exists()) {

+			status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Type ''{0}'' does not exist.", new Object[] { fRoleType

+					.getElementName() })));

+		}else if (fRoleType.isBinary()){

+			status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Type ''{0}'' is declared in a binary class file.", new Object[] { fRoleType

+					.getElementName() })));

+		}else if (fRoleType.isReadOnly()){

+			status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Type ''{0}'' is declared in a read-only file.", new Object[] { fRoleType

+					.getElementName() })));

+		}

+		

+		fRoleCUnit = fRoleType.getCompilationUnit();

+		if (fRootRole == null) {

+			fRootRole = RefactoringASTParser.parseWithASTProvider(fRoleCUnit, true, new SubProgressMonitor(pm, 99));

+		}

+		fRoleImportRewriter = StubUtility.createImportRewrite(fRootRole, true);

+		fRoleAST = fRootRole.getAST();

+		

+		if(fDeleteBaseMethod && fMappingKind != ICallinMapping.KIND_REPLACE){

+			//TODO check if base method can be deleted (no references expect the extracted method invocation)

+		}

+		

+		status.merge(checkRoleMethodName());

+		

+		status.merge(checkCallinKind());

+

+		return status;

+	}

+

+	private RefactoringStatus checkCallinKind() throws JavaModelException {

+		if (fMappingKind == 0) {

+			return RefactoringStatus.createFatalErrorStatus("Callin kind has not been specified.");

+		}

+		if (fMappingKind == ICallinMapping.KIND_BEFORE && !isExtractBeforeAvailable()) {

+			return RefactoringStatus.createFatalErrorStatus("The first statement in the base method must be a method invocation to extract a before callin.");

+		}

+		if (fMappingKind == ICallinMapping.KIND_AFTER && !isExtractAfterAvailable()) {

+			return RefactoringStatus.createFatalErrorStatus("The last statement in the base method must be a method invocation to extract an after callin.");

+		}

+		if (fMappingKind != ICallinMapping.KIND_REPLACE && fMappingKind != ICallinMapping.KIND_BEFORE && fMappingKind != ICallinMapping.KIND_AFTER) {

+			return RefactoringStatus.createFatalErrorStatus("Invalid callin kind.");

+		}

+		return new RefactoringStatus();

+	}

+

+	@Override

+	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {

+		extractCallin();

+		CompositeChange change = new CompositeChange(getName(), new TextFileChange[] { fBaseTextFileChange, fRoleTextFileChange });

+		return change;

+	}

+

+	@Override

+	public String getName() {

+		return "Extract Callin";

+	}

+	

+	@SuppressWarnings("unchecked")

+	private void extractCallin() throws CoreException {

+		fBaseRewrite = ASTRewrite.create(fBaseAST);

+		fRoleRewrite = ASTRewrite.create(fRoleAST);

+

+		MethodDeclaration baseMethodDeclaration = RefactoringUtil.methodToDeclaration(fBaseMethod, fRootBase);

+

+		List<Statement> statements = baseMethodDeclaration.getBody().statements();

+

+		fExtractedBaseMethod = null;

+

+		// change the strategy for the different mapping kinds

+		switch (fMappingKind) {

+		case ICallinMapping.KIND_BEFORE:

+			fExtractedMethodInvocation = (MethodInvocation) ((ExpressionStatement) statements.get(0)).getExpression();

+			IMethodBinding methodBinding = fExtractedMethodInvocation.resolveMethodBinding();

+			fExtractedBaseMethod = (IMethod) methodBinding.getJavaElement();

+			

+			fBaseRewrite.getListRewrite(baseMethodDeclaration.getBody(), Block.STATEMENTS_PROPERTY).remove(statements.get(0), null);

+			// TODO check for unused imports

+			break;

+		case ICallinMapping.KIND_AFTER:

+			fExtractedMethodInvocation = (MethodInvocation) ((ExpressionStatement) statements.get(statements.size() - 1)).getExpression();

+			methodBinding = fExtractedMethodInvocation.resolveMethodBinding();

+			fExtractedBaseMethod = (IMethod) methodBinding.getJavaElement();

+			

+			fBaseRewrite.getListRewrite(baseMethodDeclaration.getBody(), Block.STATEMENTS_PROPERTY).remove(statements.get(statements.size() - 1), null);

+			// TODO check for unused imports

+			break;

+		case ICallinMapping.KIND_REPLACE:

+			fExtractedBaseMethod = fBaseMethod;

+			break;

+		default:

+			break;

+		}

+

+		MethodDeclaration extractedCallin = extractCallinMethod();

+		

+		insertMethodIntoRole(extractedCallin);

+		

+		CallinMappingDeclaration callinMapping = createMethodMapping();

+		

+		appendMethodMappingToRole(callinMapping);

+		

+		if(fDeleteBaseMethod && fMappingKind != ICallinMapping.KIND_REPLACE){

+			MethodDeclaration extractedBaseMethodDecl = RefactoringUtil.methodToDeclaration(fExtractedBaseMethod, fRootBase);

+			AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) typeToDeclaration(fBaseType, fRootBase);

+			ChildListPropertyDescriptor descriptor = typeToBodyDeclarationProperty(fBaseType, fRootBase);

+			fBaseRewrite.getListRewrite(declaration, descriptor).remove(extractedBaseMethodDecl, null);

+		}

+			

+		// collect imports

+		Set<IBinding> staticImports = new HashSet<IBinding>();

+		Set<ITypeBinding> imports = new HashSet<ITypeBinding>();

+		MethodDeclaration extractedCallinMethodDeclaration = RefactoringUtil.methodToDeclaration(fExtractedBaseMethod, fRootBase);

+		ImportRewriteUtil.collectImports(fRoleType.getJavaProject(), extractedCallinMethodDeclaration, imports, staticImports, false);

+		if(fMappingKind != ICallinMapping.KIND_REPLACE)

+			ImportRewriteUtil.collectImports(fRoleType.getJavaProject(), fExtractedMethodInvocation, imports, staticImports, false);

+		for (ITypeBinding typeBinding : imports) {

+			fRoleImportRewriter.addImport(typeBinding);

+		}

+		for (IBinding binding : staticImports) {

+			fRoleImportRewriter.addStaticImport(binding);

+		}

+		

+		// create the text change for the base

+		MultiTextEdit baseMultiEdit = new MultiTextEdit();

+		baseMultiEdit.addChild(fBaseRewrite.rewriteAST());

+		fBaseTextFileChange = new TextFileChange(fBaseCUnit.getElementName(), (IFile) fBaseCUnit.getResource());

+		fBaseTextFileChange.setTextType("java");

+		fBaseTextFileChange.setEdit(baseMultiEdit);

+		

+		// create the text change for the role

+		MultiTextEdit roleMultiEdit = new MultiTextEdit();

+		roleMultiEdit.addChild(fRoleRewrite.rewriteAST());

+		fRoleTextFileChange = new TextFileChange(fRoleCUnit.getElementName(), (IFile) fRoleCUnit.getResource());

+		fRoleTextFileChange.setTextType("java");

+		fRoleTextFileChange.setEdit(roleMultiEdit);

+		

+		// Update imports

+		if (fRoleImportRewriter.hasRecordedChanges()) {

+			TextEdit edit = fRoleImportRewriter.rewriteImports(null);

+			roleMultiEdit.addChild(edit);

+			fRoleTextFileChange.addTextEditGroup(new TextEditGroup("Update Imports", new TextEdit[] { edit }));

+		}

+	}

+	

+	@SuppressWarnings("unchecked")

+	private MethodDeclaration extractCallinMethod() throws JavaModelException {

+		// copy the extracted callin to the role

+		MethodDeclaration extractedCallinMethodDeclaration = RefactoringUtil.methodToDeclaration(fExtractedBaseMethod, fRootBase);

+		MethodDeclaration copyOfExtractedCallin = (MethodDeclaration) ASTNode.copySubtree(fRoleAST, extractedCallinMethodDeclaration);

+		copyOfExtractedCallin.getName().setIdentifier(fRoleMethodName);

+

+		if (fMappingKind == ICallinMapping.KIND_REPLACE) {

+			addCallinModifier(fRoleRewrite, copyOfExtractedCallin);

+			// copyOfExtractedCallin.

+			if(!fCopyBaseMethod){

+				// remove all statments and add a base call

+				Block body = fRoleAST.newBlock();

+				BaseCallMessageSend baseCall = createBaseMethodInvocation(fRoleMethodName, fExtractedBaseMethod, fBaseMethod);

+				body.statements().add(fRoleAST.newExpressionStatement(baseCall));

+				copyOfExtractedCallin.setBody(body);

+			}

+		} else if (!Flags.isPrivate(fExtractedBaseMethod.getFlags())) {

+			changeToPrivateVisibility(fRoleRewrite, copyOfExtractedCallin);

+		}

+		return copyOfExtractedCallin;

+	}

+	

+	private BaseCallMessageSend createBaseMethodInvocation(String roleMethodName, IMethod roleMethod, IMethod baseMethod) throws JavaModelException {

+		BaseCallMessageSend baseCall = fRoleAST.newBaseCallMessageSend();

+		baseCall.setName(fRoleAST.newSimpleName(roleMethodName));

+		copyInvocationParameters(baseCall, roleMethod);

+

+		// if the role method doesn't declare the same number of parameters as

+		// the base method, the parameters have to be appended

+		int roleMethodParameterLength = roleMethod.getParameterNames().length;

+		int baseMethodParameterLength = baseMethod.getParameterNames().length;

+		if (roleMethodParameterLength < baseMethodParameterLength) {

+			appendInvocationParameters(baseCall, baseMethod, baseMethodParameterLength - roleMethodParameterLength);

+		}

+

+		return baseCall;

+	}

+	

+	static MethodSpec createMethodSpec(AST ast, ImportRewrite imports, IMethodBinding methodBinding, String[] argNames) {

+		List<SingleVariableDeclaration> args = new ArrayList<SingleVariableDeclaration>();

+		for (int i = 0; i < methodBinding.getParameterTypes().length; i++) {

+			ITypeBinding paramType = methodBinding.getParameterTypes()[i];

+			args.add(ASTNodeCreator.createArgument(ast, 0/* modifiers */, imports.addImport(paramType, ast), argNames[i], 0 /* extraDimensions */, null));

+		}

+		ITypeBinding providedReturnType = methodBinding.getReturnType();

+		Type returnType = imports.addImport(providedReturnType, ast);

+		return ASTNodeCreator.createMethodSpec(ast, methodBinding.getName(), returnType, args, true);

+	}

+

+	private void appendMethodMappingToRole(CallinMappingDeclaration callinMapping) throws JavaModelException {

+		AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) typeToDeclaration(fRoleType, fRootRole);

+		ChildListPropertyDescriptor descriptor = typeToBodyDeclarationProperty(fRoleType, fRootRole);

+		fRoleRewrite.getListRewrite(declaration, descriptor).insertLast(callinMapping, null);

+	}

+

+	@SuppressWarnings("unchecked")

+	private CallinMappingDeclaration createMethodMapping() throws JavaModelException {

+		CallinMappingDeclaration mapping = fRoleAST.newCallinMappingDeclaration();

+

+		Modifier callinModifier = createCallinModifier();

+

+		mapping.setCallinModifier(callinModifier);

+		

+		IMethodBinding roleMethodBinding = RefactoringUtil.methodToDeclaration(fExtractedBaseMethod, fRootBase).resolveBinding();

+		MethodSpec roleMethodSpec = createMethodSpec(fRoleAST, fRoleImportRewriter, roleMethodBinding, fExtractedBaseMethod.getParameterNames());

+		roleMethodSpec.setName(fRoleAST.newSimpleName(fRoleMethodName));

+		mapping.setRoleMappingElement(roleMethodSpec);

+		

+		IMethodBinding baseMethodBinding = RefactoringUtil.methodToDeclaration(fBaseMethod, fRootBase).resolveBinding();

+		MethodSpec baseMethodSpec = createMethodSpec(fRoleAST, fRoleImportRewriter, baseMethodBinding, fBaseMethod.getParameterNames());

+		mapping.getBaseMappingElements().add(baseMethodSpec);

+		

+		if (needsParameterMapping()) {

+			// parameterMapping.

+			List<SingleVariableDeclaration> parameters = roleMethodSpec.parameters();

+			for (int i = 0; i < parameters.size(); i++) {

+				SingleVariableDeclaration varDecl = parameters.get(i);

+				ParameterMapping parameterMapping = fRoleAST.newParameterMapping();

+				Expression expr = (Expression) ASTNode.copySubtree(fRoleAST, (Expression) fExtractedMethodInvocation.arguments().get(i));

+				

+				parameterMapping.setIdentifier(fRoleAST.newSimpleName(varDecl.getName().getIdentifier()));

+				parameterMapping.setExpression(expr);

+				parameterMapping.setDirection("<-");

+				mapping.getParameterMappings().add(parameterMapping);

+			}

+		}

+		return mapping;

+	}

+

+	private boolean needsParameterMapping() throws JavaModelException {

+		if (fMappingKind == ICallinMapping.KIND_REPLACE) {

+			return false;

+		}

+		if (fExtractedBaseMethod.getParameterNames().length == 0) {

+			return false;

+		}

+		if (fExtractedMethodInvocation.arguments().size() > fBaseMethod.getParameterNames().length) {

+			return true;

+		}

+		for (int i = 0; i < fExtractedMethodInvocation.arguments().size(); i++) {

+			Expression expression = (Expression) fExtractedMethodInvocation.arguments().get(i);

+			if (expression instanceof SimpleName) {

+				if (!((SimpleName) expression).getIdentifier().equals(fBaseMethod.getParameterNames()[i])) {

+					return true;

+				}

+			} else {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private Modifier createCallinModifier() {

+		switch (fMappingKind) {

+		case ICallinMapping.KIND_BEFORE:

+			return fRoleAST.newModifier(ModifierKeyword.BEFORE_KEYWORD);

+		case ICallinMapping.KIND_AFTER:

+			return fRoleAST.newModifier(ModifierKeyword.AFTER_KEYWORD);

+		case ICallinMapping.KIND_REPLACE:

+			return fRoleAST.newModifier(ModifierKeyword.REPLACE_KEYWORD);

+		default:

+			return null;

+		}

+	}

+

+	@SuppressWarnings("unchecked")

+	private void addCallinModifier(ASTRewrite astRewrite, MethodDeclaration methodDeclaration) {

+		Modifier callinModifier = fRoleAST.newModifier(ModifierKeyword.CALLIN_KEYWORD);

+

+		// add the callin modifier

+		astRewrite.getListRewrite(methodDeclaration, MethodDeclaration.MODIFIERS2_PROPERTY).insertLast(callinModifier, null);

+

+		// visibility modifiers should be removed because callin methods don't

+		// declare a visibility (OTJLD 4.2(d))

+		List<IExtendedModifier> modifiers = methodDeclaration.modifiers();

+		for (IExtendedModifier extendedModifier : modifiers) {

+			if (extendedModifier instanceof Modifier) {

+				Modifier modifier = (Modifier) extendedModifier;

+				if (Modifier.isPublic(modifier.getKeyword().toFlagValue()) || Modifier.isProtected(modifier.getKeyword().toFlagValue())

+						|| Modifier.isPrivate(modifier.getKeyword().toFlagValue())) {

+					astRewrite.getListRewrite(methodDeclaration, MethodDeclaration.MODIFIERS2_PROPERTY).remove(modifier, null);

+					break;

+				}

+			}

+		}

+	}

+

+	private void insertMethodIntoRole(MethodDeclaration methodDeclaration) throws JavaModelException {

+		AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) typeToDeclaration(fRoleType, fRootRole);

+		ChildListPropertyDescriptor descriptor = typeToBodyDeclarationProperty(fRoleType, fRootRole);

+		fRoleRewrite.getListRewrite(declaration, descriptor).insertLast(methodDeclaration, null);

+	}

+

+	/**

+	 * Replaces <code>public</code> and <code>protected</code> by a

+	 * <code>private</code> modifier. If the method has default visibility

+	 * <code>private</code> modifier will be prepended to the modifier list.

+	 * 

+	 * @param rewrite

+	 *            the rewrite that notes the changes

+	 * @param methodDeclaration

+	 *            the method declaration to be changed

+	 */

+	@SuppressWarnings("unchecked")

+	private void changeToPrivateVisibility(ASTRewrite astRewrite, MethodDeclaration methodDeclaration) {

+		Modifier privateVisibility = methodDeclaration.getAST().newModifier(ModifierKeyword.PRIVATE_KEYWORD);

+		

+		List<IExtendedModifier> modifiers = methodDeclaration.modifiers();

+		for (IExtendedModifier extendedModifier : modifiers) {

+			if (extendedModifier instanceof Modifier) {

+				Modifier modifier = (Modifier) extendedModifier;

+				if (Modifier.isPublic(modifier.getKeyword().toFlagValue())) {

+					astRewrite.replace(modifier, privateVisibility, null);

+					return;

+				}

+				if (Modifier.isProtected(modifier.getKeyword().toFlagValue())) {

+					astRewrite.replace(modifier, privateVisibility, null);

+					return;

+				}

+				if (Modifier.isPrivate(modifier.getKeyword().toFlagValue())) {

+					// don't replace private modifiers or create a 2nd private

+					// modifier

+					return;

+				}

+			}

+		}

+		// no visibility modifier was found => default visibility will be

+		// reduced to private

+		astRewrite.getListRewrite(methodDeclaration, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(privateVisibility, null);

+	}

+	

+	@SuppressWarnings("unchecked")

+	private void copyInvocationParameters(BaseCallMessageSend baseCall, IMethod method) throws JavaModelException {

+		String[] names = method.getParameterNames();

+		for (String element : names)

+			baseCall.getArguments().add(fRoleAST.newSimpleName(element));

+	}

+

+	/**

+	 * Appends invocation parameter names from the given method from the given

+	 * offset. This method is used to extend base method calls if the role

+	 * method declares fewer parameters than the base method.

+	 * 

+	 * @param baseCall

+	 *            the base call invocation to receive the parameters

+	 * @param method

+	 *            the method that declares the parameters

+	 * @param offset

+	 *            the offset to begin to copy

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private void appendInvocationParameters(BaseCallMessageSend baseCall, IMethod method, int offset) throws JavaModelException {

+		String[] names = method.getParameterNames();

+

+		for (int i = offset; i < names.length; i++) {

+			String name = names[i];

+			baseCall.getArguments().add(fBaseAST.newSimpleName(name));

+		}

+

+	}

+

+	@SuppressWarnings("rawtypes")

+	private ASTNode getParent(ASTNode node, Class parentClass) {

+		do {

+			node = node.getParent();

+		} while (node != null && !parentClass.isInstance(node));

+		return node;

+	}

+

+	private ASTNode typeToDeclaration(IType type, CompilationUnit node) throws JavaModelException {

+		Name result = (Name) NodeFinder.perform(node, type.getNameRange());

+		if (type.isAnonymous())

+			return getParent(result, AnonymousClassDeclaration.class);

+		return getParent(result, AbstractTypeDeclaration.class);

+	}

+	

+	private ChildListPropertyDescriptor typeToBodyDeclarationProperty(IType type, CompilationUnit node) throws JavaModelException {

+		ASTNode result = typeToDeclaration(type, node);

+		if (result instanceof AbstractTypeDeclaration)

+			return ((AbstractTypeDeclaration) result).getBodyDeclarationsProperty();

+		else if (result instanceof AnonymousClassDeclaration)

+			return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;

+

+		Assert.isTrue(false);

+		return null;

+	}

+	

+	private ArrayList<IRoleType> findCandidateRoles() throws CoreException {

+		ArrayList<IRoleType> boundRoles = RefactoringUtil.getAllRolesForBase(fBaseType);

+		List<IRoleType> rolesToRemove = new ArrayList<IRoleType>();

+		for (IRoleType boundRole : boundRoles) {

+			if(!boundRole.exists() || boundRole.isReadOnly() || boundRole.isBinary()){

+				rolesToRemove.add(boundRole);

+			}

+		}

+		boundRoles.removeAll(rolesToRemove);

+		return boundRoles;

+	}

+

+	public IMethod[] getBoundBaseMethods() throws JavaModelException {

+		List<IMethod> boundBaseMethods = new ArrayList<IMethod>();

+		for (ICallinMapping mapping : fBoundCallinMappings) {

+			boundBaseMethods.addAll(Arrays.asList(mapping.getBoundBaseMethods()));

+		}

+		return boundBaseMethods.toArray(new IMethod[boundBaseMethods.size()]);

+	}

+

+	public List<ICallinMapping> getBoundCallinMappings() {

+		return fBoundCallinMappings;

+	}

+

+	public void setRoleMethodName(String name) {

+		fRoleMethodName = name;

+	}

+

+	private RefactoringStatus checkIfMethodExists() {

+		try {

+			if (methodWithNameExists(fRoleType, fRoleMethodName)) {

+				return RefactoringStatus.createErrorStatus(MessageFormat.format("A method with the same name already exists.", fRoleMethodName));

+			}

+		} catch (JavaModelException exception) {

+			return RefactoringStatus.createFatalErrorStatus("Could not perform the search for binding role types.");

+		}

+		return new RefactoringStatus();

+	}

+	

+	private RefactoringStatus createCouldNotParseStatus() {

+		return RefactoringStatus.createFatalErrorStatus("Could not parse the declaring type.");

+	}

+

+	private boolean methodWithNameExists(IType type, String methodName) throws JavaModelException {

+		IMethod[] methods = type.getMethods();

+		for (IMethod method : methods) {

+			if (method.getElementName().equals(methodName))

+				return true;

+		}

+		return false;

+	}

+

+	@SuppressWarnings("unchecked")

+	public boolean isExtractBeforeAvailable() {

+		List<Statement> statements = fBaseMethodDeclaration.getBody().statements();

+		if (statements.isEmpty()) {

+			return false;

+		}

+		if(statements.get(0) instanceof ExpressionStatement 

+			&& ((ExpressionStatement) statements.get(0)).getExpression() instanceof MethodInvocation) {

+				MethodInvocation invocation = (MethodInvocation) ((ExpressionStatement) statements.get(0)).getExpression();

+				Expression receiver = invocation.getExpression();

+				boolean isSelfcall = false;

+				if (receiver == null) {

+					isSelfcall = true;

+				} else if (receiver instanceof ThisExpression) {

+					isSelfcall = ((ThisExpression)receiver).getQualifier() == null;

+				}

+				if (isSelfcall)

+					return !((IMethod)invocation.resolveMethodBinding().getJavaElement()).getDeclaringType().isBinary();

+		}

+		return false;

+	}

+	

+	@SuppressWarnings("unchecked")

+	public boolean isExtractAfterAvailable() {

+		List<Statement> statements = fBaseMethodDeclaration.getBody().statements();

+		if (statements.isEmpty()) {

+			return false;

+		}

+		if (statements.get(statements.size() - 1) instanceof ExpressionStatement

+				&& ((ExpressionStatement) statements.get(statements.size() - 1)).getExpression() instanceof MethodInvocation) {

+			MethodInvocation invocation = (MethodInvocation) ((ExpressionStatement) statements.get(statements.size() - 1)).getExpression();

+			if (((IMethod) invocation.resolveMethodBinding().getJavaElement()).getDeclaringType().equals(fBaseType)) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	RefactoringStatus checkRoleMethodName() {

+		RefactoringStatus status = new RefactoringStatus();

+		status.merge(checkIfMethodExists());

+		status.merge(checkMethodName(fRoleMethodName));

+		return status;

+	}

+

+	private RefactoringStatus checkMethodName(String name) {

+		RefactoringStatus result = new RefactoringStatus();

+

+		if (name == null)

+			return RefactoringStatus.createFatalErrorStatus("No new role method name specified.");

+

+		if ("".equals(name)) //$NON-NLS-1$

+			return RefactoringStatus.createFatalErrorStatus("New role method name cannot be empty.");

+

+		IJavaProject javaProject = this.fRoleType.getJavaProject();

+		String sourceLevel= javaProject.getOption(JavaCore.COMPILER_SOURCE, true);

+		String complianceLevel= javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);

+		IStatus status = JavaConventions.validateMethodName(name, sourceLevel, complianceLevel);

+		if (status.isOK())

+			return result;

+

+		switch (status.getSeverity()) {

+		case IStatus.ERROR:

+			return RefactoringStatus.createFatalErrorStatus(status.getMessage());

+		case IStatus.WARNING:

+			return RefactoringStatus.createWarningStatus(status.getMessage());

+		case IStatus.INFO:

+			return RefactoringStatus.createInfoStatus(status.getMessage());

+		default: // no nothing

+			return new RefactoringStatus();

+		}

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinWizard.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinWizard.java
new file mode 100644
index 0000000..3b18686
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/extractcallin/ExtractCallinWizard.java
@@ -0,0 +1,16 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin;

+

+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;

+

+public class ExtractCallinWizard extends RefactoringWizard {

+

+	public ExtractCallinWizard(ExtractCallinRefactoring refactoring, String pageTitle) {

+		super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);

+		setDefaultPageTitle(pageTitle);

+	}

+

+	@Override

+	protected void addUserInputPages() {

+		addPage(new ExtractCallinInputPage("ExtractCallinInputPage"));

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/CallinBaseMethodInfo.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/CallinBaseMethodInfo.java
new file mode 100644
index 0000000..8622913
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/CallinBaseMethodInfo.java
@@ -0,0 +1,38 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin;

+

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+

+/**

+ * @author Johannes Gebauer

+ * 

+ */

+public class CallinBaseMethodInfo {

+

+	private IMethod _method;

+	private ICallinMapping _callinMapping;

+	private String _newMethodName;

+

+	public CallinBaseMethodInfo(IMethod _method, ICallinMapping mapping) {

+		super();

+		this._method = _method;

+		this._callinMapping = mapping;

+	}

+

+	public IMethod getMethod() {

+		return _method;

+	}

+

+	public ICallinMapping getCallinMapping() {

+		return _callinMapping;

+	}

+

+	public void setNewMethodName(String _newMethodName) {

+		this._newMethodName = _newMethodName;

+	}

+

+	public String getNewMethodName() {

+		return _newMethodName;

+	}

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinAction.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinAction.java
new file mode 100644
index 0000000..5730bb9
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinAction.java
@@ -0,0 +1,95 @@
+/**********************************************************************

+ * This file is part of "Object Teams Development Tooling"-Software

+ * 

+ * Copyright 2009 Johannes Gebauer and Stephan Herrmann.

+ * 

+ * 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: InlineCallinAction.java 23473 2010-02-05 19:46:08Z stephan $

+ * 

+ * Please visit http://www.objectteams.org for updates and contact.

+ * 

+ * Contributors:

+ * 		Johannes Gebauer - Initial API and implementation

+ * 		Stephan Herrmann - Initial API and implementation

+ **********************************************************************/

+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin;

+

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.IWorkbenchWindowActionDelegate;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+import org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.AbstractCallinRefactoringAction;

+

+/**

+ * Action classes for the inline callin refactoring:

+ * <ul>

+ * <li>The toplevel class provides the action to the main menu bar (registered via plugin.xml).</li>

+ * <li>Inherited nested class {@link SelectionDispatchAction} provides the action to context menus of all views.</li>

+ * <li>Nested class {@link InlineCallinActionCommon} implements the shared stateful part of both actions.</li>

+ * </ul>

+ */

+@SuppressWarnings("restriction")

+public class InlineCallinAction extends AbstractCallinRefactoringAction implements IWorkbenchWindowActionDelegate 

+{	

+	/** 

+	 * Fill inherited class {@link CallinRefactoringActionCommon} with details.

+	 */

+	class InlineCallinActionCommon extends CallinRefactoringActionCommon

+	{

+		InlineCallinActionCommon(JavaEditor editor) {

+			super(editor);

+		}

+		

+		InlineCallinActionCommon(IWorkbenchWindow window) {

+			super(window);

+		}

+

+		protected void filterElements(Object[] elements) {

+			this.fJavaElement = null;

+			if (elements == null || elements.length != 1)

+				return;

+			else if (elements[0] instanceof IMethod)

+				this.fJavaElement = (IMethod) elements[0];

+			else if (elements[0] instanceof ICallinMapping)

+				this.fJavaElement = ((ICallinMapping)elements[0]).getRoleMethod();

+		}

+

+		protected void doRun() {

+			if (fJavaElement != null && fWindow != null) {

+				try {

+					new RefactoringWizardOpenOperation(

+							new InlineCallinWizard(

+									new InlineCallinRefactoring((IMethod)fJavaElement), 

+									"Inline Callin"

+							)

+					).run(fWindow.getShell(), "Inline Callin");

+				} catch (InterruptedException exception) {

+					// Do nothing

+				}

+			} else {

+				MessageDialog.openInformation(null, "Inline Callin", "Operation unavailable on the current selection. Select a callin-bound role method or a callin method binding");

+			}		

+		}

+	}

+	

+	

+	// =========== Start InlineCallinAction ===========

+	

+	public InlineCallinAction () {

+		super("Inline Callin ...", "Inline a callin-bound role meth.");

+	}

+

+	protected CallinRefactoringActionCommon createRefactoringActionCommon(IWorkbenchWindow window) {

+		return new InlineCallinActionCommon(window);

+	}

+

+	protected CallinRefactoringActionCommon createRefactoringActionCommon(JavaEditor editor) {

+		return new InlineCallinActionCommon(editor);

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinInputPage.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinInputPage.java
new file mode 100644
index 0000000..d533d0c
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinInputPage.java
@@ -0,0 +1,294 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.jdt.internal.ui.util.SWTUtil;

+import org.eclipse.jdt.internal.ui.util.TableLayoutComposite;

+import org.eclipse.jdt.ui.JavaElementLabelProvider;

+import org.eclipse.jface.viewers.ArrayContentProvider;

+import org.eclipse.jface.viewers.CheckStateChangedEvent;

+import org.eclipse.jface.viewers.CheckboxTableViewer;

+import org.eclipse.jface.viewers.ColumnWeightData;

+import org.eclipse.jface.viewers.ICheckStateListener;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.ISelectionChangedListener;

+import org.eclipse.jface.viewers.ITableLabelProvider;

+import org.eclipse.jface.viewers.LabelProvider;

+import org.eclipse.jface.viewers.SelectionChangedEvent;

+import org.eclipse.jface.viewers.TableLayout;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.events.ModifyEvent;

+import org.eclipse.swt.events.ModifyListener;

+import org.eclipse.swt.events.SelectionAdapter;

+import org.eclipse.swt.events.SelectionEvent;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.swt.widgets.Table;

+import org.eclipse.swt.widgets.TableColumn;

+import org.eclipse.swt.widgets.Text;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+

+@SuppressWarnings("restriction")

+public class InlineCallinInputPage extends UserInputWizardPage {

+

+

+	Text fNameField;

+

+	private CheckboxTableViewer fTableViewer;

+

+	private Label fLabel;

+

+	private Button fReferenceButton;

+

+	public InlineCallinInputPage(String name) {

+		super(name);

+	}

+

+	public void createControl(Composite parent) {

+		Composite result = new Composite(parent, SWT.NONE);

+

+		setControl(result);

+

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 2;

+		result.setLayout(layout);

+

+		Label label = new Label(result, SWT.NONE);

+		label.setText("&Inlined method name:");

+

+		fNameField = createNameField(result);

+

+		createMemberTableLabel(result);

+		createMemberTableComposite(result);

+		

+		fReferenceButton = new Button(result, SWT.CHECK);

+		fReferenceButton.setEnabled(false);

+		fReferenceButton.setText("&Delete role method");

+		GridData data = new GridData(GridData.FILL_HORIZONTAL);

+		data.horizontalSpan = 2;

+		data.verticalIndent = 2;

+		fReferenceButton.setLayoutData(data);

+

+

+		final InlineCallinRefactoring refactoring = getInlineCallinRefactoring();

+		fNameField.setText(refactoring.getRoleMethod().getElementName());

+

+		fNameField.addModifyListener(new ModifyListener() {

+

+			public void modifyText(ModifyEvent event) {

+				handleInputChanged();

+			}

+		});

+

+		fReferenceButton.addSelectionListener(new SelectionAdapter() {

+

+			@Override

+			public void widgetSelected(SelectionEvent event) {

+				refactoring.setDeleteRoleMethod(fReferenceButton.getSelection());

+			}

+		});

+

+		fNameField.setFocus();

+		fNameField.selectAll();

+		handleInputChanged();

+		fReferenceButton.setSelection(false);

+	}

+

+	private Text createNameField(Composite result) {

+		Text field = new Text(result, SWT.SINGLE | SWT.LEFT | SWT.BORDER);

+		field.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

+		return field;

+	}

+

+	private InlineCallinRefactoring getInlineCallinRefactoring() {

+		return (InlineCallinRefactoring) getRefactoring();

+	}

+

+	void handleInputChanged() {

+		fReferenceButton.setEnabled(allBaseMethodSelected());

+		

+		RefactoringStatus status = new RefactoringStatus();

+		InlineCallinRefactoring refactoring = getInlineCallinRefactoring();

+		refactoring.setRoleMethodName(fNameField.getText());

+		status.merge(refactoring.checkRoleMethodName());

+		

+		setSelectedBaseMethods(refactoring);

+		status.merge(refactoring.checkBaseMethods());

+

+		setPageComplete(!status.hasError());

+		int severity = status.getSeverity();

+		String message = status.getMessageMatchingSeverity(severity);

+		if (severity >= RefactoringStatus.INFO) {

+			setMessage(message, severity);

+		} else {

+			setMessage("", NONE); //$NON-NLS-1$

+		}

+	}

+

+	private void setSelectedBaseMethods(InlineCallinRefactoring refactoring) {

+		CallinBaseMethodInfo[] baseMethodInfos = getTableInput();

+		List<CallinBaseMethodInfo> baseMethods = new ArrayList<CallinBaseMethodInfo>();

+		for (int i = 0; i < baseMethodInfos.length; i++) {

+			if (fTableViewer.getChecked(baseMethodInfos[i]))

+				baseMethods.add(baseMethodInfos[i]);

+		}

+		refactoring.setBaseMethods(baseMethods.toArray(new CallinBaseMethodInfo[baseMethods.size()]));

+	}

+	

+	private CallinBaseMethodInfo[] getTableInput() {

+		return (CallinBaseMethodInfo[]) fTableViewer.getInput();

+	}

+

+	private boolean allBaseMethodSelected() {

+		boolean selected = true;

+		Object[] baseMethods = (Object[]) fTableViewer.getInput();

+		for (int i = 0; i < baseMethods.length; i++) {

+			selected = selected && fTableViewer.getChecked(baseMethods[i]); 

+		}

+		return selected;

+	}

+

+	protected void createMemberTableLabel(final Composite parent) {

+		fLabel = new Label(parent, SWT.NONE);

+		fLabel.setText("&Select the bound base methods:");

+		final GridData data = new GridData();

+		data.horizontalSpan = 2;

+		fLabel.setLayoutData(data);

+	}

+	

+	protected void createMemberTableComposite(final Composite parent) {

+		final Composite composite = new Composite(parent, SWT.NONE);

+		final GridData data = new GridData(GridData.FILL_BOTH);

+		data.horizontalSpan = 2;

+		composite.setLayoutData(data);

+		final GridLayout layout = new GridLayout();

+		layout.numColumns = 1;

+		layout.marginWidth = 0;

+		layout.marginHeight = 0;

+		composite.setLayout(layout);

+

+		createBaseMethodsTable(composite);

+	}

+	

+	private void createBaseMethodsTable(final Composite parent) {

+		final TableLayoutComposite layouter = new TableLayoutComposite(parent, SWT.NONE);

+		layouter.addColumnData(new ColumnWeightData(60, true));

+		layouter.addColumnData(new ColumnWeightData(40, true));

+

+		final Table table = new Table(layouter, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK);

+		table.setHeaderVisible(true);

+		table.setLinesVisible(true);

+

+		final GridData gd = new GridData(GridData.FILL_BOTH);

+		gd.heightHint = SWTUtil.getTableHeightHint(table, 10);

+		gd.widthHint = convertWidthInCharsToPixels(30);

+		layouter.setLayoutData(gd);

+

+		final TableLayout tableLayout = new TableLayout();

+		table.setLayout(tableLayout);

+

+		final TableColumn column0 = new TableColumn(table, SWT.NONE);

+		column0.setText("Base Method");

+

+		final TableColumn column1 = new TableColumn(table, SWT.NONE);

+		column1.setText("Callin Kind");

+

+		fTableViewer = new CheckboxTableViewer(table);

+		fTableViewer.setUseHashlookup(true);

+		fTableViewer.setContentProvider(new ArrayContentProvider());

+		fTableViewer.setLabelProvider(new BaseMethodInfoLabelProvider());

+		fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {

+

+			public void selectionChanged(final SelectionChangedEvent event) {

+				handleInputChanged();

+			}

+		});

+		fTableViewer.addCheckStateListener(new ICheckStateListener() {

+

+			public void checkStateChanged(final CheckStateChangedEvent event) {

+				updateWizardPage(null, true);

+			}

+		});

+

+		setTableInput();

+	}

+

+	private static class BaseMethodInfoLabelProvider extends LabelProvider implements ITableLabelProvider {

+

+		private static final String BEFORE_LABEL = "Before";

+		private static final String AFTER_LABEL = "After";

+		private static final String REPLACE_LABEL = "Replace";

+		

+		private static final int CALLIN_KIND_COLUMN = 1;

+		private static final int METHOD_COLUMN = 0;

+		

+		private final ILabelProvider fLabelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT

+				| JavaElementLabelProvider.SHOW_SMALL_ICONS);

+

+		public void dispose() {

+			super.dispose();

+			fLabelProvider.dispose();

+		}

+

+		public Image getColumnImage(final Object element, final int columnIndex) {

+			final CallinBaseMethodInfo info = (CallinBaseMethodInfo) element;

+			switch (columnIndex) {

+			case METHOD_COLUMN:

+				return fLabelProvider.getImage(info.getMethod());

+			case CALLIN_KIND_COLUMN:

+				return null;

+			default:

+				return null;

+			}

+		}

+

+		public String getColumnText(final Object element, final int columnIndex) {

+			final CallinBaseMethodInfo info = (CallinBaseMethodInfo) element;

+			switch (columnIndex) {

+			case METHOD_COLUMN:

+				return fLabelProvider.getText(info.getMethod());

+			case CALLIN_KIND_COLUMN:

+				return createCallinLabel(info.getCallinMapping().getCallinKind());

+			default:

+				return null;

+			}

+		}

+

+		public String createCallinLabel(int callinKind) {

+			switch (callinKind) {

+			case ICallinMapping.KIND_BEFORE:

+				return BEFORE_LABEL;

+			case ICallinMapping.KIND_AFTER:

+				return AFTER_LABEL;

+			case ICallinMapping.KIND_REPLACE:

+				return REPLACE_LABEL;

+			default:

+				return null;

+			}

+		}

+	}

+

+	private CallinBaseMethodInfo[] getBaseMethodInfos() {

+		return getInlineCallinRefactoring().getBaseMethodInfos();

+	}

+

+	private void setTableInput() {

+		fTableViewer.setInput(getBaseMethodInfos());

+	}

+

+	private void updateWizardPage(final ISelection selection, final boolean displayErrors) {

+		fTableViewer.refresh();

+		if (selection != null) {

+			fTableViewer.getControl().setFocus();

+			fTableViewer.setSelection(selection);

+		}

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinRefactoring.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinRefactoring.java
new file mode 100644
index 0000000..8bbed68
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinRefactoring.java
@@ -0,0 +1,1550 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin;

+

+import java.text.MessageFormat;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.core.runtime.SubProgressMonitor;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IField;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.core.IMember;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.JavaConventions;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.core.Signature;

+import org.eclipse.jdt.core.dom.AST;

+import org.eclipse.jdt.core.dom.ASTNode;

+import org.eclipse.jdt.core.dom.ASTVisitor;

+import org.eclipse.jdt.core.dom.AbstractMethodMappingDeclaration;

+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;

+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;

+import org.eclipse.jdt.core.dom.Assignment;

+import org.eclipse.jdt.core.dom.BaseCallMessageSend;

+import org.eclipse.jdt.core.dom.Block;

+import org.eclipse.jdt.core.dom.CallinMappingDeclaration;

+import org.eclipse.jdt.core.dom.CalloutMappingDeclaration;

+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;

+import org.eclipse.jdt.core.dom.CompilationUnit;

+import org.eclipse.jdt.core.dom.Expression;

+import org.eclipse.jdt.core.dom.IBinding;

+import org.eclipse.jdt.core.dom.IExtendedModifier;

+import org.eclipse.jdt.core.dom.IMethodBinding;

+import org.eclipse.jdt.core.dom.ITypeBinding;

+import org.eclipse.jdt.core.dom.MethodDeclaration;

+import org.eclipse.jdt.core.dom.MethodInvocation;

+import org.eclipse.jdt.core.dom.MethodSpec;

+import org.eclipse.jdt.core.dom.Modifier;

+import org.eclipse.jdt.core.dom.ParameterMapping;

+import org.eclipse.jdt.core.dom.PrimitiveType;

+import org.eclipse.jdt.core.dom.ReturnStatement;

+import org.eclipse.jdt.core.dom.SimpleName;

+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;

+import org.eclipse.jdt.core.dom.Statement;

+import org.eclipse.jdt.core.dom.Type;

+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

+import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;

+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;

+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;

+import org.eclipse.jdt.core.search.IJavaSearchConstants;

+import org.eclipse.jdt.core.search.IJavaSearchScope;

+import org.eclipse.jdt.core.search.SearchEngine;

+import org.eclipse.jdt.core.search.SearchMatch;

+import org.eclipse.jdt.core.search.SearchParticipant;

+import org.eclipse.jdt.core.search.SearchPattern;

+import org.eclipse.jdt.core.search.SearchRequestor;

+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;

+import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;

+import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRewriteUtil;

+import org.eclipse.jdt.internal.corext.refactoring.structure.ReferenceFinderUtil;

+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;

+import org.eclipse.jdt.internal.corext.util.Messages;

+import org.eclipse.jdt.ui.JavaElementLabels;

+import org.eclipse.ltk.core.refactoring.Change;

+import org.eclipse.ltk.core.refactoring.CompositeChange;

+import org.eclipse.ltk.core.refactoring.Refactoring;

+import org.eclipse.ltk.core.refactoring.RefactoringStatus;

+import org.eclipse.ltk.core.refactoring.TextFileChange;

+import org.eclipse.text.edits.MultiTextEdit;

+import org.eclipse.text.edits.TextEdit;

+import org.eclipse.text.edits.TextEditGroup;

+import org.eclipse.objectteams.otdt.core.ICallinMapping;

+import org.eclipse.objectteams.otdt.core.ICalloutMapping;

+import org.eclipse.objectteams.otdt.core.ICalloutToFieldMapping;

+import org.eclipse.objectteams.otdt.core.IMethodMapping;

+import org.eclipse.objectteams.otdt.core.IOTJavaElement;

+import org.eclipse.objectteams.otdt.core.IRoleType;

+import org.eclipse.objectteams.otdt.core.OTModelManager;

+import org.eclipse.objectteams.otdt.internal.refactoring.corext.rename.BaseCallFinder;

+import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

+

+@SuppressWarnings("restriction")

+public class InlineCallinRefactoring extends Refactoring {

+	

+	private IMethod fRoleMethod;

+	

+	private String fRoleMethodName;

+	

+	private CallinBaseMethodInfo[] fCallinBaseMethodInfos;

+

+	private boolean fDeleteRoleMethod;

+

+	private CompilationUnit fRootBase;

+

+	private AST fBaseAST;

+

+	private ImportRewrite fBaseImportRewriter;

+

+	private ICompilationUnit fBaseCUnit;

+	

+	private CallinBaseMethodInfo[] fTargetBaseMethods;

+

+	private ICompilationUnit fRoleCUnit;

+

+	private CompilationUnit fRootRole;

+

+	private AST fRoleAST;

+

+	private IType fRoleType;

+

+	private TextFileChange fBaseTextFileChange;

+

+	private TextFileChange fRoleTextFileChange;

+

+	private List<ICallinMapping> fBoundCallinMappings;

+

+	private IType fBaseType;

+

+	private ASTRewrite fBaseRewrite;

+

+	private ASTRewrite fRoleRewrite;

+

+	private Object fCachedBaseMethodInfo = null;

+

+	private Set<String> fCachedTunneledParameters = null;

+	

+	public InlineCallinRefactoring() {

+	}

+

+	public InlineCallinRefactoring(IMethod roleMethod) {

+		fRoleMethod = roleMethod;

+	}

+

+	public InlineCallinRefactoring(IMethod roleMethod, ICallinMapping[] callinMapping, IMethod[] baseMethods) {

+		fBaseType = baseMethods[0].getDeclaringType();

+		

+		List<CallinBaseMethodInfo> methodInfos = new ArrayList<CallinBaseMethodInfo>();

+		for (int i = 0; i < baseMethods.length; i++) {

+			methodInfos.add(new CallinBaseMethodInfo(baseMethods[i], callinMapping[i]));

+		}

+		setBaseMethods(methodInfos.toArray(new CallinBaseMethodInfo[methodInfos.size()]));

+

+		fRoleMethod = roleMethod;

+	}

+

+	public IMethod getRoleMethod() {

+		return fRoleMethod;

+	}

+	

+	public IMethod[] getBoundBaseMethods() throws JavaModelException {

+		List<IMethod> boundBaseMethods = new ArrayList<IMethod>();

+		for (ICallinMapping mapping : fBoundCallinMappings) {

+			boundBaseMethods.addAll(Arrays.asList(mapping.getBoundBaseMethods()));

+		}

+		return boundBaseMethods.toArray(new IMethod[boundBaseMethods.size()]);

+	}

+

+	public List<ICallinMapping> getBoundCallinMappings() {

+		return fBoundCallinMappings;

+	}

+

+	@Override

+	public String getName() {

+		return "Inline Callin";

+	}

+

+	public void setRoleMethodName(String name) {

+		fRoleMethodName = name;

+	}

+

+	public CallinBaseMethodInfo[] getBaseMethodInfos() {

+		return fCallinBaseMethodInfos;

+	}

+

+	public void setBaseMethods(CallinBaseMethodInfo[] baseMethods) {

+		fTargetBaseMethods = baseMethods;

+	}

+

+	public void setDeleteRoleMethod(boolean deleteRoleMethod) {

+		fDeleteRoleMethod = deleteRoleMethod;

+	}

+

+	@Override

+	public RefactoringStatus checkInitialConditions(IProgressMonitor monitor) throws CoreException, OperationCanceledException {

+		RefactoringStatus status= new RefactoringStatus();

+		

+		try {

+			monitor.beginTask("Checking preconditions...", 1);

+			if (fRoleMethod == null){

+				status.merge(RefactoringStatus.createFatalErrorStatus("Method has not been specified."));

+			}else if (!fRoleMethod.exists()){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' does not exist.", new Object[] { fRoleMethod

+						.getElementName() })));

+			}else if (fRoleMethod.isBinary()){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' is declared in a binary class file.", new Object[] { fRoleMethod

+						.getElementName() })));

+			}else if (fRoleMethod.isReadOnly()){

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Method ''{0}'' is declared in a read-only class file.", new Object[] { fRoleMethod

+						.getElementName() })));

+			}else if (!fRoleMethod.getCompilationUnit().isStructureKnown()){

+					status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("Compilation unit ''{0}'' contains compile errors.",

+							new Object[] { fRoleMethod.getCompilationUnit().getElementName() })));

+			} else if (!RefactoringUtil.isRoleMethod(fRoleMethod)) {

+				status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format("The selected method ''{0}'' is not declared in a role.",

+						new Object[] { fRoleMethod.getElementName() })));

+			}else{ 

+					status.merge(initialize(monitor));

+			}

+		} finally {

+			monitor.done();

+		}

+		return status;

+	}	

+	

+	private RefactoringStatus initialize(IProgressMonitor monitor) {

+		RefactoringStatus status = new RefactoringStatus();

+		fRoleMethodName = fRoleMethod.getElementName();

+		fRoleType = fRoleMethod.getDeclaringType();

+		fRoleCUnit = fRoleMethod.getCompilationUnit();

+

+		if (fRootRole == null) {

+			fRootRole = RefactoringASTParser.parseWithASTProvider(fRoleCUnit, true, new SubProgressMonitor(monitor, 99));

+		}

+

+		fRoleAST = fRootRole.getAST();

+		

+		try {

+			IType baseType = ((IRoleType) OTModelManager.getOTElement(fRoleMethod.getDeclaringType())).getBaseClass();

+			if (baseType.isBinary()) {

+				status.merge(RefactoringStatus.createFatalErrorStatus("Base class "+baseType.getElementName()+" is a binary type, cannot modify."));

+				return status;

+			}

+			if(baseType.isReadOnly()){

+				status.merge(RefactoringStatus.createFatalErrorStatus("Base class "+baseType.getElementName()+" is read-only, cannot modify."));

+				return status;

+			}

+			if (baseType != null) {

+				fBaseType = baseType;

+				fBaseCUnit = baseType.getCompilationUnit();

+

+				if (fRootBase == null) {

+					fRootBase = RefactoringASTParser.parseWithASTProvider(fBaseCUnit, true, new SubProgressMonitor(monitor, 99));

+				}

+				

+				fBaseImportRewriter = StubUtility.createImportRewrite(fRootBase, true);

+				fBaseAST = fRootBase.getAST();

+			} else {

+				status.merge(RefactoringStatus.createFatalErrorStatus("The declaring role class is not bound to a base class."));

+			}

+		} catch (JavaModelException e) {

+			status.merge(createCouldNotParseStatus());

+		}

+		if (status.hasFatalError()) {

+			return status;

+		}

+		

+		IMethodMapping[] callinMappings = ((IRoleType) OTModelManager.getOTElement(fRoleType)).getMethodMappings(IRoleType.CALLINS);

+

+		fBoundCallinMappings = new ArrayList<ICallinMapping>();

+

+		for (int i = 0; i < callinMappings.length; i++) {

+			if (callinMappings[i].getRoleMethod().equals(fRoleMethod)) {

+				fBoundCallinMappings.add((ICallinMapping) callinMappings[i]);

+			}

+		}

+

+		if (fBoundCallinMappings.size() == 0) {

+			status.merge(RefactoringStatus.createFatalErrorStatus(MessageFormat.format(

+					"The selected method ''{0}'' is not bound on the left hand side of a callin method binding.", new Object[] { fRoleMethod

+							.getElementName() })));

+		}

+		

+		List<CallinBaseMethodInfo> infos = new ArrayList<CallinBaseMethodInfo>();

+

+		for (ICallinMapping mapping : fBoundCallinMappings) {

+			try {

+				for (IMethod method : mapping.getBoundBaseMethods()) {

+					infos.add(new CallinBaseMethodInfo(method, mapping));

+				}

+				fCallinBaseMethodInfos = infos.toArray(new CallinBaseMethodInfo[infos.size()]);

+			} catch (JavaModelException e) {

+				status.merge(RefactoringStatus.createFatalErrorStatus("Could not parse the method mappings."));

+			}

+		}

+		return status;

+	}

+	

+	@Override

+	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {

+		RefactoringStatus status = new RefactoringStatus();

+		

+		status.merge(checkBaseMethods());

+		

+		if (status.hasFatalError()) {

+			return status;

+		}

+

+		status.merge(generateNewBaseMethodNames());

+		

+		status.merge(checkRoleMethodName());

+		

+		status.merge(checkDependenciesToRole(pm));

+		

+		status.merge(checkRoleMethodReferences(pm));

+

+		return status;

+	}

+

+	private RefactoringStatus checkRoleMethodReferences(IProgressMonitor pm) throws CoreException {

+		// search all references for the role method

+		final Set<SearchMatch> references = new HashSet<SearchMatch>();

+		IJavaSearchScope scope = SearchEngine.createWorkspaceScope();

+		SearchPattern pattern = SearchPattern.createPattern(fRoleMethod, IJavaSearchConstants.REFERENCES, SearchPattern.R_EXACT_MATCH);

+		SearchEngine engine = new SearchEngine();

+		engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, new SearchRequestor() {

+			@Override

+			public void acceptSearchMatch(SearchMatch match) throws CoreException {

+				if (match.getAccuracy() == SearchMatch.A_ACCURATE && !match.isInsideDocComment()) {

+					references.add(match);

+				}

+			}

+		}, pm);

+		

+		RefactoringStatus status = new RefactoringStatus();

+		

+		List<ICallinMapping> inlinedCallins = new ArrayList<ICallinMapping>();

+		for (int i = 0; i < fCallinBaseMethodInfos.length; i++) {

+			inlinedCallins.add(fCallinBaseMethodInfos[i].getCallinMapping());

+		}

+

+		for (SearchMatch match : references) {

+			Object element= match.getElement();

+			if (element instanceof ICallinMapping) {

+				ICallinMapping mapping = (ICallinMapping) element;

+				if(mapping.getRoleMethod().equals(fRoleMethod)){

+					if(inlinedCallins.contains(mapping)){

+						continue;

+					}

+				} else {

+					status.addError(Messages.format("The Role Method ''{0}'' is bound in a callin binding and cannot be inlined.", new String[] { fRoleMethod

+							.getElementName() }));

+					continue;

+				}

+			}

+			

+			if (element instanceof ICalloutMapping) {

+				status.addError(Messages.format("The Role Method ''{0}'' is bound in a callout binding and cannot be inlined.", new String[] { fRoleMethod

+						.getElementName() }));

+				continue;

+			}

+			

+			if (fDeleteRoleMethod) {

+				if (element instanceof IMember) {

+					// try to create context informations for the search result

+					IMember referencingMember = (IMember) element;

+					String msg = Messages.format("The Role Method ''{0}'' is referenced by ''{1}'' and cannot be deleted.", new String[] {

+							fRoleMethod.getElementName(), JavaElementLabels.getTextLabel(referencingMember, JavaElementLabels.ALL_FULLY_QUALIFIED) });

+					status.addError(msg, JavaStatusContext.create(referencingMember));

+				} else {

+					status.addError(Messages.format("The Role Method ''{0}'' is referenced and cannot be deleted.",

+							new String[] { fRoleMethod.getElementName() }));

+				}

+			}

+		}

+		return status;

+	}

+

+	private RefactoringStatus checkMethodName(String name) {

+		RefactoringStatus result = new RefactoringStatus();

+	

+		if (name == null)

+			return RefactoringStatus.createFatalErrorStatus("No new role method name specified.");

+	

+		if ("".equals(name)) //$NON-NLS-1$

+			return RefactoringStatus.createFatalErrorStatus("New role method name cannot be empty.");

+	

+		IJavaProject javaProject = this.fRoleType.getJavaProject();

+		String sourceLevel= javaProject.getOption(JavaCore.COMPILER_SOURCE, true);

+		String complianceLevel= javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);

+		IStatus status = JavaConventions.validateMethodName(name, sourceLevel, complianceLevel);

+		if (status.isOK())

+			return result;

+	

+		switch (status.getSeverity()) {

+		case IStatus.ERROR:

+			return RefactoringStatus.createFatalErrorStatus(status.getMessage());

+		case IStatus.WARNING:

+			return RefactoringStatus.createWarningStatus(status.getMessage());

+		case IStatus.INFO:

+			return RefactoringStatus.createInfoStatus(status.getMessage());

+		default: // no nothing

+			return new RefactoringStatus();

+		}

+	}

+

+	private RefactoringStatus checkIfMethodExists() {

+		try {

+			if (methodWithNameExists(fBaseType, fRoleMethodName)){

+				return RefactoringStatus.createErrorStatus(MessageFormat.format("A method with the same name already exists.", fRoleMethodName));

+			}

+		} catch (JavaModelException exception) {

+			return createCouldNotParseStatus();

+		}

+		return new RefactoringStatus();

+	}

+

+	private RefactoringStatus checkDependenciesToRole(IProgressMonitor pm) throws JavaModelException {

+		RefactoringStatus status = new RefactoringStatus();

+

+		IMethod[] referencedMethods = ReferenceFinderUtil.getMethodsReferencedIn(new IJavaElement[] { fRoleMethod }, null /* owner */, new SubProgressMonitor(pm,

+				1));

+		for (int i = 0; i < referencedMethods.length; i++) {

+			IMethod referencedMethod = referencedMethods[i];

+			if (referencedMethod.getDeclaringType().equals(fRoleType)) {

+				status.merge(RefactoringStatus.createErrorStatus(MessageFormat.format("The method to inline ''{0}'' references the role method ''{1}''.",

+						fRoleMethodName, referencedMethod)));

+			}

+		}

+

+		IField[] referencedFileds = ReferenceFinderUtil.getFieldsReferencedIn(new IJavaElement[] { fRoleMethod }, null /* owner */, new SubProgressMonitor(pm,

+				1));

+		for (int i = 0; i < referencedFileds.length; i++) {

+			IField referencedFiled = referencedFileds[i];

+			if (referencedFiled.getDeclaringType().equals(fRoleType)) {

+				status.merge(RefactoringStatus.createErrorStatus(MessageFormat.format("The method to inline ''{0}'' references the role field ''{1}''.",

+						fRoleMethodName, referencedFiled)));

+			}

+		}

+		return status;

+	}

+	

+	RefactoringStatus checkRoleMethodName() {

+		RefactoringStatus status = new RefactoringStatus();

+		status.merge(checkIfMethodExists());

+		status.merge(checkMethodName(fRoleMethodName));

+		return status;

+	}

+

+	RefactoringStatus checkBaseMethods() {

+		RefactoringStatus status = new RefactoringStatus();

+		if (fTargetBaseMethods == null || fTargetBaseMethods.length == 0) {

+			status.merge(RefactoringStatus.createFatalErrorStatus("No base method selected."));

+		}

+		return status;

+	}

+

+	private boolean methodWithNameExists(IType type, String methodName) throws JavaModelException {

+		IMethod[] methods = type.getMethods();

+		for (IMethod method : methods) {

+			if (method.getElementName().equals(methodName))

+				return true;

+		}

+		return false;

+	}

+

+	private RefactoringStatus createCouldNotParseStatus() {

+		return RefactoringStatus.createFatalErrorStatus("Could not parse the declaring type.");

+	}

+

+	@Override

+	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {

+		pm.beginTask("Creating Change", fCallinBaseMethodInfos.length + 2);

+		inlineCallin(pm);

+		Change change = new CompositeChange(getName(), new TextFileChange[] { fBaseTextFileChange, fRoleTextFileChange });

+		pm.done();

+		return change;

+	}

+

+	@SuppressWarnings("unchecked")

+	private void inlineCallin(IProgressMonitor pm) throws CoreException {

+		fBaseRewrite = ASTRewrite.create(fBaseAST);

+		fRoleRewrite = ASTRewrite.create(fRoleAST);

+		

+		for (int i = 0; i < fTargetBaseMethods.length; i++) {

+

+			IMethod baseMethod = fTargetBaseMethods[i].getMethod();

+			CallinBaseMethodInfo methodInfo = fTargetBaseMethods[i];

+			renameBaseMethod(methodInfo);

+			MethodDeclaration wrapperMethodDeclaration = createWrapperMethod(methodInfo);

+			Statement roleMethodInvocation = createRoleMethodInvocation(methodInfo);

+			List<Statement> statements = wrapperMethodDeclaration.getBody().statements();

+

+			// change the strategy for the different mapping kinds

+			switch (methodInfo.getCallinMapping().getCallinKind()) {

+			case ICallinMapping.KIND_BEFORE:

+				statements.add(0, roleMethodInvocation);

+				break;

+			case ICallinMapping.KIND_AFTER:

+				// TODO check for result parameter mappings

+				if (!baseMethod.getReturnType().equals(Character.toString(Signature.C_VOID))) {

+					// remove the base method invocation

+					statements.clear();

+		

+					// insert local variable statement to save the return value

+					// of

+					// the base method invocation

+					MethodDeclaration baseMethodDeclaration = RefactoringUtil.methodToDeclaration(baseMethod, fRootBase);

+					String varName = generateResultVarName(methodInfo);

+					VariableDeclarationFragment fragment = fBaseAST.newVariableDeclarationFragment();

+					fragment.setName(fBaseAST.newSimpleName(varName));

+					fragment.setInitializer(createBaseMethodInvocation(methodInfo));

+					VariableDeclarationStatement variableDeclarationStatement = fBaseAST.newVariableDeclarationStatement(fragment);

+					variableDeclarationStatement.setType((Type) ASTNode.copySubtree(fBaseAST, baseMethodDeclaration.getReturnType2()));

+					statements.add(variableDeclarationStatement);

+

+					// invoke the role method

+					statements.add(roleMethodInvocation);

+

+					// return the stored return value

+					ReturnStatement returnStatement = fBaseAST.newReturnStatement();

+					returnStatement.setExpression(fBaseAST.newSimpleName(varName));

+					statements.add(returnStatement);

+				} else {

+					statements.add(roleMethodInvocation);

+				}

+				break;

+			case ICallinMapping.KIND_REPLACE:

+				statements.clear();

+				statements.add(roleMethodInvocation);

+				break;

+			default:

+				break;

+			}

+		

+			insertMethodIntoBase(wrapperMethodDeclaration, baseMethod);

+			pm.worked(1);

+		}

+		

+		adjustMethodMappings();

+		pm.worked(1);

+		

+		copyRoleMethodToBase(fTargetBaseMethods[0]);

+		pm.worked(1);

+		

+		if (fDeleteRoleMethod) {

+			deleteRoleMethod();

+		}

+		

+		// create the text change for the base

+		MultiTextEdit baseMultiEdit = new MultiTextEdit();

+		baseMultiEdit.addChild(fBaseRewrite.rewriteAST());

+		fBaseTextFileChange = new TextFileChange(fBaseCUnit.getElementName(), (IFile) fBaseCUnit.getResource());

+		fBaseTextFileChange.setTextType("java");

+		fBaseTextFileChange.setEdit(baseMultiEdit);

+			

+		if (fBaseImportRewriter.hasRecordedChanges()) {

+			TextEdit edit = fBaseImportRewriter.rewriteImports(null);

+			baseMultiEdit.addChild(edit);

+			fBaseTextFileChange.addTextEditGroup(new TextEditGroup("Organize Imports", new TextEdit[] { edit }));

+		}

+

+		// create the text change for the role

+		MultiTextEdit roleMultiEdit = new MultiTextEdit();

+		roleMultiEdit.addChild(fRoleRewrite.rewriteAST());

+		fRoleTextFileChange = new TextFileChange(fRoleCUnit.getElementName(), (IFile) fRoleCUnit.getResource());

+		fRoleTextFileChange.setTextType("java");

+		fRoleTextFileChange.setEdit(roleMultiEdit);

+	}

+

+	

+	/**

+	 * Renames the given base method to the name given in the info object.

+	 * 

+	 * @param baseMethodInfo

+	 *            the info object containing the base method and the new base

+	 *            method name

+	 * @throws JavaModelException

+	 */

+	private void renameBaseMethod(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		ASTNode baseMethodDeclaration = RefactoringUtil.methodToDeclaration(baseMethodInfo.getMethod(), fRootBase);

+		fBaseRewrite.set(baseMethodDeclaration, MethodDeclaration.NAME_PROPERTY, fBaseAST.newSimpleName(baseMethodInfo.getNewMethodName()), null);

+	}

+

+	/**

+	 * Creates the method declaration for the wrapper method with the old base

+	 * method name.

+	 * 

+	 * @param baseMethodInfo

+	 *            the info object containing the base method and the new base

+	 *            method name

+	 * @return the generated wrapper method declaration

+	 * @throws CoreException

+	 */

+	private MethodDeclaration createWrapperMethod(CallinBaseMethodInfo baseMethodInfo) throws CoreException {

+		MethodDeclaration baseMethodDeclaration = RefactoringUtil.methodToDeclaration(baseMethodInfo.getMethod(), fRootBase);

+		MethodDeclaration methodDeclaration = (MethodDeclaration) ASTNode.copySubtree(fBaseAST, baseMethodDeclaration);

+		methodDeclaration.setBody(createMethodBody(baseMethodInfo));

+		return methodDeclaration;

+	}

+

+	/**

+	 * Creates the method body for the wrapper method that maps the inlined

+	 * method binding.

+	 * 

+	 * @param baseMethodInfo

+	 *            the info object containing the base method and the new base

+	 *            method name

+	 * @return the method body

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private Block createMethodBody(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		Block block = fBaseAST.newBlock();

+		List<Statement> statements = block.statements();

+		MethodInvocation invocation = createBaseMethodInvocation(baseMethodInfo);

+		

+		// create a return statement for the base method invocation if necessary

+		MethodDeclaration declaration = RefactoringUtil.methodToDeclaration(baseMethodInfo.getMethod(), fRootBase);

+		final Type type = declaration.getReturnType2();

+		if (type == null || (type instanceof PrimitiveType && PrimitiveType.VOID.equals(((PrimitiveType) type).getPrimitiveTypeCode()))) {

+			statements.add(invocation.getAST().newExpressionStatement(invocation));

+		} else {

+			ReturnStatement statement = invocation.getAST().newReturnStatement();

+			statement.setExpression(invocation);

+			statements.add(statement);

+		}

+		return block;

+	}

+

+	/**

+	 * Removes the base methods from the inlined method mappings. If all bound

+	 * base methods of a binding are removed, the whole mapping will be deleted.

+	 * The change is performed on the given <code>ASTRewrite</code>.

+	 * 

+	 * @param rewrite

+	 *            the rewrite that notes the changes

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private void adjustMethodMappings() throws JavaModelException {

+	

+		// create a map that gathers multiple methods for the same callin mapping

+		Map<IMethod, ICallinMapping> methodToMapping = new HashMap<IMethod, ICallinMapping>();

+		for (int i = 0; i < fTargetBaseMethods.length; i++) {

+			methodToMapping.put(fTargetBaseMethods[i].getMethod(), fTargetBaseMethods[i].getCallinMapping());

+		}

+	

+		for (ICallinMapping callinMapping : methodToMapping.values()) {

+			Collection<IMethod> baseMethodsToRemove = methodToMapping.keySet();

+			

+			// search the current callin mapping in the ast

+			CallinMappingDeclaration methodMappingDecl = (CallinMappingDeclaration) RefactoringUtil.methodMappingToDeclaration(callinMapping, fRootRole);

+			

+			if (baseMethodsToRemove.containsAll(Arrays.asList(callinMapping.getBoundBaseMethods()))) {

+				// if all bound base methods should be removed the remove the

+				// method mapping

+				fRoleRewrite.remove(methodMappingDecl, null);

+				

+			} else {

+				// otherwise remove the references to the base methods from the

+				// mapping

+				CallinMappingDeclaration mappingDeclaration = methodMappingDecl;

+				List<MethodSpec> baseMethods = mappingDeclaration.getBaseMappingElements();

+				for (MethodSpec methodSpec : baseMethods) {

+					for (IMethod method : baseMethodsToRemove) {

+						IMethodBinding methodBinding = methodSpec.resolveBinding();

+						IMethod boundMethod = (IMethod) methodBinding.getJavaElement();

+						if (method.equals(boundMethod)) {

+							// TODO remove unused imports

+							fRoleRewrite.remove(methodSpec, null);

+						}

+					}

+				}

+			}

+		}

+	}

+

+	private void deleteRoleMethod() throws JavaModelException {

+		// TODO remove unused imports

+		AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) RefactoringUtil.typeToDeclaration(fRoleType, fRootRole);

+		ChildListPropertyDescriptor descriptor = typeToBodyDeclarationProperty(fBaseType, fRootBase);

+		MethodDeclaration roleMethodDecl = RefactoringUtil.methodToDeclaration(fRoleMethod, fRootRole);

+		fRoleRewrite.getListRewrite(declaration, descriptor).remove(roleMethodDecl, null);

+	}

+

+	private boolean hasResultTunneling(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		// only replace callins can have result tunneling

+		if (baseMethodInfo.getCallinMapping().getCallinKind() != ICallinMapping.KIND_REPLACE) {

+			return false;

+		}

+

+		// only base methods with return types can produce result tunneling

+		if (isVoidMethod(baseMethodInfo.getMethod())) {

+			return false;

+		}

+		

+		// only role methods without a return type can produce result tunneling

+		if (!isVoidMethod(fRoleMethod)) {

+			return false;

+		}

+

+		if (hasResultParameterMapping(baseMethodInfo.getCallinMapping())) {

+			return false;

+		}

+		

+		return true;

+	}

+

+

+	@SuppressWarnings("unchecked")

+	private boolean hasResultParameterMapping(ICallinMapping callinMapping) throws JavaModelException {

+		if (!hasParameterMapping(callinMapping)) {

+			return false;

+		}

+		AbstractMethodMappingDeclaration mappingDecl = RefactoringUtil.methodMappingToDeclaration(callinMapping, fRootRole);

+		List<ParameterMapping> parameterMappings = mappingDecl.getParameterMappings();

+		for (ParameterMapping parameterMapping : parameterMappings) {

+			if (parameterMapping.hasResultFlag()) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private Statement createRoleMethodInvocation(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		MethodInvocation invocation = fBaseAST.newMethodInvocation();

+		ICallinMapping callinMapping = baseMethodInfo.getCallinMapping();

+

+		invocation.setName(fBaseAST.newSimpleName(fRoleMethodName));

+

+		CallinMappingDeclaration callinMappingDecl = (CallinMappingDeclaration) RefactoringUtil.methodMappingToDeclaration(callinMapping, fRootRole);

+		if (hasParameterMapping(callinMapping)) {

+			copyRoleParameterMappingsToInvocation(invocation, callinMappingDecl, baseMethodInfo);

+		} else {

+			copyInvocationParameters(invocation, baseMethodInfo.getMethod());

+		}

+		if (needsReturnStatement(baseMethodInfo)) {

+			ReturnStatement statement = invocation.getAST().newReturnStatement();

+			statement.setExpression(invocation);

+			return statement;

+		} else {

+			return invocation.getAST().newExpressionStatement(invocation);

+		}

+	}

+	

+	private boolean needsReturnStatement(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		if (isReplace(baseMethodInfo)) {

+			return !isVoidMethod(baseMethodInfo.getMethod());

+		} else {

+			return !(isVoidMethod(fRoleMethod) || isVoidMethod(baseMethodInfo.getMethod()));

+		}

+	}

+

+	private boolean isVoidMethod(IMethod method) throws JavaModelException {

+		return method.getReturnType().equals(Character.toString(Signature.C_VOID));

+	}

+

+	@SuppressWarnings("unchecked")

+	private void copyRoleParameterMappingsToInvocation(MethodInvocation invocation, CallinMappingDeclaration callinMappingDecl,

+			CallinBaseMethodInfo baseMethodInfo)

+			throws JavaModelException {	

+		MethodSpec baseMethodSpec = findBaseMethodSpec(callinMappingDecl, baseMethodInfo.getMethod());

+		

+		List<SingleVariableDeclaration> baseMappingParams = baseMethodSpec.parameters();

+		

+		// create a map that maps the original param names of the base method to

+		// the param names used in the mapping

+		Map<String, String> callinParamNamesToBaseMethodParamNames = new HashMap<String, String>();

+		String[] names = baseMethodInfo.getMethod().getParameterNames();

+		for (int i = 0; i < names.length; i++) {

+			callinParamNamesToBaseMethodParamNames.put(baseMappingParams.get(i).getName().getIdentifier(), names[i]);

+		}

+		

+		List<ParameterMapping> paramMappings = callinMappingDecl.getParameterMappings();

+		MethodSpec roleMethodSpec = (MethodSpec) callinMappingDecl.getRoleMappingElement();

+		List<SingleVariableDeclaration> roleMappingParams = roleMethodSpec.parameters();

+

+

+		for (SingleVariableDeclaration singleVariableDeclaration : roleMappingParams) {

+			String paramName = singleVariableDeclaration.getName().getIdentifier();

+			for (ParameterMapping mapping : paramMappings) {

+				if (mapping.hasResultFlag())

+					continue;

+				if (mapping.getIdentifier().getIdentifier().equals(paramName)) {

+					Expression expr = (Expression) ASTNode.copySubtree(fBaseAST, mapping.getExpression());

+					substituteBaseParams(expr, callinParamNamesToBaseMethodParamNames, baseMethodInfo);

+					invocation.arguments().add(expr);

+				}

+			}

+		}

+

+		

+		if (isReplace(baseMethodInfo)) {

+			Set<String> tunneledParams = findTunneledParameters(baseMethodInfo);

+			// replace tunneled parameters in base method invocations

+			for (String paramName : tunneledParams) {

+				String tunneledName = generateTunneledParamName(paramName);

+				invocation.arguments().add(fBaseAST.newSimpleName(tunneledName));

+			}

+		}

+	}

+	

+	@SuppressWarnings("unchecked")

+	private void copyBaseParameterMappingsToInvocation(MethodInvocation invocation, CallinMappingDeclaration callinMappingDecl,

+			CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		MethodSpec roleMethodSpec = (MethodSpec) callinMappingDecl.getRoleMappingElement();

+		List<SingleVariableDeclaration> roleMappingParams = roleMethodSpec.parameters();

+

+		// create a map that maps the original param names of the role method to

+		// the param names used in the mapping

+		Map<String, String> callinParamNamesToRoleMethodParamNames = new HashMap<String, String>();

+		String[] roleParamNames = fRoleMethod.getParameterNames();

+		for (int i = 0; i < roleParamNames.length; i++) {

+			callinParamNamesToRoleMethodParamNames.put(roleMappingParams.get(i).getName().getIdentifier(), roleParamNames[i]);

+		}

+

+		List<ParameterMapping> paramMappings = callinMappingDecl.getParameterMappings();

+		MethodSpec baseMethodSpec = findBaseMethodSpec(callinMappingDecl, baseMethodInfo.getMethod());

+		List<SingleVariableDeclaration> baseMappingParams = baseMethodSpec.parameters();

+

+		// create a map that maps the original param names of the base method to

+		// the param names used in the mapping

+		Map<String, String> callinParamNamesToBaseMethodParamNames = new HashMap<String, String>();

+		String[] baseParamNames = baseMethodInfo.getMethod().getParameterNames();

+		for (int i = 0; i < baseParamNames.length; i++) {

+			callinParamNamesToBaseMethodParamNames.put(baseMappingParams.get(i).getName().getIdentifier(), baseParamNames[i]);

+		}

+		

+		Map<String, Expression> baseParamToExpression = new HashMap<String, Expression>();

+		

+

+		for (SingleVariableDeclaration singleVariableDeclaration : baseMappingParams) {

+			String paramName = singleVariableDeclaration.getName().getIdentifier();

+			for (ParameterMapping mapping : paramMappings) {

+				if (mapping.hasResultFlag())

+					continue;

+				if (mapping.getExpression() instanceof SimpleName) {

+					SimpleName mappedName = (SimpleName) mapping.getExpression();

+					if (mappedName.getIdentifier().equals(paramName)) {

+						// resolve the original param names because param names

+						// in the mapping can be different

+						String roleMethodIdentifier = callinParamNamesToRoleMethodParamNames.get(mapping.getIdentifier().getIdentifier());

+						String baseMethodIdentifier = callinParamNamesToBaseMethodParamNames.get(paramName);

+						baseParamToExpression.put(baseMethodIdentifier, fBaseAST.newSimpleName(roleMethodIdentifier));

+						// base parameters can only be mapped once �4.4.(b)

+						continue;

+					}

+				}

+			}

+		}

+		

+		// pass the right statement for each base param

+		for (String name : baseParamNames) {

+			if(baseParamToExpression.get(name) == null){

+				String tunneledName = generateTunneledParamName(name);

+				invocation.arguments().add(fBaseAST.newSimpleName(tunneledName));

+			}else{

+				// pass the simple name of the mapped role method parameter

+				invocation.arguments().add(baseParamToExpression.get(name));

+			}

+		}

+

+		if (isReplace(baseMethodInfo)) {

+

+			// parameter mappings are handled differently because they depend on

+			// the mapping

+			if (!hasParameterMapping(baseMethodInfo.getCallinMapping())) {

+				// if the role method doesn't declare the same number of

+				// parameters

+				// as the base method, the parameters have to be appended

+				int roleMethodParameterLength = baseMethodInfo.getCallinMapping().getRoleMethod().getParameterNames().length;

+				int baseMethodParameterLength = baseMethodInfo.getMethod().getParameterNames().length;

+				if (roleMethodParameterLength < baseMethodParameterLength) {

+					appendInvocationParameters(invocation, baseMethodInfo.getMethod(), roleMethodParameterLength);

+				}

+			}

+		}

+	}

+	

+	private void substituteBaseParams(Expression expr, Map<String, String> callinParamNamesToBaseMethodParamNames, CallinBaseMethodInfo baseMethodInfo)

+			throws JavaModelException {

+		ArrayList<String> callinParamNames = new ArrayList<String>();

+		for (String name : callinParamNamesToBaseMethodParamNames.keySet()) {

+			callinParamNames.add(name);

+		}

+		SimpleNameFinder simpleNameFinder = new SimpleNameFinder(callinParamNames);

+		expr.accept(simpleNameFinder);

+		List<SimpleName> simpleNames = simpleNameFinder.getResult();

+		for (SimpleName simpleName : simpleNames) {

+			String baseMethodParamName = callinParamNamesToBaseMethodParamNames.get(simpleName.getIdentifier());

+			simpleName.setIdentifier(baseMethodParamName);

+		}

+	}

+

+	@SuppressWarnings("unchecked")

+	private Set<String> findTunneledParameters(CallinBaseMethodInfo baseMethodInfo)

+			throws JavaModelException {

+		// try to reuse cached result

+		if (fCachedBaseMethodInfo == baseMethodInfo) {

+			return fCachedTunneledParameters;

+		}

+		fCachedBaseMethodInfo = baseMethodInfo;

+		Set<String> tunneledParams = new HashSet<String>();

+		CallinMappingDeclaration callinMappingDecl = (CallinMappingDeclaration) RefactoringUtil.methodMappingToDeclaration(baseMethodInfo.getCallinMapping(),

+				fRootRole);

+		MethodSpec baseMethodSpec = findBaseMethodSpec(callinMappingDecl, baseMethodInfo.getMethod());

+

+		List<SingleVariableDeclaration> baseMappingParams = baseMethodSpec.parameters();

+

+		// create a map that maps the original param names of the base method to

+		// the param names used in the mapping

+		Map<String, String> baseMethodParamNameToBaseMappingParamName = new HashMap<String, String>();

+		String[] names = baseMethodInfo.getMethod().getParameterNames();

+		for (int i = 0; i < names.length; i++) {

+			baseMethodParamNameToBaseMappingParamName.put(names[i], baseMappingParams.get(i).getName().getIdentifier());

+		}

+

+		List<ParameterMapping> paramMappings = callinMappingDecl.getParameterMappings();

+		tunneledParams.addAll(Arrays.asList(baseMethodInfo.getMethod().getParameterNames()));

+		for (int i = 0; i < names.length; i++) {

+			for (ParameterMapping mapping : paramMappings) {

+				if (mapping.hasResultFlag())

+					continue;

+				Expression expr = (Expression) mapping.getExpression();

+				if (expr instanceof SimpleName) {

+					SimpleName simpleName = (SimpleName) expr;

+					if (simpleName.getIdentifier().equals(baseMethodParamNameToBaseMappingParamName.get(names[i]))) {

+						tunneledParams.remove(names[i]);

+					}

+				}

+			}

+		}

+		fCachedTunneledParameters = tunneledParams;

+		return fCachedTunneledParameters;

+	}

+	

+	/**

+	 * Copies the invocation parameter of the given base method to the given

+	 * method invocation.

+	 * 

+	 * @param invocation

+	 *            the method invocation to receive the parameters

+	 * @param method

+	 *            the method that declares the parameters

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private void copyInvocationParameters(MethodInvocation invocation, IMethod method) throws JavaModelException {

+		String[] names = method.getParameterNames();

+		for (String element : names)

+			invocation.arguments().add(fBaseAST.newSimpleName(element));

+	}

+

+	/**

+	 * Copies the role method to the base class and creates store variables for

+	 * implicit result tunneling. If the role method was a callin method, base

+	 * methods are replaced by method invocations to the new method name,

+	 * specified in <code>baseMethodInfo</code>.

+	 * 

+	 * @param rewrite

+	 *            the rewrite that notes the changes

+	 * @param baseMethodInfo

+	 *            the info object containing the base method, callin mapping,

+	 *            and the new base method name

+	 * @throws JavaModelException

+	 */

+	private void copyRoleMethodToBase(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		ASTNode roleMethodDeclaration = RefactoringUtil.methodToDeclaration(fRoleMethod, fRootRole);

+		MethodDeclaration copyOfRoleMethodDeclaration = (MethodDeclaration) ASTNode.copySubtree(fBaseAST, roleMethodDeclaration);

+		copyOfRoleMethodDeclaration.setName(fBaseAST.newSimpleName(fRoleMethodName));

+		

+		// change the visibility of the copy to private to avoid overriding and

+		// hide the role method

+		if (!Flags.isPrivate(fRoleMethod.getFlags()) && !Flags.isCallin(fRoleMethod.getFlags()))

+			changeToPrivateVisibility(fBaseRewrite, copyOfRoleMethodDeclaration);

+		

+		// special treatment for replace mappings/callin methods

+		if (Flags.isCallin(fRoleMethod.getFlags())) {

+			handleCallinMethod(fBaseRewrite, baseMethodInfo, copyOfRoleMethodDeclaration);

+		}

+		

+		if ((isReplace(baseMethodInfo))) {

+			if (hasParameterMapping(baseMethodInfo.getCallinMapping())) {

+				// append parameters that are tunneled because of a missing

+				// parameter mapping �4.4.(b)

+				appendTunneledParameterDeclarations(baseMethodInfo, copyOfRoleMethodDeclaration);

+			} else {

+				// if a callin method doesn't declare the same number of

+				// parameters

+				// as the base method, the parameters have to be appended

+				int roleMethodParameterLength = baseMethodInfo.getCallinMapping().getRoleMethod().getParameterNames().length;

+				int baseMethodParameterLength = baseMethodInfo.getMethod().getParameterNames().length;

+				if (roleMethodParameterLength < baseMethodParameterLength) {

+					appendParameterDeclarations(copyOfRoleMethodDeclaration, baseMethodInfo.getMethod(), roleMethodParameterLength);

+				}

+			}

+		}

+		

+		findAndReplaceCallouts(fBaseRewrite, copyOfRoleMethodDeclaration);

+		

+		insertMethodIntoBase(copyOfRoleMethodDeclaration, baseMethodInfo.getMethod());

+		

+		// oragnize imports

+		Set<IBinding> staticImports = new HashSet<IBinding>();

+		Set<ITypeBinding> imports = new HashSet<ITypeBinding>();

+		ImportRewriteUtil.collectImports(fRoleMethod.getJavaProject(), roleMethodDeclaration, imports, staticImports, false);

+		for (ITypeBinding typeBinding : imports) {

+			fBaseImportRewriter.addImport(typeBinding);

+		}

+		for (IBinding binding : staticImports) {

+			fBaseImportRewriter.addStaticImport(binding);

+		}

+	}

+

+	/**

+	 * Replaces <code>public</code> and <code>protected</code> by a

+	 * <code>private</code> modifier. If the method has default visibility

+	 * <code>private</code> modifier will be prepended to the modifier list.

+	 * 

+	 * @param rewrite

+	 *            the rewrite that notes the changes

+	 * @param methodDeclaration

+	 *            the method declaration to be changed

+	 */

+	@SuppressWarnings("unchecked")

+	private void changeToPrivateVisibility(ASTRewrite astRewrite, MethodDeclaration methodDeclaration) {

+		Modifier privateVisibility = methodDeclaration.getAST().newModifier(ModifierKeyword.PRIVATE_KEYWORD);

+		

+		List<IExtendedModifier> modifiers = methodDeclaration.modifiers();

+		for (IExtendedModifier extendedModifier : modifiers) {

+			if (extendedModifier instanceof Modifier) {

+				Modifier modifier = (Modifier) extendedModifier;

+				if (Modifier.isPublic(modifier.getKeyword().toFlagValue())) {

+					astRewrite.replace(modifier, privateVisibility, null);

+					return;

+				}

+				if (Modifier.isProtected(modifier.getKeyword().toFlagValue())) {

+					astRewrite.replace(modifier, privateVisibility, null);

+					return;

+				}

+				if (Modifier.isPrivate(modifier.getKeyword().toFlagValue())) {

+					// don't replace private modifiers or create a 2nd private

+					// modifier

+					return;

+				}

+			}

+		}

+		// no visibility modifier was found => default visibility will be

+		// reduced to private

+		astRewrite.getListRewrite(methodDeclaration, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(privateVisibility, null);

+	}

+

+	/**

+	 * Handles special cases for callin methods like result tunneling and base

+	 * call replacement.

+	 * 

+	 * @param rewrite

+	 *            the rewrite that notes the changes

+	 * @param baseMethodInfo

+	 *            the info object containing the base method, callin mapping,

+	 *            and the new base method name

+	 * @param methodDeclaration

+	 *            the method declaration node of the role method

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private void handleCallinMethod(ASTRewrite astRewrite, CallinBaseMethodInfo baseMethodInfo, MethodDeclaration methodDeclaration)

+			throws JavaModelException {

+		List<Statement> statements = methodDeclaration.getBody().statements();

+		removeCallinFlag(methodDeclaration);

+		

+		if (fRoleMethod.getReturnType().equals(Character.toString(Signature.C_VOID))) {

+			ReturnFinder returnFinder = new ReturnFinder();

+			methodDeclaration.accept(returnFinder);

+			List<ReturnStatement> returns = returnFinder.getResult();

+			for (ReturnStatement returnStatement : returns) {

+				astRewrite.replace(returnStatement, fBaseAST.newReturnStatement(), null);

+			}

+		}

+		

+		if (hasResultTunneling(baseMethodInfo)) {

+			String varName = generateResultVarName(baseMethodInfo);

+			VariableDeclarationFragment fragment = fBaseAST.newVariableDeclarationFragment();

+			fragment.setName(fBaseAST.newSimpleName(varName));

+			VariableDeclarationStatement variableDeclarationStatement = fBaseAST.newVariableDeclarationStatement(fragment);

+			MethodDeclaration baseMethodDeclaration = RefactoringUtil.methodToDeclaration(baseMethodInfo.getMethod(), fRootBase);

+			variableDeclarationStatement.setType((Type) ASTNode.copySubtree(fBaseAST, baseMethodDeclaration.getReturnType2()));

+			statements.add(0, variableDeclarationStatement);

+			

+			

+			// return the stored return value

+			ReturnStatement returnStatement = fBaseAST.newReturnStatement();

+			returnStatement.setExpression(fBaseAST.newSimpleName(varName));

+			statements.add(returnStatement);

+			

+			substituteBaseCalls(methodDeclaration, astRewrite, varName, baseMethodInfo);

+			

+		} else if(hasResultParameterMapping(baseMethodInfo.getCallinMapping())

+				&& isVoidMethod(fRoleMethod)) {

+			// replace callins may define a result mapping if they don't have a

+			// return value

+			AbstractMethodMappingDeclaration mappingDecl = RefactoringUtil.methodMappingToDeclaration(baseMethodInfo.getCallinMapping(), fRootRole);

+			List<ParameterMapping> parameterMappings = mappingDecl.getParameterMappings();

+			Expression resultMappingExpression = null;

+			for (ParameterMapping parameterMapping : parameterMappings) {

+				if (parameterMapping.hasResultFlag()) {

+					resultMappingExpression = (Expression) parameterMapping.getExpression();

+				}

+			}

+

+			// return the mapped return value

+			ReturnStatement returnStatement = fBaseAST.newReturnStatement();

+			returnStatement.setExpression((Expression) ASTNode.copySubtree(fBaseAST, resultMappingExpression));

+			statements.add(returnStatement);

+			substituteBaseCalls(methodDeclaration, astRewrite, null /* localStoreVarIdentifier */, baseMethodInfo);

+		} else {

+			substituteBaseCalls(methodDeclaration, astRewrite, null /* localStoreVarIdentifier */, baseMethodInfo);

+		}

+	

+		Modifier privateVisibility = fBaseAST.newModifier(ModifierKeyword.PRIVATE_KEYWORD);

+		methodDeclaration.modifiers().add(privateVisibility);

+	

+		// callin methods need the same return type as the base method

+		// after inlining

+		MethodDeclaration declaration = RefactoringUtil.methodToDeclaration(baseMethodInfo.getMethod(), fRootBase);

+		methodDeclaration.setReturnType2((Type) ASTNode.copySubtree(fBaseAST, declaration.getReturnType2()));

+	}

+

+	/**

+	 * Removes a callin modifier from the given <code>MethodDeclaration</code>.

+	 * 

+	 * @param methodDeclaration

+	 *            the method declaration to remove the callin modifier from

+	 * @return true if a callin modifier was removed - otherwise false

+	 */

+	@SuppressWarnings("unchecked")

+	private boolean removeCallinFlag(MethodDeclaration methodDeclaration) {

+		List<IExtendedModifier> modifiers = methodDeclaration.modifiers();

+	

+		for (IExtendedModifier extendedModifier : modifiers) {

+			if (extendedModifier instanceof Modifier) {

+				Modifier modifier = (Modifier) extendedModifier;

+				if (Modifier.isCallin(modifier.getKeyword().toFlagValue())) {

+					modifier.delete();

+					return true;

+				}

+			}

+		}

+		return false;

+	}

+

+	/**

+	 * Substitutes base calls in the body of a callin method by method

+	 * invocations to the method specified in baseMethodInfo. If a identifier

+	 * for a local variable is given, the method invocations will be assigned to

+	 * it.

+	 * 

+	 * @param methodDeclaration

+	 *            the method declaration containing the base calls

+	 * @param rewrite

+	 *            the rewrite that notes the changes

+	 * @param localStoreVarIdentifier

+	 *            the name of a return store variable - <code>null</code> if no

+	 *            return value must be stored

+	 * @param baseMethodInfo

+	 *            the info object containing the base method and the new base

+	 *            method name

+	 * @throws JavaModelException

+	 */

+	private void substituteBaseCalls(MethodDeclaration methodDeclaration, ASTRewrite astRewrite, String localStoreVarIdentifier,

+			CallinBaseMethodInfo baseMethodInfo)

+			throws JavaModelException {

+		BaseCallFinder baseCallFinder = new BaseCallFinder();

+		methodDeclaration.accept(baseCallFinder);

+		BaseCallMessageSend[] baseCalls = baseCallFinder.getResult();

+		

+		if (localStoreVarIdentifier != null) {

+			// create assignment statements if a store identifier exist

+			for (int i = 0; i < baseCalls.length; i++) {

+				BaseCallMessageSend basecall = baseCalls[i];

+	

+				Assignment assignment = fBaseAST.newAssignment();

+				assignment.setLeftHandSide(fBaseAST.newSimpleName(localStoreVarIdentifier));

+				assignment.setRightHandSide(createBaseMethodInvocation(baseMethodInfo));

+	

+				astRewrite.replace(basecall, assignment, null);

+			}

+		} else {

+			// substitute the base calls with a simple base call

+			for (int i = 0; i < baseCalls.length; i++) {

+				BaseCallMessageSend basecall = baseCalls[i];

+				astRewrite.replace(basecall, createBaseMethodInvocation(baseMethodInfo), null);

+			}

+		}

+	}

+

+	private void findAndReplaceCallouts(ASTRewrite astRewrite, MethodDeclaration copyOfRoleMethodDeclaration) throws JavaModelException {

+		MethodInvocationFinder methodInvocationFinder = new MethodInvocationFinder();

+		copyOfRoleMethodDeclaration.accept(methodInvocationFinder);

+		List<MethodInvocation> methodInvocations = methodInvocationFinder.getResult();

+		IMethodMapping[] calloutMappings = ((IRoleType) OTModelManager.getOTElement(fRoleType)).getMethodMappings(IRoleType.CALLOUTS);

+	

+		Map<String, IMethodMapping> calloutNameToMapping = new HashMap<String, IMethodMapping>();

+		for (IMethodMapping methodMapping : calloutMappings) {

+			if(methodMapping instanceof ICalloutMapping){

+				ICalloutMapping calloutMapping = (ICalloutMapping)methodMapping;

+				calloutNameToMapping.put(calloutMapping.getRoleMethodHandle().getSelector(), calloutMapping);

+				

+			}

+			if(methodMapping instanceof ICalloutToFieldMapping){

+				ICalloutToFieldMapping calloutToFieldMapping = (ICalloutToFieldMapping)methodMapping;

+				calloutNameToMapping.put(calloutToFieldMapping.getRoleMethodHandle().getSelector(), calloutToFieldMapping);

+			}

+		}

+		

+		for (MethodInvocation invocation : methodInvocations) {

+			IMethodMapping mapping = calloutNameToMapping.get(invocation.getName().getIdentifier());

+			if(mapping == null){

+				continue;

+			}

+			// TODO Parameter mappings

+			switch (mapping.getMappingKind()) {

+			case IOTJavaElement.CALLOUT_MAPPING:

+				ICalloutMapping calloutMapping = (ICalloutMapping)mapping;

+				invocation.setName(fBaseAST.newSimpleName(calloutMapping.getBoundBaseMethod().getElementName()));

+				break;

+			case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:

+				ICalloutToFieldMapping calloutToFieldMapping = (ICalloutToFieldMapping)mapping;

+				CalloutMappingDeclaration calloutDecl = (CalloutMappingDeclaration) RefactoringUtil.methodMappingToDeclaration(calloutToFieldMapping, fRootRole);

+				String fieldName = calloutToFieldMapping.getBoundBaseField().getElementName();

+				if (Modifier.isSet(calloutDecl.bindingOperator().getBindingModifier())) {

+					// set

+					Assignment setAssignment = fBaseAST.newAssignment();

+					setAssignment.setLeftHandSide(fBaseAST.newSimpleName(fieldName));

+					Expression setExpression = (Expression) ASTNode.copySubtree(fBaseAST, (Expression) invocation.arguments().get(0));

+					setAssignment.setRightHandSide(setExpression);

+					astRewrite.replace(invocation, setAssignment, null);

+				} else {

+					// get

+					astRewrite.replace(invocation, fBaseAST.newSimpleName(fieldName), null);

+				}

+				

+				

+				break;

+			default:

+				break;

+			}

+		}

+	}

+

+	private MethodInvocation createBaseMethodInvocation(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		MethodInvocation invocation = fBaseAST.newMethodInvocation();

+		invocation.setName(fBaseAST.newSimpleName(baseMethodInfo.getNewMethodName()));

+		

+		

+		if (isReplace(baseMethodInfo)) {	

+			// parameter mappings are handled differently because they depend on

+			// the mapping

+			if (!hasParameterMapping(baseMethodInfo.getCallinMapping())) {

+				// replace callins call the method within the role method body

+				copyInvocationParameters(invocation, baseMethodInfo.getCallinMapping().getRoleMethod());

+				// if the role method doesn't declare the same number of

+				// parameters as the base method, the parameters have to be

+				// appended

+				int roleMethodParameterLength = baseMethodInfo.getCallinMapping().getRoleMethod().getParameterNames().length;

+				int baseMethodParameterLength = baseMethodInfo.getMethod().getParameterNames().length;

+				if (roleMethodParameterLength < baseMethodParameterLength) {

+					appendInvocationParameters(invocation, baseMethodInfo.getMethod(), roleMethodParameterLength);

+				}

+			} else {

+				CallinMappingDeclaration callinMappingDecl = (CallinMappingDeclaration) RefactoringUtil.methodMappingToDeclaration(baseMethodInfo

+						.getCallinMapping(), fRootRole);

+				copyBaseParameterMappingsToInvocation(invocation, callinMappingDecl, baseMethodInfo);

+			}

+		} else {

+			// replace and after callins call the base method within the wrapper

+			// method of the role

+			copyInvocationParameters(invocation, baseMethodInfo.getMethod());

+		}

+

+

+		return invocation;

+	}

+

+	private boolean isReplace(CallinBaseMethodInfo baseMethodInfo) {

+		return baseMethodInfo.getCallinMapping().getCallinKind() == ICallinMapping.KIND_REPLACE;

+	}

+	

+	private boolean hasParameterMapping(IMethodMapping mapping) throws JavaModelException {

+		AbstractMethodMappingDeclaration decl = RefactoringUtil.methodMappingToDeclaration(mapping, fRootRole);

+		return decl.hasParameterMapping();

+	}

+

+	private void insertMethodIntoBase(MethodDeclaration methodDeclaration, IMethod baseMethod) throws JavaModelException {

+		AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) RefactoringUtil.typeToDeclaration(fBaseType, fRootBase);

+		ChildListPropertyDescriptor descriptor = typeToBodyDeclarationProperty(fBaseType, fRootBase);

+		MethodDeclaration baseMethodDeclaration = RefactoringUtil.methodToDeclaration(baseMethod, fRootBase);

+		fBaseRewrite.getListRewrite(declaration, descriptor).insertBefore(methodDeclaration, baseMethodDeclaration, null);

+	}

+	

+

+

+	/**

+	 * Appends the parameter declarations from the given <code>baseMethod</code>

+	 * to the end of the parameter list of the given

+	 * <code>roleMethodDeclaration</code>, starting at the given

+	 * <code>offset</code>. This method is used if the role method declares

+	 * fewer parameters than the base method.

+	 * 

+	 * @param roleMethodDeclaration

+	 *            the method declaration of the copied role method

+	 * @param baseMethod

+	 *            the base method to copy the parameter declarations from

+	 * @param offset

+	 *            the offset to start

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private void appendParameterDeclarations(MethodDeclaration roleMethodDeclaration, IMethod baseMethod, int offset) throws JavaModelException {

+		MethodDeclaration baseMethodDecl = RefactoringUtil.methodToDeclaration(baseMethod, fRootBase);

+		List<SingleVariableDeclaration> baseParamDeclarations = baseMethodDecl.parameters();

+		for (int i = offset; i < baseParamDeclarations.size(); i++) {

+			SingleVariableDeclaration paramDecl = (SingleVariableDeclaration) ASTNode.copySubtree(fBaseAST, baseParamDeclarations.get(i));

+			

+			// generate a parameter name that does not produce a name clash

+			List<String> localVarNames = new ArrayList<String>();

+			localVarNames.addAll(localVarNamesInRoleMethod());

+			localVarNames.addAll(Arrays.asList(fRoleMethod.getParameterNames()));

+			String validParameterName = generateVarName(paramDecl.getName().getIdentifier(), localVarNames);

+			paramDecl.setName(fBaseAST.newSimpleName(validParameterName));

+			fBaseRewrite.getListRewrite(roleMethodDeclaration, MethodDeclaration.PARAMETERS_PROPERTY).insertLast(paramDecl, null);

+		}

+	}

+

+	@SuppressWarnings("unchecked")

+	private void appendTunneledParameterDeclarations(CallinBaseMethodInfo baseMethodInfo, MethodDeclaration copyOfRoleMethodDeclaration)

+			throws JavaModelException {

+		// append tunneled parameters to roleMethodSignature

+		Set<String> tunneledParams = findTunneledParameters(baseMethodInfo);

+		// replace tunneled parameters in base method invocations

+		MethodDeclaration baseMethodDecl = RefactoringUtil.methodToDeclaration(baseMethodInfo.getMethod(), fRootBase);

+		List<SingleVariableDeclaration> baseParamDeclarations = baseMethodDecl.parameters();

+		ListRewrite listRewrite = fBaseRewrite.getListRewrite(copyOfRoleMethodDeclaration, MethodDeclaration.PARAMETERS_PROPERTY);

+		for (SingleVariableDeclaration varDecl : baseParamDeclarations) {

+			String paramName = varDecl.getName().getIdentifier();

+			if (tunneledParams.contains(paramName)) {

+				String tunneledName = generateTunneledParamName(paramName);

+				SingleVariableDeclaration paramDecl = (SingleVariableDeclaration) ASTNode.copySubtree(fBaseAST, varDecl);

+				paramDecl.setName(fBaseAST.newSimpleName(tunneledName));

+				listRewrite.insertLast(paramDecl, null);

+			}

+		}

+	}

+

+	/**

+	 * Appends invocation parameter names from the given method from the given

+	 * offset. This method is used to extend base method calls if the role

+	 * method declares fewer parameters than the base method.

+	 * 

+	 * @param invocation

+	 *            the method invocation to receive the parameters

+	 * @param method

+	 *            the method that declares the parameters

+	 * @param offset

+	 *            the offset to begin to copy

+	 * @throws JavaModelException

+	 */

+	@SuppressWarnings("unchecked")

+	private void appendInvocationParameters(MethodInvocation invocation, IMethod method, int offset) throws JavaModelException {

+		String[] names = method.getParameterNames();

+		

+		for (int i = offset; i < names.length; i++) {

+			String name = names[i];

+

+			// generate a valid parameter name to prevent name clashes

+			List<String> localVarNames = new ArrayList<String>();

+			localVarNames.addAll(localVarNamesInRoleMethod());

+			localVarNames.addAll(Arrays.asList(fRoleMethod.getParameterNames()));

+			String validParameterName = generateVarName(name, localVarNames);

+			invocation.arguments().add(fBaseAST.newSimpleName(validParameterName));

+		}

+	}

+

+	private RefactoringStatus generateNewBaseMethodNames() {

+		try {

+			generateBaseMethodNames(fTargetBaseMethods);

+		} catch (JavaModelException e) {

+			return createCouldNotParseStatus();

+		}

+		return new RefactoringStatus();

+	}

+

+	private String generateResultVarName(CallinBaseMethodInfo baseMethodInfo) throws JavaModelException {

+		String name = "baseResult";

+		List<String> paramNames = Arrays.asList(baseMethodInfo.getMethod().getParameterNames());

+		return generateVarName(name, paramNames);

+	}

+

+	/**

+	 * Generates a name for a parameter or local variable that does not produce

+	 * name clashes with a base field, a parameter name or a local variable

+	 * name. If there are no name clashes, the method returns the desired name,

+	 * otherwise it returns the desired name with an appended number.

+	 * 

+	 * @param desiredName

+	 *            the name to be checked

+	 * @param localVarNames

+	 *            list of local variable names

+	 * @return a name that does not produce a name clash

+	 */

+	private String generateVarName(String desiredName, List<String> localVarNames) {

+		String varName = desiredName;

+		

+		int i = 2;

+		while (fBaseType.getField(varName).exists() || localVarNames.contains(varName)) {

+			varName = desiredName + i;

+			i++;

+		}

+		return varName;

+	}

+

+	private void generateBaseMethodNames(CallinBaseMethodInfo[] baseMethodInfos) throws JavaModelException {

+		for (int i = 0; i < baseMethodInfos.length; i++) {

+			String newBaseName = "base_" + fTargetBaseMethods[i].getMethod().getElementName();

+			int j = 2;

+			while (methodWithNameExists(fBaseType, newBaseName)) {

+				newBaseName = "base_" + fTargetBaseMethods[i].getMethod().getElementName() + j;

+				j++;

+			}

+			baseMethodInfos[i].setNewMethodName(newBaseName);

+		}

+	}

+

+	private String generateTunneledParamName(String identifier) throws JavaModelException {

+		String upperCasedName = identifier.substring(0, 1).toUpperCase() + identifier.substring(1);

+		List<String> localVarNames = new ArrayList<String>();

+		localVarNames.addAll(localVarNamesInRoleMethod());

+		localVarNames.addAll(Arrays.asList(fRoleMethod.getParameterNames()));

+		String tunneledName = generateVarName("tunneled" + upperCasedName, localVarNames);

+		return tunneledName;

+	}

+

+	private List<String> localVarNamesInRoleMethod() throws JavaModelException {

+		List<String> localVars = new ArrayList<String>();

+		MethodDeclaration declaration = RefactoringUtil.methodToDeclaration(fRoleMethod, fRootRole);

+		LocalVariableFinder localVariableFinder = new LocalVariableFinder();

+		declaration.accept(localVariableFinder);

+		localVars = localVariableFinder.getResult();

+		return localVars;

+	}

+

+	@SuppressWarnings("unchecked")

+	private MethodSpec findBaseMethodSpec(CallinMappingDeclaration callinMappingDecl, IMethod baseMethod) {

+		MethodSpec baseMethodSpec = null;

+		List<MethodSpec> methodSpecs = callinMappingDecl.getBaseMappingElements();

+		for (MethodSpec methodSpec : methodSpecs) {

+			IMethodBinding methodBinding = methodSpec.resolveBinding();

+			IMethod method = (IMethod) methodBinding.getJavaElement();

+			if (method.equals(baseMethod)) {

+				baseMethodSpec = methodSpec;

+			}

+		}

+		return baseMethodSpec;

+	}

+

+	private ChildListPropertyDescriptor typeToBodyDeclarationProperty(IType type, CompilationUnit node) throws JavaModelException {

+		ASTNode result = RefactoringUtil.typeToDeclaration(type, node);

+		if (result instanceof AbstractTypeDeclaration)

+			return ((AbstractTypeDeclaration) result).getBodyDeclarationsProperty();

+		else if (result instanceof AnonymousClassDeclaration)

+			return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;

+	

+		Assert.isTrue(false);

+		return null;

+	}

+

+	private class LocalVariableFinder extends ASTVisitor {

+	

+		private List<String> _locals = new ArrayList<String>();

+	

+		@Override

+		public boolean visit(VariableDeclarationFragment node) {

+			_locals.add(node.getName().getIdentifier());

+			return false;

+		}

+	

+		public List<String> getResult() {

+			return _locals;

+		}

+	}

+

+	private class SimpleNameFinder extends ASTVisitor {

+	

+		private List<SimpleName> _simpleNames = new ArrayList<SimpleName>();

+		private List<String> _identifier;

+	

+		public SimpleNameFinder(List<String> identifier) {

+			_identifier = identifier;

+		}

+	

+		@Override

+		public boolean visit(SimpleName node) {

+			if (_identifier.contains(node.getIdentifier())) {

+				_simpleNames.add(node);

+			}

+			return false;

+		}

+	

+		public List<SimpleName> getResult() {

+			return _simpleNames;

+		}

+	}

+

+	private class MethodInvocationFinder extends ASTVisitor {

+	

+		private List<MethodInvocation> _methodInvocations = new ArrayList<MethodInvocation>();

+	

+		@Override

+		public boolean visit(MethodInvocation node) {

+			_methodInvocations.add(node);

+			return false;

+		}

+	

+		public List<MethodInvocation> getResult() {

+			return _methodInvocations;

+		}

+	}

+

+	private class ReturnFinder extends ASTVisitor {

+	

+		private List<ReturnStatement> _returns = new ArrayList<ReturnStatement>();

+	

+		@Override

+		public boolean visit(ReturnStatement node) {

+			_returns.add(node);

+			return false;

+		}

+	

+		public List<ReturnStatement> getResult() {

+			return _returns;

+		}

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinWizard.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinWizard.java
new file mode 100644
index 0000000..2b603f2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/otrefactorings/inlinecallin/InlineCallinWizard.java
@@ -0,0 +1,16 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin;

+

+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;

+

+public class InlineCallinWizard extends RefactoringWizard {

+

+	public InlineCallinWizard(InlineCallinRefactoring refactoring, String pageTitle) {

+		super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);

+		setDefaultPageTitle(pageTitle);

+	}

+

+	@Override

+	protected void addUserInputPages() {

+		addPage(new InlineCallinInputPage("InlineCallinInputPage"));

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/IAmbuguityMessageCreator.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/IAmbuguityMessageCreator.java
new file mode 100644
index 0000000..76e9790
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/IAmbuguityMessageCreator.java
@@ -0,0 +1,19 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.util;

+

+/**

+ * 

+ * This Interface is used for call back objects to provide refactoring specific

+ * error messages concerning ambiguity.

+ * 

+ * @author Johannes Gebauer

+ */

+public interface IAmbuguityMessageCreator {

+

+	/**

+	 * Creates an ambiguous method specifier error message.

+	 * 

+	 * @return a refactoring specific message for an abmigious method specifier.

+	 */

+	public String createAmbiguousMethodSpecifierMsg();

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/IOverloadingMessageCreator.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/IOverloadingMessageCreator.java
new file mode 100644
index 0000000..e881fab
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/IOverloadingMessageCreator.java
@@ -0,0 +1,19 @@
+package org.eclipse.objectteams.otdt.internal.refactoring.util;

+

+/**

+ * 

+ * This Interface is used for call back objects to provide refactoring specific

+ * error messages concerning overloading.

+ * 

+ * @author Johannes Gebauer

+ */

+public interface IOverloadingMessageCreator {

+

+	/**

+	 * Creates a refactoring specific message for overloading warnings.

+	 * 

+	 * @return a refactoring specific message for overloading.

+	 */

+	public String createOverloadingMessage();

+

+}

diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/ITeamConstants.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/ITeamConstants.java
new file mode 100644
index 0000000..a491b2c
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/ITeamConstants.java
@@ -0,0 +1,66 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2007, 2009 Technical University Berlin,
+ * Germany.
+ * 
+ * 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: ITeamConstants.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.util;
+
+import org.eclipse.jdt.core.Signature;
+
+/**
+ * @author svacina
+ *
+ * Constants for class org.objectteams.Team
+ */
+@SuppressWarnings("nls")
+public interface ITeamConstants
+{
+	/**
+	 *	constants for class team:
+	 *	- virtualTeamMethodNames: Names of virtual team methods (_OT$ methods excluded)
+	 *	- virtualTeamMethodParamTypes: parameter types of virtual team methods
+	 *	- virtualTeamMethodReturnTypes: return types pf virtual team methods 
+	 */
+	String[] noParams= new String[0];
+	String[] virtualTeamMethodNames = new String[]{"getActivationRepr", "getActivationRepr",
+			"isActive","activate", "deactivate",
+			"hasRole", "hasRole",
+			"hasRole", "hasRole",
+			"getRole", "getRole",
+			"getRole", "getRole",
+			"isExecutingCallin",
+			"unregisterRole", "unregisterRole",
+			"unregisterRole", "unregisterRole"};
+	
+	String[][] virtualTeamMethodParamTypes = new String[][]{noParams, noParams,
+			noParams, noParams, noParams,
+			{"QObject;"}, {"Qjava.lang.Object;"},
+			{"QObject;", "QClass;"},{"Qjava.lang.Object;", "Qjava.lang.Class;"},
+			{"QObject;"}, {"Qjava.lang.Object;"},
+			{"QObject;", "QClass;"},{"Qjava.lang.Object;", "Qjava.lang.Class;"},
+			noParams,
+			{"QObject;"}, {"Qjava.lang.Object;"},
+			{"QObject;", "QClass;"},{"Qjava.lang.Object;", "Qjava.lang.Class;"}};
+	
+	String[] virtualTeamMethodReturnTypes = new String[]{"QString;", "Qjava.lang.String;",
+			Signature.SIG_BOOLEAN, Signature.SIG_VOID, Signature.SIG_VOID,
+			Signature.SIG_BOOLEAN, Signature.SIG_BOOLEAN,
+			Signature.SIG_BOOLEAN, Signature.SIG_BOOLEAN,
+			"QObject;", "Qjava.lang.Object;",
+			"QObject;", "Qjava.lang.Object;",
+			Signature.SIG_BOOLEAN,
+			Signature.SIG_VOID, Signature.SIG_VOID,
+			Signature.SIG_VOID, Signature.SIG_VOID};
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/RefactoringUtil.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/RefactoringUtil.java
new file mode 100644
index 0000000..e80a869
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/util/RefactoringUtil.java
@@ -0,0 +1,1392 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2009 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute and Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany.
+ * 
+ * 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: RefactoringUtil.java 23473 2010-02-05 19:46:08Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ * Johannes Gebauer - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.refactoring.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AbstractMethodMappingDeclaration;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.CallinMappingDeclaration;
+import org.eclipse.jdt.core.dom.CalloutMappingDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodMappingElement;
+import org.eclipse.jdt.core.dom.MethodSpec;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.RoleTypeDeclaration;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.SearchRequestor;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.corext.Corext;
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.core.dom.NodeFinder;
+import org.eclipse.jdt.internal.corext.refactoring.Checks;
+import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
+import org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2;
+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
+import org.eclipse.jdt.internal.corext.util.JdtFlags;
+import org.eclipse.jdt.internal.corext.util.Messages;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
+import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
+import org.eclipse.objectteams.otdt.core.IMethodMapping;
+import org.eclipse.objectteams.otdt.core.IOTType;
+import org.eclipse.objectteams.otdt.core.IRoleType;
+import org.eclipse.objectteams.otdt.core.OTModelManager;
+import org.eclipse.objectteams.otdt.core.TypeHelper;
+import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
+import org.eclipse.objectteams.otdt.core.search.OTSearchEngine;
+import org.eclipse.objectteams.otdt.core.search.OTSearchRequestor;
+import org.eclipse.objectteams.otdt.internal.core.InheritedMethodsRequestor;
+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchy;
+import org.eclipse.objectteams.otdt.internal.core.OTTypeHierarchyTraverser;
+import org.eclipse.objectteams.otdt.internal.refactoring.OTRefactoringPlugin;
+import org.eclipse.objectteams.otdt.internal.refactoring.corext.OTRefactoringCoreMessages;
+import org.eclipse.objectteams.otdt.internal.refactoring.corext.base.OTRefactoringStatusCodes;
+
+/**
+ * This utility class is a part of the OT/J refactoring adaptation. It contains
+ * some OT refactoring related helper methods.
+ * 
+ * @author brcan
+ */
+@SuppressWarnings("restriction")
+public class RefactoringUtil implements ITeamConstants {
+	/**
+	 * Checks whether the top-level type of the given compilation unit is a
+	 * regular class or a team class.
+	 * 
+	 * @param compUnit
+	 *            the given compilation unit
+	 * @param str
+	 *            the string describing the error
+	 * @return the refactoring status
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOOClass(ICompilationUnit compUnit, String str) throws JavaModelException {
+		RefactoringStatus status = new RefactoringStatus();
+		IType type = robustFindPrimaryType(compUnit);
+
+		if (Flags.isTeam(type.getFlags())) {
+			status.addFatalError(OTRefactoringCoreMessages.getString(str));
+		}
+		return status;
+	}
+
+	/*
+	 * Make a best guess to find the primary type of a CU even if names do not
+	 * match.
+	 */
+	private static IType robustFindPrimaryType(ICompilationUnit compUnit) {
+		IType type = compUnit.findPrimaryType();
+		if (type != null)
+			return type;
+		IType[] types;
+		try {
+			types = compUnit.getTypes();
+			if (types != null) {
+				for (IType type2 : types) {
+					if (Flags.isPublic(type2.getFlags()))
+						return type2;
+				}
+				if (types.length > 0)
+					return types[0];
+			}
+		} catch (JavaModelException e) {
+			// nothing useful found, return null below
+		}
+		return null;
+	}
+
+	/**
+	 * Returns all role types contained in the given project.
+	 * 
+	 * @param thisProject
+	 *            the given project
+	 * @return an array containing all role types of the given project
+	 * @throws JavaModelException
+	 * 
+	 * @deprecated use getAllRoleClasses(IJavaProject, IProgressMonitor) instead
+	 */
+	public static IType[] getAllRoleTypes(IJavaProject thisProject) throws JavaModelException {
+		List<IType> roles = new ArrayList<IType>();
+		IPackageFragment[] packages = thisProject.getPackageFragments();
+
+		for (int idx = 0; idx < packages.length; idx++) {
+			if (packages[idx].getKind() != IPackageFragmentRoot.K_BINARY) {
+				// get all compilation units in this package
+				ICompilationUnit[] compUnits = packages[idx].getCompilationUnits();
+				if (compUnits != null && compUnits.length != 0) {
+					for (int idy = 0; idy < compUnits.length; idy++) {
+						// get all top-level types declared
+						// in this compilation unit
+						IType[] types = compUnits[idy].getTypes();
+						if (types != null && types.length != 0) {
+							for (int idz = 0; idz < types.length; idz++) {
+								// add role files
+								if (TypeHelper.isRole(types[idz].getFlags())) {
+									roles.add(types[idz]);
+								}
+								if (Modifier.isTeam(types[idz].getFlags())) {
+									// get all roles of this team
+									IType[] rolesOfTeam = types[idz].getTypes();
+									for (int roleNr = 0; roleNr < rolesOfTeam.length; roleNr++) {
+										roles.add(rolesOfTeam[roleNr]);
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		return roles.toArray(new IType[roles.size()]);
+	}
+
+	/**
+	 * Returns all role types contained in the given project and related
+	 * projects.
+	 * 
+	 * @param project
+	 *            the given project
+	 * @param monitor
+	 *            the progress monitor
+	 * @return an array of role types
+	 */
+	public static IOTType[] getAllRoleClasses(IJavaProject project, IProgressMonitor monitor) throws JavaModelException {
+		OTSearchRequestor requestor = new OTSearchRequestor();
+		try {
+			SearchPattern rolePattern = OTSearchEngine.createRoleTypePattern(IJavaSearchConstants.TYPE, SearchPattern.R_EXACT_MATCH);
+			IJavaElement[] relevantProjects = getRelevantProjects(project);
+			IJavaSearchScope scope = OTSearchEngine.createOTSearchScope(relevantProjects, true);
+			OTSearchEngine engine = new OTSearchEngine();
+			engine.search(rolePattern, scope, requestor, monitor);
+		} catch (CoreException ex) {
+			throw new JavaModelException(ex);
+		}
+
+		return requestor.getOTTypes();
+	}
+
+	public static ArrayList<IRoleType> getAllRolesForBase(IType baseType) throws CoreException {
+        OTSearchEngine engine = new OTSearchEngine();
+        IJavaSearchScope searchScope = SearchEngine.createWorkspaceScope();
+        SearchPattern pattern = SearchPattern.createPattern(baseType, IJavaSearchConstants.PLAYEDBY_REFERENCES);
+        final ArrayList<IRoleType> roles = new ArrayList<IRoleType>();
+        if (pattern == null)
+            OTRefactoringPlugin.getInstance().getLog().log(new Status(Status.ERROR, OTRefactoringPlugin.PLUGIN_ID, "Error creating pattern")); //$NON-NLS-1$
+        else
+        	engine.search(
+                pattern, 
+                searchScope, 
+                new SearchRequestor() {
+                    public void acceptSearchMatch(SearchMatch match) throws CoreException
+                    {
+                        Object element = match.getElement();
+                        if (element instanceof IType)
+							roles.add((IRoleType) OTModelManager.getOTElement((IType) element));
+                    }
+                },
+                null);
+        return roles;
+	}
+
+	private static IJavaElement[] getRelevantProjects(IJavaProject srcProject) throws JavaModelException {
+		List<IJavaProject> relevantProjects = new ArrayList<IJavaProject>();
+		relevantProjects.add(srcProject); // this one is relevant for sure
+
+		IJavaProject[] allJavaProjects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+		for (int idx = 0; idx < allJavaProjects.length; idx++) {
+			IJavaProject prj = allJavaProjects[idx];
+			if (prj.isOnClasspath(srcProject)) {
+				relevantProjects.add(prj);
+			}
+		}
+		return relevantProjects.toArray(new IJavaElement[relevantProjects.size()]);
+	}
+
+	/**
+	 * Returns all bound base types of the given role types, that are declared
+	 * by playedBy.
+	 * 
+	 * @param roleTypes
+	 *            an array of IRoleTypes
+	 * @return a list of bound base types
+	 * @throws JavaModelException
+	 */
+	public static ArrayList<IType> getAllDeclaredBaseTypes(IOTType[] roleTypes) throws JavaModelException {
+		ArrayList<IType> baseTypes = new ArrayList<IType>();
+		for (int idx = 0; idx < roleTypes.length; idx++) {
+			// IRoleType roleType =
+			// (IRoleType)OTModelManager.getOTElement(roleTypes[idx]);
+			IRoleType roleType = (IRoleType) roleTypes[idx];
+			if (roleType.getBaseclassName() == null) {
+				continue;
+			}
+			IType baseType = roleType.getBaseClass();
+			if (baseType != null && !baseTypes.contains(baseType)) {
+				baseTypes.add(baseType);
+			}
+		}
+		return baseTypes;
+	}
+
+	public static IMethod[] hierarchyDeclaresMethodName(IProgressMonitor pm, IMethod method, String newName) throws CoreException {
+		Set<IMethod> result = new HashSet<IMethod>();
+		IType type = method.getDeclaringType();
+		ITypeHierarchy hier = type.newTypeHierarchy(pm);
+		IMethod foundMethod = Checks.findMethod(newName, method.getParameterTypes().length, false, type);
+		if (foundMethod != null) {
+			result.add(foundMethod);
+		}
+		IMethod[] foundInHierarchyClasses = classesDeclareMethodName(hier, Arrays.asList(hier.getAllClasses()), method, newName);
+		if (foundInHierarchyClasses != null) {
+			result.addAll(Arrays.asList(foundInHierarchyClasses));
+		}
+		IType[] implementingClasses = hier.getImplementingClasses(type);
+		IMethod[] foundInImplementingClasses = classesDeclareMethodName(hier, Arrays.asList(implementingClasses), method, newName);
+		if (foundInImplementingClasses != null) {
+			result.addAll(Arrays.asList(foundInImplementingClasses));
+		}
+		return result.toArray(new IMethod[result.size()]);
+	}
+
+	private static IMethod[] classesDeclareMethodName(ITypeHierarchy hier, List<IType> classes, IMethod method, String newName) throws CoreException {
+		Set<IMethod> result = new HashSet<IMethod>();
+		IType type = method.getDeclaringType();
+		List<IType> subtypes = Arrays.asList(hier.getAllSubtypes(type));
+
+		int parameterCount = method.getParameterTypes().length;
+		boolean isMethodPrivate = JdtFlags.isPrivate(method);
+
+		for (Iterator<IType> iter = classes.iterator(); iter.hasNext();) {
+			IType clazz = iter.next();
+			IMethod[] methods = clazz.getMethods();
+			boolean isSubclass = subtypes.contains(clazz);
+			for (int j = 0; j < methods.length; j++) {
+				IMethod foundMethod = Checks.findMethod(newName, parameterCount, false, new IMethod[] { methods[j] });
+				if (foundMethod == null) {
+					continue;
+				}
+				if (isSubclass || type.equals(clazz)) {
+					result.add(foundMethod);
+				} else if ((!isMethodPrivate) && (!JdtFlags.isPrivate(methods[j]))) {
+					result.add(foundMethod);
+				}
+			}
+		}
+		return result.toArray(new IMethod[result.size()]);
+	}
+
+	/**
+	 * Checks if the given method is declared in an interface. If the method's
+	 * declaring type is an interface the method returns <code>false</code> if
+	 * it is only declared in that interface.
+	 */
+	public static IMethod isDeclaredInInterface(IMethod method, OTTypeHierarchy hierarchy, IProgressMonitor pm) throws JavaModelException {
+		assert isVirtual(method);
+		try {
+			IType[] classes = hierarchy.getAllClasses();
+			IProgressMonitor subPm = new SubProgressMonitor(pm, 3);
+			subPm.beginTask("", classes.length); //$NON-NLS-1$
+			for (int idxAllHierarchyClasses = 0; idxAllHierarchyClasses < classes.length; idxAllHierarchyClasses++) {
+				ITypeHierarchy superTypes = hierarchy.getOTSuperTypeHierarchy(classes[idxAllHierarchyClasses]);
+				IType[] superinterfaces = superTypes.getAllSuperInterfaces(classes[idxAllHierarchyClasses]);
+
+				for (int idxSuperInterfaces = 0; idxSuperInterfaces < superinterfaces.length; idxSuperInterfaces++) {
+					IMethod found = Checks.findSimilarMethod(method, superinterfaces[idxSuperInterfaces]);
+					if (found != null && !found.equals(method))
+						return found;
+				}
+				subPm.worked(1);
+			}
+			return null;
+		} finally {
+			pm.done();
+		}
+	}
+
+	public static boolean isVirtual(IMethod method) throws JavaModelException {
+		IType declaringType = method.getDeclaringType();
+
+		if (TypeHelper.isRole(declaringType.getFlags())) {
+			if (method.isConstructor())
+				return false;
+			// note: private role method is virtual
+			// if (JdtFlags.isPrivate(method))
+			// return false;
+			if (JdtFlags.isStatic(method))
+				return false;
+		} else {
+			if (method.isConstructor())
+				return false;
+			if (JdtFlags.isPrivate(method))
+				return false;
+			if (JdtFlags.isStatic(method))
+				return false;
+		}
+		return true;
+	}
+
+	public static IMethod overridesAnotherMethod(IMethod method, OTTypeHierarchy hier, IProgressMonitor pm) throws JavaModelException {
+		IType declaringType = method.getDeclaringType();
+		InheritedMethodsRequestor requestor = new InheritedMethodsRequestor(declaringType, true, true);
+		OTTypeHierarchyTraverser traverser = new OTTypeHierarchyTraverser(requestor, OTTypeHierarchyTraverser.SUPER_HIERARCHY,
+				OTTypeHierarchyTraverser.TRAVERSE_EXPLICIT_FIRST, false, false, pm);
+
+		traverser.traverse();
+		IMethod[] collectedMethods = requestor.getResult();
+
+		for (int idx = collectedMethods.length - 1; idx >= 0; idx--) {
+			if (method.isSimilar(collectedMethods[idx])) {
+				return collectedMethods[idx];
+			}
+		}
+		return null;
+	}
+
+	public static boolean isRoleMethod(IMethod method) throws JavaModelException {
+		IType type = method.getDeclaringType();
+		IOTType otType = OTModelManager.getOTElement(type);
+
+		if (otType == null) {
+			return false;
+		} else if (otType.isRole()) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	public static String stripOffJavaSuffix(String compUnit) {
+		int dot = compUnit.lastIndexOf('.');
+		return compUnit.substring(0, dot);
+	}
+
+	/**
+	 * Returns the corresponding DOM-AST node for the given role type.
+	 * 
+	 * @param role
+	 *            the given role type
+	 * @return node of type RoleTypeDeclaration
+	 * @throws JavaModelException
+	 */
+	public static RoleTypeDeclaration getRoleClassDeclaration(IMember role) throws JavaModelException {
+		ASTNode result = getASTNode(role, RoleTypeDeclaration.class);
+		return (RoleTypeDeclaration) result;
+	}
+
+	/**
+	 * Returns the corresponding DOM-AST node for the given method.
+	 * 
+	 * @param method
+	 *            the given method
+	 * @return node of type MethodDeclaration
+	 * @throws JavaModelException
+	 */
+	public static MethodDeclaration getMethodDeclaration(IMember method) throws JavaModelException {
+		ASTNode result = getASTNode(method, MethodDeclaration.class);
+		return (MethodDeclaration) result;
+	}
+
+	/**
+	 * Determines the focus type, i.e. the destination type of the refactored
+	 * element (e.g. the destination type for an extracted or moved method).
+	 * 
+	 * @param topLevelType
+	 *            the top-level type of the destination compilation unit
+	 * @param destinationType
+	 *            the destination type node
+	 * @return the focus type, i.e. either a regular class (including team) or a
+	 *         role class
+	 */
+	public static IType determineFocusType(IType topLevelType, ASTNode destinationType) {
+		// if the destination of the extracted/moved code fragment/element is a
+		// role type,
+		// this role is the focus type...
+		if (destinationType instanceof RoleTypeDeclaration) {
+			RoleTypeDeclaration roleTypeDecl = (RoleTypeDeclaration) destinationType;
+			ITypeBinding roleTypeBinding = ASTNodes.getTypeBinding(roleTypeDecl.getName());
+			// if role is declared in the top-level type, get it...
+			if (roleTypeBinding != null) {
+				// Note: use String-based comparison for ITypeBinding <-> IType:
+				String topLevelName = topLevelType.getFullyQualifiedName();
+				String roleName = roleTypeBinding.getQualifiedName();
+				if (roleName.equals(topLevelName))
+					return topLevelType; // top level = focus (RoFi)
+				if (roleTypeBinding.getDeclaringClass().getQualifiedName().equals(topLevelName)) {
+					String simpleRoleName = roleTypeBinding.getName();
+					// role name very likely starts with __OT__, strip it off:
+					if (simpleRoleName.startsWith(IOTConstants.OT_DELIM))
+						simpleRoleName = simpleRoleName.substring(IOTConstants.OT_DELIM_LEN);
+					return TypeHelper.findRoleType(topLevelType, simpleRoleName);
+				}
+				// ...else find the nested role
+				else {
+					String relativeRoleName = getRelativeName(topLevelName, roleName);
+					return TypeHelper.findNestedRoleType(topLevelType, relativeRoleName);
+				}
+			}
+			return null;
+		}
+		// ...else the focus type is a team or regular class
+		else {
+			return topLevelType;
+		}
+	}
+
+	/**
+	 * Make the given qualified name relative, so that the simple name or
+	 * rootType is the first part of the resulting name.
+	 * 
+	 * @param rootType
+	 * @param fullyQualifiedName
+	 * @return
+	 */
+	private static String getRelativeName(String rootType, String fullyQualifiedName) {
+		assert fullyQualifiedName.startsWith(rootType) : "role type must start like enclosing team"; //$NON-NLS-1$
+		int pos = rootType.lastIndexOf('.');
+		if (pos == -1)
+			pos = rootType.length();
+		return fullyQualifiedName.substring(pos + 1);
+	}
+
+	public static RefactoringStatus checkOverloading(IMethod[] inheritedMethods, String newName, String[] newParameterTypes, IOverloadingMessageCreator msgCreator) {
+		RefactoringStatus result = new RefactoringStatus();
+
+		for (int idx = 0; idx < inheritedMethods.length; idx++) {
+			// check if an inherited method or a local method has the
+			// same name as the method to be refactored
+			IMethod actualMethod = inheritedMethods[idx];
+			if (actualMethod.getElementName().equals(newName)) {
+				// get number of parameters of actual method
+				int actualMethodParamCount = actualMethod.getParameterTypes().length;
+				// get parameter types of actual method
+				String[] actualMethodParamTypes = getParameterTypesOfActualMethod(actualMethod);
+				// get number of parameters of method to be refactored
+				int refactoredMethodParamCount = newParameterTypes == null ? 0 : newParameterTypes.length;
+
+				// check if this method has a different number of parameters
+				// than
+				// the method to be refactored or...
+				if (actualMethodParamCount != refactoredMethodParamCount) {
+					// if overloading is present, issue a warning
+					result.merge(addOverloadingWarning(msgCreator));
+				}
+				// ...if it has the same number of parameters but different
+				// parameter types
+				else if (newParameterTypes != null) {
+					for (int idz = 0; idz < actualMethodParamTypes.length; idz++) {
+						if (!actualMethodParamTypes[idz].equals(newParameterTypes[idz])) {
+							// if overloading is present, issue a warning
+							result.merge(addOverloadingWarning(msgCreator));
+						}
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	private static String[] getParameterTypesOfActualMethod(IMethod actualMethod) {
+		String[] actualMethodParamTypes = actualMethod.getParameterTypes();
+		String[] readableActualMethodParamTypes = new String[actualMethodParamTypes.length];
+		for (int idy = 0; idy < actualMethodParamTypes.length; idy++) {
+			// convert parameter types into readable names
+			readableActualMethodParamTypes[idy] = Signature.toString(actualMethodParamTypes[idy]);
+		}
+		return readableActualMethodParamTypes;
+	}
+
+	@SuppressWarnings("unchecked")
+	// List getBaseMappingElements()
+	public static RefactoringStatus checkForAmbiguousBaseMethodSpecs(ArrayList<IRoleType> boundRoleTypes, String newMethodName, String oldMethodName, IAmbuguityMessageCreator msgCreator)
+			throws JavaModelException {
+		RefactoringStatus result = new RefactoringStatus();
+
+		for (Iterator<IRoleType> iter = boundRoleTypes.iterator(); iter.hasNext();) {
+			IRoleType boundRoleType = iter.next();
+			// get all method mappings of bound role type
+			AbstractMethodMappingDeclaration[] mappings = RefactoringUtil.getAllMethodMappings(boundRoleType);
+
+			if (mappings != null && mappings.length != 0) {
+				for (int idx = 0; idx < mappings.length; idx++) {
+					AbstractMethodMappingDeclaration mapping = mappings[idx];
+					if (mapping instanceof CallinMappingDeclaration) {
+						CallinMappingDeclaration callinDecl = (CallinMappingDeclaration) mapping;
+						List<MethodMappingElement> baseMethodSpecs = callinDecl.getBaseMappingElements();
+						for (Iterator<MethodMappingElement> iterator = baseMethodSpecs.iterator(); iterator.hasNext();) {
+							MethodMappingElement baseMethodSpec = iterator.next();
+							String baseMethodName = baseMethodSpec.getName().getIdentifier();
+							// check if base method specifier in callin mapping
+							// has
+							// no signature and if it has the same name as the
+							// extracted
+							// method
+							if (!baseMethodSpec.hasSignature() && (baseMethodName.equals(newMethodName) || baseMethodName.equals(oldMethodName))) {
+								// create the context
+								RefactoringStatusContext context = createContext(boundRoleType, baseMethodSpec);
+								// if it has the same name, issue an error
+								result.merge(addAmbiguityFatalError(context, msgCreator));
+							}
+						}
+					} else if (mapping instanceof CalloutMappingDeclaration) {
+						CalloutMappingDeclaration calloutDecl = (CalloutMappingDeclaration) mapping;
+						MethodMappingElement baseElement = calloutDecl.getBaseMappingElement();
+						// check if base element is a method spec and not a
+						// field access spec
+						if (baseElement instanceof MethodSpec) {
+							MethodSpec baseMethodSpec = (MethodSpec) baseElement;
+							String baseMethodName = baseMethodSpec.getName().getIdentifier();
+							// check if base method specifier in callout mapping
+							// has
+							// no signature and if it has the same name as the
+							// extracted
+							// method
+							if (!baseMethodSpec.hasSignature() && (baseMethodName.equals(newMethodName) || baseMethodName.equals(oldMethodName))) {
+								// create the context
+								RefactoringStatusContext context = createContext(boundRoleType, baseMethodSpec);
+								// if it has the same name, issue an error
+								result.merge(addAmbiguityFatalError(context, msgCreator));
+							}
+						}
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	public static RefactoringStatus checkForAmbiguousRoleMethodSpecs(IRoleType roleType, String newMethodName, IAmbuguityMessageCreator msgCreator) throws JavaModelException {
+		RefactoringStatus result = new RefactoringStatus();
+		// get all method mappings of role type
+		AbstractMethodMappingDeclaration[] mappings = RefactoringUtil.getAllMethodMappings(roleType);
+
+		if (mappings != null && mappings.length != 0) {
+			for (int idx = 0; idx < mappings.length; idx++) {
+				AbstractMethodMappingDeclaration mapping = mappings[idx];
+				if (mapping instanceof CallinMappingDeclaration) {
+					CallinMappingDeclaration callinDecl = (CallinMappingDeclaration) mapping;
+					MethodSpec roleMethodSpec = (MethodSpec) callinDecl.getRoleMappingElement();
+					String roleMethodName = roleMethodSpec.getName().getIdentifier();
+					// check if role method specifier in callin mapping has
+					// no signature and if it has the same name as the extracted
+					// method
+					if (!roleMethodSpec.hasSignature() && roleMethodName.equals(newMethodName)) {
+						// create the context
+						RefactoringStatusContext context = createContext(roleType, roleMethodSpec);
+						// if it has the same name, issue an error
+						result.merge(addAmbiguityFatalError(context, msgCreator));
+					}
+				} else if (mapping instanceof CalloutMappingDeclaration) {
+					CalloutMappingDeclaration calloutDecl = (CalloutMappingDeclaration) mapping;
+					MethodSpec roleMethodSpec = (MethodSpec) calloutDecl.getRoleMappingElement();
+					String roleMethodName = roleMethodSpec.getName().getIdentifier();
+					// check if role method specifier in callout mapping has
+					// no signature and if it has the same name as the extracted
+					// method
+					if (!roleMethodSpec.hasSignature() && roleMethodName.equals(newMethodName)) {
+						// create the context
+						RefactoringStatusContext context = createContext(roleType, roleMethodSpec);
+						// if it has the same name, issue an error
+						result.merge(addAmbiguityFatalError(context, msgCreator));
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Returns all method mappings of the given role type.
+	 * 
+	 * @param roleType
+	 *            the given role type
+	 * @return an array of method mapping declarations
+	 * @throws JavaModelException
+	 */
+	public static AbstractMethodMappingDeclaration[] getAllMethodMappings(IRoleType roleType) throws JavaModelException {
+		RoleTypeDeclaration roleClassDecl = getRoleClassDeclaration(roleType);
+		// get all callin and callout mappings of given role type
+		AbstractMethodMappingDeclaration[] callinMappings = roleClassDecl.getCallIns();
+		AbstractMethodMappingDeclaration[] calloutMappings = roleClassDecl.getCallOuts();
+
+		AbstractMethodMappingDeclaration[] mappings = new AbstractMethodMappingDeclaration[callinMappings.length + calloutMappings.length];
+		if (callinMappings.length != 0) {
+			System.arraycopy(callinMappings, 0, mappings, 0, callinMappings.length);
+			System.arraycopy(calloutMappings, 0, mappings, callinMappings.length, calloutMappings.length);
+		} else {
+			System.arraycopy(calloutMappings, 0, mappings, 0, calloutMappings.length);
+		}
+		return mappings;
+	}
+
+	public static RefactoringStatus addOverloadingWarning(IOverloadingMessageCreator msgCreator) {
+		RefactoringStatus result = RefactoringUtil.createWarningStatus(msgCreator.createOverloadingMessage(),
+				null, OTRefactoringStatusCodes.OVERLOADING);
+		return result;
+	}
+
+	public static RefactoringStatus addAmbiguityFatalError(RefactoringStatusContext context, IAmbuguityMessageCreator msgCreator) {
+		RefactoringStatus result = RefactoringUtil.createFatalErrorStatus(msgCreator.createAmbiguousMethodSpecifierMsg(),
+				context, OTRefactoringStatusCodes.AMBIGUOUS_METHOD_SPECIFIER);
+		return result;
+	}
+
+	
+	/**
+	 * Performs overloading checks for a team class or a regular class.
+	 * 
+	 * @param result
+	 *            the actual refactoring status
+	 * @param newMethodName
+	 *            the name of the refactored method
+	 * @param focusType
+	 *            the destination type of the refactored method
+	 * @param msgCreator a message creator object to provide refactoring specific error messages
+	 * @param pm
+	 *            the progress monitor
+	 * @param newMethod
+	 *            the refactored method
+	 * @return the refactoring status containing a warning entry in case of
+	 *         overloading; ok otherwise.
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOverloadingForTeamOrRegularClass(RefactoringStatus result, String newMethodName, String[] newParamTypes,
+			IType focusType, IOverloadingMessageCreator msgCreator, IProgressMonitor pm) throws JavaModelException {
+		RefactoringStatus status = new RefactoringStatus();
+
+		RefactoringStatusEntry overloading = result.getEntryMatchingCode(Corext.getPluginId(), OTRefactoringStatusCodes.OVERLOADING);
+
+		if (overloading == null) {
+			IMethod[] methods = TypeHelper.getInheritedMethods(focusType, true, true, true, pm);
+			status.merge(checkOverloading(methods, newMethodName, newParamTypes, msgCreator));
+		}
+		return status;
+	}
+
+	/**
+	 * Performs overloading and ambiguity checks for a role type.
+	 * 
+	 * @param result
+	 *            the actual refactoring status
+	 * @param newMethodName
+	 *            the name of the refactored method
+	 * @param roleType
+	 *            the focus role
+	 * @param ambiguitymsgCreator a message creator object to provide refactoring specific error messages
+	 * @param overloadingmsgCreator a message creator object to provide refactoring specific error messages
+	 * @param pm
+	 *            the progress monitor
+	 * @param newMethod
+	 *            the refactored method
+	 * @return the refactoring status containing a warning entry in case of
+	 *         overloading, or a warning and fatal error entry in case of
+	 *         overloading and ambiguous method specs; ok otherwise.
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOverloadingAndAmbiguityForRole(RefactoringStatus result, String newMethodName, String[] newParamTypes,
+			IRoleType roleType, IAmbuguityMessageCreator ambiguityMsgCreator, IOverloadingMessageCreator overloadingMsgCreator, IProgressMonitor pm) throws JavaModelException {
+		RefactoringStatus status = new RefactoringStatus();
+
+		RefactoringStatusEntry overloading = result.getEntryMatchingCode(Corext.getPluginId(), OTRefactoringStatusCodes.OVERLOADING);
+
+		if (overloading == null) {
+			// NOTE(gbr): result array of getInheritedMethods(..) also includes
+			// private methods. The reason is that method bindings may refer
+			// to hidden base methods (see OTJLD �3.4 and �4.6). This fact
+			// must be considered in the overloading and ambiguity checks.
+			IMethod[] methods = TypeHelper.getInheritedMethods(roleType, true, true, false, pm);
+			status.merge(checkOverloading(methods, newMethodName, newParamTypes, overloadingMsgCreator));
+		}
+		if (status.hasWarning() || result.hasWarning()) {
+			status.merge(checkForAmbiguousRoleMethodSpecs(roleType, newMethodName, ambiguityMsgCreator));
+		}
+		return status;
+	}
+
+	/**
+	 * Performs overloading and ambiguity checks for a bound base type.
+	 * 
+	 * @param result
+	 *            the actual refactoring status
+	 * @param newMethodName
+	 *            the name of the refactored method
+	 * @param oldMethodName
+	 *            the old name of the refactored method
+	 * @param focusType
+	 *            the regarded type
+	 * @param roleTypes
+	 *            the role types contained in the project
+	 * @param ambiguitymsgCreator a message creator object to provide refactoring specific error messages
+	 * @param overloadingmsgCreator a message creator object to provide refactoring specific error messages
+	 * @param pm
+	 *            the progress monitor
+	 * @param newMethod
+	 *            the refactored method
+	 * @return the refactoring status containing a warning entry in case of
+	 *         overloading, or a warning and fatal error entry in case of
+	 *         overloading and ambiguous method specs; ok otherwise.
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOverloadingAndAmbiguityForBase(RefactoringStatus result, String newMethodName, String oldMethodName,
+			String[] newParamTypes, IType focusType, IOTType[] roleTypes, IAmbuguityMessageCreator ambiguityMsgCreator, IOverloadingMessageCreator overloadingMsgCreator, IProgressMonitor pm) throws JavaModelException {
+		RefactoringStatus status = new RefactoringStatus();
+
+		ArrayList<IRoleType> boundRoleTypes = new ArrayList<IRoleType>();
+		for (int idx = 0; idx < roleTypes.length; idx++) {
+			IRoleType roleType = (IRoleType) roleTypes[idx];
+			IType baseClass = roleType.getBaseClass();
+			if (baseClass != null && baseClass.equals(focusType)) {
+				RefactoringStatusEntry overloadingThis = status.getEntryMatchingCode(Corext.getPluginId(), OTRefactoringStatusCodes.OVERLOADING);
+				RefactoringStatusEntry overloadingOther = result.getEntryMatchingCode(Corext.getPluginId(), OTRefactoringStatusCodes.OVERLOADING);
+
+				// check overloading only once for all role types bound to the
+				// same baseclass
+				if (overloadingThis == null && overloadingOther == null) {
+					// NOTE(gbr): result array of getInheritedMethods(..) also
+					// includes
+					// private methods. The reason is that method bindings may
+					// refer
+					// to hidden base methods (see OTJLD �3.4 and �4.6).
+					// This fact
+					// must be considered in the overloading and ambiguity
+					// checks.
+					IMethod[] baseMethods = TypeHelper.getInheritedMethods(baseClass, true, true, false, pm);
+					status.merge(checkOverloading(baseMethods, newMethodName, newParamTypes, overloadingMsgCreator));
+				}
+				// add role that is bound to the base class to the list
+				boundRoleTypes.add(roleType);
+			}
+		}
+		if (status.hasWarning() || result.hasWarning()) {
+			status.merge(checkForAmbiguousBaseMethodSpecs(boundRoleTypes, newMethodName, oldMethodName, ambiguityMsgCreator));
+		}
+		return status;
+	}
+
+	/**
+	 * Performs overloading and ambiguity checks for a bound base type present
+	 * in the super hierarchy of the focus (destination) type.
+	 * 
+	 * @param newMethodName
+	 *            the name of the refactored method
+	 * @param oldMethodName
+	 *            the old name of the refactored method
+	 * @param superTypes
+	 *            the super types of the focus type
+	 * @param msgCreator a message creator object to provide refactoring specific error messages
+	 * @param roleType
+	 *            the role type bound to the base type
+	 * @return the refactoring status containing a fatal error entry in case of
+	 *         ambiguous method specs; ok otherwise.
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkAmbiguityForBasePresentInFocusTypeSuperhierarchy(String newMethodName, String oldMethodName, IType[] superTypes,
+			IAmbuguityMessageCreator msgCreator, IRoleType roleType) throws JavaModelException {
+		RefactoringStatus status = new RefactoringStatus();
+		ArrayList<IRoleType> roleList = new ArrayList<IRoleType>();
+
+		IType baseClass = roleType.getBaseClass();
+		if (baseClass != null) {
+			for (int idx = 0; idx < superTypes.length; idx++) {
+				if (baseClass.equals(superTypes[idx])) {
+					roleList.add(roleType);
+					status.merge(checkForAmbiguousBaseMethodSpecs(roleList, newMethodName, oldMethodName, msgCreator));
+				}
+			}
+		}
+		return status;
+	}
+
+	/**
+	 * Checks overloading and ambiguity for the given method name and method
+	 * declaration.
+	 * 
+	 * @param compUnit
+	 *            the target compilation unit
+	 * @param destination
+	 *            the ast node representing the destination type
+	 * @param newMethodName
+	 *            the name of the new method
+	 * @param ambiguitymsgCreator a message creator object to provide refactoring specific error messages
+	 * @param overloadingmsgCreator a message creator object to provide refactoring specific error messages
+	 * @param pm
+	 *            the progress monitor
+	 * @param newMethod
+	 *            the method declaration of the new method
+	 * @return the refactoring status
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOverloadingAndAmbiguity(ICompilationUnit compUnit, ASTNode destination, String newMethodName, String[] newParamTypes,
+			IAmbuguityMessageCreator ambiguityMsgCreator, IOverloadingMessageCreator overloadingMsgCreator, IProgressMonitor pm) throws JavaModelException {
+		// get top level type declared in compilation unit
+		IType topLevelType = robustFindPrimaryType(compUnit);
+		// determine focus type: can be either a regular class (including team)
+		// or a role
+		IType focusType = RefactoringUtil.determineFocusType(topLevelType, destination);
+
+		return checkOverloadingAndAmbiguity(focusType, null, newMethodName, newParamTypes, ambiguityMsgCreator, overloadingMsgCreator, pm);
+		
+	}
+
+	/**
+	 * Checks overloading and ambiguity for the given method name and method
+	 * declaration.
+	 * 
+	 * @param focusType
+	 *            the focus type to check for ambiguity
+	 * @param focusTypeHierarchy
+	 *            the type hierarchy for the focus type - will be computed if
+	 *            <code>null</code>
+	 * @param newMethodName
+	 *            the name of the new method
+	 * @param newParamTypes
+	 *            the parameters of the new method
+	 * @param ambigutiymsgCreator a message creator object to provide refactoring specific error messages
+	 * @param overloadingmsgCreator a message creator object to provide refactoring specific error messages
+	 * @param pm
+	 *            the progress monitor
+	 * @return the refactoring status
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOverloadingAndAmbiguity(IType focusType, ITypeHierarchy focusTypeHierarchy, String newMethodName,
+			String[] newParamTypes, IAmbuguityMessageCreator ambigutiyMsgCreator, IOverloadingMessageCreator overloadingMsgCreator, IProgressMonitor pm) throws JavaModelException {
+		ICompilationUnit compUnit = focusType.getCompilationUnit();
+		// create OT typehierarchy
+		if (focusTypeHierarchy == null) {
+			focusTypeHierarchy = new OTTypeHierarchy(focusType, compUnit.getJavaProject(), true);
+			focusTypeHierarchy.refresh(pm);
+		}
+		// get all supertypes of focus type
+		IType[] superTypes = focusTypeHierarchy.getAllSupertypes(focusType);
+		// get all subtypes of focus type
+		IType[] subTypes = focusTypeHierarchy.getAllSubtypes(focusType);
+		// get all role types in this project
+		IOTType[] roleTypes = RefactoringUtil.getAllRoleClasses(compUnit.getJavaProject(), pm);
+		// get all base types
+		ArrayList<IType> baseTypes = RefactoringUtil.getAllDeclaredBaseTypes(roleTypes);
+
+		RefactoringStatus result = new RefactoringStatus();
+		// if the focus type is a team,
+		// check for overloading methods in team and its supertypes
+		if (TypeHelper.isTeam(focusType.getFlags())) {
+			result.merge(RefactoringUtil.checkOverloadingForTeamOrRegularClass(result, newMethodName, newParamTypes, focusType, overloadingMsgCreator, pm));
+			if (result.getSeverity() == RefactoringStatus.WARNING) {
+				return result;
+			}
+		}
+		// if the focus type is a role,
+		// check for overloading methods in role and its supertypes,
+		// and for ambiguity in its method bindings
+		if (TypeHelper.isRole(focusType.getFlags())) {
+			IRoleType roleType = (IRoleType) OTModelManager.getOTElement(focusType);
+			result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForRole(result, newMethodName, newParamTypes, roleType, ambigutiyMsgCreator, overloadingMsgCreator,
+					pm));
+			result.merge(RefactoringUtil.checkAmbiguityForBasePresentInFocusTypeSuperhierarchy(newMethodName, "", superTypes, ambigutiyMsgCreator, roleType));
+		}
+		// if the focus type is an unbound regular class,
+		// check for overloading methods in this class and its supertypes
+		else if (!baseTypes.contains(focusType)) {
+			RefactoringUtil.checkOverloadingForTeamOrRegularClass(result, newMethodName, newParamTypes, focusType, overloadingMsgCreator, pm);
+			if (result.getSeverity() == RefactoringStatus.WARNING) {
+				return result;
+			}
+		}
+		// if the focus type is a bound base class,
+		// check for overloading methods in this base class and its supertypes,
+		// and for ambiguity in method bindings of bound role classes
+		else if (baseTypes.contains(focusType)) {
+			result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForBase(result, newMethodName, "", newParamTypes, focusType, roleTypes,
+					ambigutiyMsgCreator, overloadingMsgCreator, pm));
+		}
+		// if the focus type has subtypes,
+		// check overloading in the super hierarchy of each type
+		if (subTypes.length != 0) {
+			for (int idx = 0; idx < subTypes.length; idx++) {
+				IType subType = subTypes[idx];
+
+				// if the actual subtype of the focus type is a role,
+				// check for overloading methods in this role and its
+				// supertypes and for ambiguity in method bindings
+				if (TypeHelper.isRole(subType.getFlags())) {
+					IRoleType roleType = (IRoleType) OTModelManager.getOTElement(subType);
+					result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForRole(result, newMethodName, newParamTypes, roleType, ambigutiyMsgCreator,
+							overloadingMsgCreator, pm));
+					if (result.hasWarning()) {
+						IType baseClass = roleType.getBaseClass();
+						ArrayList<IRoleType> roleList = new ArrayList<IRoleType>();
+						// if base class of role type is the focus type,
+						// check also ambiguous base method specs
+						if (baseClass != null && baseClass.equals(focusType)) {
+							roleList.add(roleType);
+							result.merge(RefactoringUtil.checkForAmbiguousBaseMethodSpecs(roleList, newMethodName, "", ambigutiyMsgCreator));
+						}
+						// else if base class of role type is a direct or
+						// indirect
+						// superclass of focus type, check also ambiguous base
+						// method specs
+						else {
+							result.merge(RefactoringUtil.checkAmbiguityForBasePresentInFocusTypeSuperhierarchy(newMethodName, "", superTypes, ambigutiyMsgCreator,
+									roleType));
+						}
+					}
+				}
+				// if the actual subtyp of the focus type is an unbound regular
+				// class,
+				// check for overloading methods in this class and its
+				// supertypes
+				else if (!baseTypes.contains(subType)) {
+					result.merge(RefactoringUtil
+							.checkOverloadingForTeamOrRegularClass(result, newMethodName, newParamTypes, subType, overloadingMsgCreator, pm));
+				}
+				// if the actual subtype of the focus type is a bound base
+				// class,
+				// check for overloading methods in this base class and its
+				// supertypes
+				// and for ambiguity in method bindings of bound role classes
+				else if (baseTypes.contains(subType)) {
+					result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForBase(result, newMethodName, "", newParamTypes, subType, roleTypes, ambigutiyMsgCreator,
+							overloadingMsgCreator, pm));
+				}
+			}
+		}
+		return result;
+	}
+
+	// TODO(jsv): copy of checkOverloadingAndAmbiguity with ASTNode as
+	// destination -> remove redundant code
+	/**
+	 * Checks overloading and ambiguity for the given method name and method
+	 * declaration.
+	 * 
+	 * @param compUnit
+	 *            the target compilation unit
+	 * @param focusType
+	 *            the type of the renamed method
+	 * @param newMethodName
+	 *            the name of the new method
+	 * @param oldMethodName
+	 *            the old name of the method
+	 * @param ambiguitymsgCreator a message creator object to provide refactoring specific error messages
+	 * @param overloadingmsgCreator a message creator object to provide refactoring specific error messages.
+	 * @param pm
+	 *            the progress monitor
+	 * @param newMethod
+	 *            the IMethod of the new method
+	 * @return the refactoring status
+	 * @throws JavaModelException
+	 */
+	public static RefactoringStatus checkOverloadingAndAmbiguity(ICompilationUnit compUnit, IType focusType, String newMethodName, String oldMethodName,
+			String[] newParamTypes, IAmbuguityMessageCreator ambiguityMsgCreator, IOverloadingMessageCreator overloadingMsgCreator, IProgressMonitor pm) throws JavaModelException {
+		// FIXME(SH): what is this unused code good for?
+		// get top level type declared in compilation unit
+		// IType topLevelType = compUnit.findPrimaryType();
+		// determine focus type: can be either a regular class (including team)
+		// or a role
+		// IType focusType = RefactoringUtil.determineFocusType(topLevelType,
+		// destination);
+
+		// create OT typehierarchy
+		OTTypeHierarchy completeHierarchy = new OTTypeHierarchy(focusType, compUnit.getJavaProject(), true);
+		completeHierarchy.refresh(pm);
+		// get all supertypes of focus type
+		IType[] superTypes = completeHierarchy.getAllSupertypes(focusType);
+		// get all subtypes of focus type
+		IType[] subTypes = completeHierarchy.getAllSubtypes(focusType);
+		// get all role types in this project
+		IOTType[] roleTypes = RefactoringUtil.getAllRoleClasses(compUnit.getJavaProject(), pm);
+		// get all base types
+		ArrayList<IType> baseTypes = RefactoringUtil.getAllDeclaredBaseTypes(roleTypes);
+
+		RefactoringStatus result = new RefactoringStatus();
+		// if the focus type is a team,
+		// check for overloading methods in team and its supertypes
+		if (TypeHelper.isTeam(focusType.getFlags())) {
+			result.merge(RefactoringUtil.checkOverloadingForTeamOrRegularClass(result, newMethodName, newParamTypes, focusType, overloadingMsgCreator, pm));
+			if (result.getSeverity() == RefactoringStatus.WARNING) {
+				return result;
+			}
+		}
+		// if the focus type is a role,
+		// check for overloading methods in role and its supertypes,
+		// and for ambiguity in its method bindings
+		if (TypeHelper.isRole(focusType.getFlags())) {
+			IRoleType roleType = (IRoleType) OTModelManager.getOTElement(focusType);
+			result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForRole(result, newMethodName, newParamTypes, roleType, ambiguityMsgCreator, overloadingMsgCreator,
+					pm));
+			result.merge(RefactoringUtil.checkAmbiguityForBasePresentInFocusTypeSuperhierarchy(newMethodName, oldMethodName, superTypes, ambiguityMsgCreator, roleType));
+		}
+		// if the focus type is an unbound regular class,
+		// check for overloading methods in this class and its supertypes
+		else if (!baseTypes.contains(focusType)) {
+			RefactoringUtil.checkOverloadingForTeamOrRegularClass(result, newMethodName, newParamTypes, focusType, overloadingMsgCreator, pm);
+			if (result.getSeverity() == RefactoringStatus.WARNING) {
+				return result;
+			}
+		}
+		// if the focus type is a bound base class,
+		// check for overloading methods in this base class and its supertypes,
+		// and for ambiguity in method bindings of bound role classes
+		else if (baseTypes.contains(focusType)) {
+			result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForBase(result, newMethodName, oldMethodName, newParamTypes, focusType, roleTypes,
+					ambiguityMsgCreator, overloadingMsgCreator, pm));
+		}
+		// if the focus type has subtypes,
+		// check overloading in the super hierarchy of each type
+		if (subTypes.length != 0) {
+			for (int idx = 0; idx < subTypes.length; idx++) {
+				IType subType = subTypes[idx];
+
+				// if the actual subtype of the focus type is a role,
+				// check for overloading methods in this role and its
+				// supertypes and for ambiguity in method bindings
+				if (TypeHelper.isRole(subType.getFlags())) {
+					IRoleType roleType = (IRoleType) OTModelManager.getOTElement(subType);
+					result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForRole(result, newMethodName, newParamTypes, roleType, ambiguityMsgCreator,
+							overloadingMsgCreator, pm));
+					if (result.hasWarning()) {
+						IType baseClass = roleType.getBaseClass();
+						ArrayList<IRoleType> roleList = new ArrayList<IRoleType>();
+						// if base class of role type is the focus type,
+						// check also ambiguous base method specs
+						if (baseClass != null && baseClass.equals(focusType)) {
+							roleList.add(roleType);
+							result.merge(RefactoringUtil.checkForAmbiguousBaseMethodSpecs(roleList, newMethodName, oldMethodName, ambiguityMsgCreator));
+						}
+						// else if base class of role type is a direct or
+						// indirect
+						// superclass of focus type, check also ambiguous base
+						// method specs
+						else {
+							result.merge(RefactoringUtil.checkAmbiguityForBasePresentInFocusTypeSuperhierarchy(newMethodName, oldMethodName, superTypes,
+									ambiguityMsgCreator, roleType));
+						}
+					}
+				}
+				// if the actual subtyp of the focus type is an unbound regular
+				// class,
+				// check for overloading methods in this class and its
+				// supertypes
+				else if (!baseTypes.contains(subType)) {
+					result.merge(RefactoringUtil
+							.checkOverloadingForTeamOrRegularClass(result, newMethodName, newParamTypes, subType, overloadingMsgCreator, pm));
+				}
+				// if the actual subtype of the focus type is a bound base
+				// class,
+				// check for overloading methods in this base class and its
+				// supertypes
+				// and for ambiguity in method bindings of bound role classes
+				else if (baseTypes.contains(subType)) {
+					result.merge(RefactoringUtil.checkOverloadingAndAmbiguityForBase(result, newMethodName, oldMethodName, newParamTypes, subType, roleTypes,
+							ambiguityMsgCreator, overloadingMsgCreator, pm));
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Creates a refactoring status context for the given role type and method
+	 * spec.
+	 * 
+	 * @param roleType
+	 *            the role containing the error
+	 * @param methodSpec
+	 *            the method spec that has caused the error
+	 * @return the refactoring status context or null if the context cannot be
+	 *         created
+	 */
+	public static RefactoringStatusContext createContext(IRoleType roleType, MethodMappingElement methodSpec) {
+		RefactoringStatusContext context = JavaStatusContext.create(roleType.getCompilationUnit(), methodSpec);
+		return context;
+	}
+
+	/**
+	 * Creates a warning refactoring status.
+	 * 
+	 * @param msg
+	 *            the message of the warning entry
+	 * @param context
+	 *            the context of the warning entry
+	 * @param code
+	 *            the problem code (@see <code>OTRefactoringStatusCodes</code>)
+	 * @return the refactoring status
+	 */
+	public static RefactoringStatus createWarningStatus(String msg, RefactoringStatusContext context, int code) {
+		return RefactoringStatus.createStatus(RefactoringStatus.WARNING, msg, context, Corext.getPluginId(), code, null);
+	}
+
+	/**
+	 * Creates an error refactoring status.
+	 * 
+	 * @param msg
+	 *            the message of the error entry
+	 * @param context
+	 *            the context of the error entry
+	 * @param code
+	 *            the problem code (@see <code>OTRefactoringStatusCodes</code>)
+	 * @return the refactoring status
+	 */
+	public static RefactoringStatus createErrorStatus(String msg, RefactoringStatusContext context, int code) {
+		return RefactoringStatus.createStatus(RefactoringStatus.ERROR, msg, context, Corext.getPluginId(), code, null);
+	}
+
+	/**
+	 * Creates a fatal error refactoring status.
+	 * 
+	 * @param msg
+	 *            the message of the fatal error entry
+	 * @param context
+	 *            the context of the fatal error entry
+	 * @param code
+	 *            the problem code (@see <code>OTRefactoringStatusCodes</code>)
+	 * @return the refactoring status
+	 */
+	public static RefactoringStatus createFatalErrorStatus(String msg, RefactoringStatusContext context, int code) {
+		return RefactoringStatus.createStatus(RefactoringStatus.FATAL, msg, context, Corext.getPluginId(), code, null);
+	}
+
+	/**
+	 * Checks, if method has a special OT name. Does not use the
+	 * OTTypeHIerarchy, because of performance optimization (team constants are
+	 * using)
+	 * 
+	 * @param current
+	 *            method to check
+	 * @param new method name, should be <code>null</code> or an empty String if
+	 *        you wants to check the current method and not the new method with
+	 *        the same arguments like the current method
+	 * @return the refactoring status
+	 */
+	public static boolean isOTSpecialCase(IMethod origMethod, String newMethodName, boolean checkImplementingClasses, IProgressMonitor pm) throws CoreException {
+		// TODO(jsv) what to do in case of interface is only used by base
+		// class(es) ? to check the impolementing classes is a performance
+		// overhead
+		IType declaringType = origMethod.getDeclaringType();
+
+		if (!Flags.isTeam(declaringType.getFlags())) {
+			// heavyweight check for interfaces
+			if (Flags.isInterface(declaringType.getFlags()) && checkImplementingClasses) {
+				OTTypeHierarchy hier = new OTTypeHierarchy(declaringType, declaringType.getJavaProject(), true);
+				hier.refresh(pm);
+				IType[] impementingClasses = hier.getImplementingClasses(declaringType);
+				boolean teamImplementsInterface = false;
+				for (int idx = 0; idx < impementingClasses.length; idx++) {
+					if (Flags.isTeam(impementingClasses[idx].getFlags())) {
+						teamImplementsInterface = true;
+						break;
+					}
+				}
+
+				if (!teamImplementsInterface) {
+					return false;
+				}
+			} else {
+				return false;
+			}
+		}
+
+		if (newMethodName == null || newMethodName.length() == 0)
+			newMethodName = origMethod.getElementName();
+
+		assert (virtualTeamMethodNames.length == virtualTeamMethodParamTypes.length)
+				&& (virtualTeamMethodParamTypes.length == virtualTeamMethodReturnTypes.length);
+		for (int i = 0; i < virtualTeamMethodNames.length; i++) {
+			if (virtualTeamMethodNames[i].equals(newMethodName) && Checks.compareParamTypes(origMethod.getParameterTypes(), virtualTeamMethodParamTypes[i])
+					&& virtualTeamMethodReturnTypes[i].equals(origMethod.getReturnType())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public static ASTNode getASTNode(IMember member, Class<? extends ASTNode> nodeClass) {
+		if (member == null || member.getCompilationUnit() == null) {
+			return null;
+		}
+
+		ICompilationUnit source = member.getCompilationUnit();
+
+		ASTParser parser = ASTParser.newParser(AST.JLS3);
+		parser.setSource(source);
+		parser.setResolveBindings(true);
+		CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
+		// NOTE(SH): cannot use member.getSourceRange() together with the AST:
+		// member uses declarationSourceEnd (incl. comment) whereas
+		// the ASTConverter uses bodyEnd instead (excluding comment/trailing
+		// '}')
+		// However, getNameRange() should be safe.
+		try {
+			ASTNode name = NodeFinder.perform(astRoot, member.getNameRange());
+			return getParent(name, nodeClass);
+		} catch (JavaModelException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Finds all overridden methods of a certain method.
+	 * 
+	 */
+	public static IMethod[] getOverriddenMethods(IMethod method, IProgressMonitor monitor) throws CoreException {
+
+		assert method != null;
+		return RippleMethodFinder2.getRelatedMethods(method, monitor, null);
+	}
+
+	/**
+	 * Locates the topmost method of an override ripple and returns it. If none
+	 * is found, null is returned.
+	 * 
+	 * @param method
+	 *            the IMethod which may be part of a ripple
+	 * @param typeHierarchy
+	 *            a ITypeHierarchy of the declaring type of the method. May be
+	 *            null
+	 * @param monitor
+	 *            an IProgressMonitor
+	 * @return the topmost method of the ripple, or null if none
+	 * @throws JavaModelException
+	 */
+	public static IMethod getTopmostMethod(IMethod method, ITypeHierarchy typeHierarchy, IProgressMonitor monitor) throws JavaModelException {
+
+		assert method != null;
+
+		ITypeHierarchy hierarchy = typeHierarchy;
+		IMethod topmostMethod = null;
+		final IType declaringType = method.getDeclaringType();
+		if (!declaringType.isInterface()) {
+			if ((hierarchy == null) || !declaringType.equals(hierarchy.getType())) {
+				hierarchy = new OTTypeHierarchy(declaringType, declaringType.getJavaProject(), false);
+				hierarchy.refresh(monitor);
+			}
+			if (hierarchy instanceof OTTypeHierarchy) {
+				IMethod inInterface = isDeclaredInInterface(method, (OTTypeHierarchy) hierarchy, monitor);
+				if (inInterface != null && !inInterface.equals(method))
+					topmostMethod = inInterface;
+			}
+		}
+		if (topmostMethod == null) {
+			if (hierarchy == null) {
+				hierarchy = new OTTypeHierarchy(declaringType, declaringType.getJavaProject(), false);
+				hierarchy.refresh(monitor);
+			}
+			if (hierarchy instanceof OTTypeHierarchy) {
+				IMethod overrides = overridesAnotherMethod(method, (OTTypeHierarchy) hierarchy, monitor);
+				if (overrides != null && !overrides.equals(method))
+					topmostMethod = overrides;
+			}
+		}
+		return topmostMethod;
+	}
+	
+	public static IField fieldIsShadowedInType(String elementName, String typeSignature, IType type) throws JavaModelException {
+		IField field = type.getField(elementName);
+		if (field.exists() && !field.getTypeSignature().equals(typeSignature)) {
+			return field;
+		}
+		return null;
+	}
+
+	public static MethodDeclaration methodToDeclaration(IMethod method, CompilationUnit node) throws JavaModelException {
+		ICompilationUnit methodCU = (ICompilationUnit) method.getAncestor(IJavaElement.COMPILATION_UNIT);
+		if (!methodCU.equals(node.getJavaElement())) {
+			node = RefactoringASTParser.parseWithASTProvider(methodCU, true, null);
+		}
+		Name result = (Name) NodeFinder.perform(node, method.getNameRange());
+		return (MethodDeclaration) getParent(result, MethodDeclaration.class);
+	}
+
+	public static AbstractMethodMappingDeclaration methodMappingToDeclaration(IMethodMapping methodMapping, CompilationUnit node) throws JavaModelException {
+		Name result = (Name) NodeFinder.perform(node, methodMapping.getNameRange());
+		return (AbstractMethodMappingDeclaration) getParent(result, AbstractMethodMappingDeclaration.class);
+	}
+
+	public static RefactoringStatus createNotYetFullyOTAwareMsg(String refactoringName) {
+		return RefactoringStatus.createInfoStatus(Messages.format("The ''{0}'' Refactoring is not yet fully OT-aware!", new Object[] { refactoringName }));
+	}
+
+	@SuppressWarnings("rawtypes")
+	private static ASTNode getParent(ASTNode node, Class parentClass) {
+		do {
+			node = node.getParent();
+		} while (node != null && !parentClass.isInstance(node));
+		return node;
+	}
+
+	public static ASTNode typeToDeclaration(IType type, CompilationUnit node) throws JavaModelException {
+		Name result = (Name) NodeFinder.perform(node, type.getNameRange());
+		if (type.isAnonymous())
+			return getParent(result, AnonymousClassDeclaration.class);
+		return getParent(result, AbstractTypeDeclaration.class);
+	}
+
+	public static RefactoringStatus checkForExistingRoles(String refactoringName,
+			IJavaProject project, IProgressMonitor pm) {
+		try {
+			if(project == null){
+				return createNotYetFullyOTAwareMsg(refactoringName);
+				
+			}
+			if(getAllRoleClasses(project, pm).length > 0){
+				return createNotYetFullyOTAwareMsg(refactoringName);
+			}
+		} catch (JavaModelException e) {
+			return createNotYetFullyOTAwareMsg(refactoringName);
+		}
+		return new RefactoringStatus();
+	}
+
+}