Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425

from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/debugger/openapi/debugger-openapi.iml b/java/debugger/openapi/debugger-openapi.iml
new file mode 100644
index 0000000..52013f3
--- /dev/null
+++ b/java/debugger/openapi/debugger-openapi.iml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="execution-openapi" />
+    <orderEntry type="module" module-name="jsp-openapi" />
+    <orderEntry type="module" module-name="java-psi-api" />
+    <orderEntry type="module" module-name="resources-en" />
+  </component>
+  <component name="copyright">
+    <Base>
+      <setting name="state" value="0" />
+    </Base>
+    <LanguageOptions name="HTML">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JAVA">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="/*&#10; * Copyright 2000-2005 JetBrains s.r.o.&#10; * &#10; * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10; * you may not use this file except in compliance with the License.&#10; * You may obtain a copy of the License at&#10; * &#10; * http://www.apache.org/licenses/LICENSE-2.0&#10; * &#10; * Unless required by applicable law or agreed to in writing, software&#10; * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10; * See the License for the specific language governing permissions and&#10; * limitations under the License.&#10; */" />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JSP">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JavaScript">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="Properties">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="XML">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="__TEMPLATE__">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright 2000-&amp;#36;{today.year} JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="4" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+  </component>
+</module>
+
diff --git a/java/debugger/openapi/src/com/intellij/debugger/DebuggerBundle.java b/java/debugger/openapi/src/com/intellij/debugger/DebuggerBundle.java
new file mode 100644
index 0000000..179cf4a
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/DebuggerBundle.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.CommonBundle;
+import com.intellij.execution.configurations.RemoteConnection;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+public class DebuggerBundle {
+  private static Reference<ResourceBundle> ourBundle;
+
+  @NonNls private static final String BUNDLE = "messages.DebuggerBundle";
+
+  private DebuggerBundle() {
+  }
+
+  public static String getAddressDisplayName(final RemoteConnection connection) {
+    return connection.isUseSockets() ? connection.getHostName() + ":" + connection.getAddress() : connection.getAddress();
+  }
+
+  public static String getTransportName(final RemoteConnection connection) {
+    return connection.isUseSockets() ? message("transport.name.socket") : message("transport.name.shared.memory");
+  }
+
+  public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) {
+    return CommonBundle.message(getBundle(), key, params);
+  }
+
+  private static ResourceBundle getBundle() {
+    ResourceBundle bundle = null;
+    if (ourBundle != null) bundle = ourBundle.get();
+    if (bundle == null) {
+      bundle = ResourceBundle.getBundle(BUNDLE);
+      ourBundle = new SoftReference<ResourceBundle>(bundle);
+    }
+    return bundle;
+  }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/DebuggerContext.java b/java/debugger/openapi/src/com/intellij/debugger/DebuggerContext.java
new file mode 100644
index 0000000..d2c9180
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/DebuggerContext.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.debugger.engine.StackFrameContext;
+import com.intellij.debugger.engine.SuspendContext;
+import com.intellij.openapi.project.Project;
+
+public interface DebuggerContext extends StackFrameContext{
+  SuspendContext getSuspendContext();
+
+  Project getProject();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java b/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java
new file mode 100644
index 0000000..26b02c8
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.intellij.debugger.engine.DebugProcessListener;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.psi.PsiClass;
+import com.intellij.util.Function;
+
+/**
+ * @author lex
+ */
+public abstract class DebuggerManager implements ProjectComponent, JDOMExternalizable {
+  public static DebuggerManager getInstance(Project project) {
+    return project.getComponent(DebuggerManager.class);
+  }
+
+  public abstract DebugProcess getDebugProcess(ProcessHandler processHandler);
+
+  public abstract void addDebugProcessListener(ProcessHandler processHandler, DebugProcessListener listener);
+
+  public abstract void removeDebugProcessListener(ProcessHandler processHandler, DebugProcessListener listener);
+
+  public abstract boolean isDebuggerManagerThread();
+
+  public abstract void addClassNameMapper(NameMapper mapper);
+
+  public abstract void removeClassNameMapper(NameMapper mapper);
+
+  public abstract String getVMClassQualifiedName(PsiClass aClass);
+
+  /**
+   * @deprecated use PositionManagerFactory extension point instead
+   */
+  public abstract void registerPositionManagerFactory(Function<DebugProcess, PositionManager> factory);
+
+  public abstract void unregisterPositionManagerFactory(Function<DebugProcess, PositionManager> factory);
+
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/NameMapper.java b/java/debugger/openapi/src/com/intellij/debugger/NameMapper.java
new file mode 100644
index 0000000..4530806
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/NameMapper.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.psi.PsiClass;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Compilers of some java-based languages (like Scala) produce classes with names different from those declared in sources.
+ * If for some language qualified names of compiled classes differ from names declared in the sources, a NameMapper must be registered
+ * within the DebuggerManager class. 
+ * Multiple registered mappers forms a "chain of responsibility" and the first non-null result is returned.  
+ * If no mappers are registered or all mappers returned null, the result of 
+ * PsiClass.getQualifiedName() will be used as a qualified name of the compiled class 
+ */
+public interface NameMapper {
+  /**
+   * @param aClass a top-level class
+   * @return a qualified name of the corresponding compiled class or null if default machanism of getting qualified names must be used  
+   */
+  String getQualifiedName(@NotNull PsiClass aClass);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java b/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java
new file mode 100644
index 0000000..b3f30af
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+public class NoDataException extends Exception{
+  @Override
+  public Throwable fillInStackTrace() {
+    return this;
+  }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/PositionManager.java b/java/debugger/openapi/src/com/intellij/debugger/PositionManager.java
new file mode 100644
index 0000000..5713483
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/PositionManager.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.debugger.requests.ClassPrepareRequestor;
+import com.sun.jdi.Location;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.request.ClassPrepareRequest;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * Manages the correspondence between source positions and bytecode locations during JVM debugging.
+ * Instances of this class are created by the factory registered via the {@link PositionManagerFactory} extension point.
+ *
+ * @see com.intellij.debugger.engine.JSR45PositionManager
+ */
+public interface PositionManager {
+  /**
+   * Returns the source position corresponding to the specified bytecode location.
+   *
+   * @param location the bytecode location.
+   * @return the corresponding source position.
+   * @throws NoDataException if the location is not in the code managed by this {@code PositionManager}
+   */
+  @Nullable
+  SourcePosition getSourcePosition(@Nullable Location location) throws NoDataException;
+
+  /**
+   * Returns the list of all Java classes corresponding to the specified position in the source code.
+   *
+   * @param classPosition the source position.
+   * @return the list of corresponding Java classes.
+   * @throws NoDataException if the location is not in the code managed by this {@code PositionManager}
+   * @see com.intellij.debugger.engine.jdi.VirtualMachineProxy#classesByName
+   */
+  @NotNull
+  List<ReferenceType> getAllClasses(SourcePosition classPosition) throws NoDataException;
+
+  /**
+   * Returns the list of bytecode locations in a specific class corresponding to the specified position in the source code.
+   *
+   * @param type a Java class (one of the list returned by {@link #getAllClasses}).
+   * @param position the position in the source code.
+   * @return the list of corresponding bytecode locations.
+   * @throws NoDataException if the location is not in the code managed by this {@code PositionManager}
+   * @see ReferenceType#locationsOfLine(int)
+   */
+  @NotNull
+  List<Location> locationsOfLine(ReferenceType type, SourcePosition position) throws NoDataException;
+
+  /**
+   * Called to request the JVM to notify the debugger engine when a class corresponding to a breakpoint location is loaded.
+   * The implementation should calculate the pattern of the class files corresponding to the breakpoint location and call
+   * {@link com.intellij.debugger.requests.RequestManager#createClassPrepareRequest} to create the request.
+   *
+   * @param requestor the object to receive the notification from the JVM.
+   * @param position the location of a breakpoint.
+   * @return the prepare request, or null if the code is managed by this {@code PositionManager} but no class prepare notification is needed
+   * @throws NoDataException if the position is not in the code managed by this {@code PositionManager}
+   */
+  @Nullable
+  ClassPrepareRequest createPrepareRequest(ClassPrepareRequestor requestor, SourcePosition position) throws NoDataException;
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/PositionManagerFactory.java b/java/debugger/openapi/src/com/intellij/debugger/PositionManagerFactory.java
new file mode 100644
index 0000000..e89d423
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/PositionManagerFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public abstract class PositionManagerFactory {
+  public static final ExtensionPointName<PositionManagerFactory> EP_NAME = ExtensionPointName.create("com.intellij.debugger.positionManagerFactory");
+
+  @Nullable
+  public abstract PositionManager createPositionManager(DebugProcess process);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java b/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java
new file mode 100644
index 0000000..9028b14
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import com.intellij.psi.*;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * User: lex
+ * Date: Oct 24, 2003
+ * Time: 8:23:06 PM
+ */
+public abstract class SourcePosition implements Navigatable{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.SourcePosition");
+  @NotNull
+  public abstract PsiFile getFile();
+
+  public abstract PsiElement getElementAt();
+
+  /**
+   * @return a zero-based line number
+   */
+  public abstract int getLine();
+
+  public abstract int getOffset();
+
+  public abstract Editor openEditor(boolean requestFocus);
+
+  private abstract static class SourcePositionCache extends SourcePosition {
+    @NotNull private final PsiFile myFile;
+    private long myModificationStamp = -1L;
+
+    private PsiElement myPsiElement;
+    private Integer myLine;
+    private Integer myOffset;
+
+    public SourcePositionCache(@NotNull PsiFile file) {
+      myFile = file;
+      updateData();
+    }
+
+    @Override
+    @NotNull
+    public PsiFile getFile() {
+      return myFile;
+    }
+
+    @Override
+    public boolean canNavigate() {
+      return getFile().isValid();
+    }
+
+    @Override
+    public boolean canNavigateToSource() {
+      return canNavigate();
+    }
+
+    @Override
+    public void navigate(final boolean requestFocus) {
+      ApplicationManager.getApplication().invokeLater(new Runnable() {
+        @Override
+        public void run() {
+          if (!canNavigate()) {
+            return;
+          }
+          openEditor(requestFocus);
+        }
+      });
+    }
+
+    @Override
+    public Editor openEditor(final boolean requestFocus) {
+      final PsiFile psiFile = getFile();
+      final Project project = psiFile.getProject();
+      if (project.isDisposed()) {
+        return null;
+      }
+      final VirtualFile virtualFile = psiFile.getVirtualFile();
+      if (virtualFile == null || !virtualFile.isValid()) {
+        return null;
+      }
+      final int offset = getOffset();
+      if (offset < 0) {
+        return null;
+      }
+      return FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, virtualFile, offset), requestFocus);
+    }
+
+    private void updateData() {
+      if(dataUpdateNeeded()) {
+        myModificationStamp = myFile.getModificationStamp();
+        myLine = null;
+        myOffset = null;
+        myPsiElement = null;
+      }
+    }
+
+    private boolean dataUpdateNeeded() {
+      if (myModificationStamp != myFile.getModificationStamp()) {
+        return true;
+      }
+      final PsiElement psiElement = myPsiElement;
+      return psiElement != null && !psiElement.isValid();
+    }
+
+    @Override
+    public int getLine() {
+      updateData();
+      if (myLine == null) {
+        myLine = calcLine();
+      }
+      return myLine.intValue();
+    }
+
+    @Override
+    public int getOffset() {
+      updateData();
+      if (myOffset == null) {
+        myOffset = calcOffset();
+      }
+      return myOffset.intValue();
+    }
+
+    @Override
+    public PsiElement getElementAt() {
+      updateData();
+      if (myPsiElement == null) {
+        myPsiElement = calcPsiElement();
+      }
+      return myPsiElement;
+    }
+
+    protected int calcLine() {
+      final PsiFile file = getFile();
+      Document document = null;
+      try {
+        document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
+      }
+      catch (Throwable e) {
+        LOG.error(e);
+      }
+      if (document != null) {
+        try {
+          return document.getLineNumber(calcOffset());
+        }
+        catch (IndexOutOfBoundsException e) {
+          // may happen if document has been changed since the this SourcePosition was created
+        }
+      }
+      return -1;
+    }
+
+    protected int calcOffset() {
+      final PsiFile file = getFile();
+      final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
+      if (document != null) {
+        try {
+          return document.getLineStartOffset(calcLine());
+        }
+        catch (IndexOutOfBoundsException e) {
+          // may happen if document has been changed since the this SourcePosition was created
+        }
+      }
+      return -1;
+    }
+
+    @Nullable
+    protected PsiElement calcPsiElement() {
+      PsiFile psiFile = getFile();
+      int lineNumber = getLine();
+      if(lineNumber < 0) {
+        return psiFile;
+      }
+
+      final Document document = PsiDocumentManager.getInstance(psiFile.getProject()).getDocument(psiFile);
+      if (document == null) {
+        return null;
+      }
+      if (lineNumber >= document.getLineCount()) {
+        return psiFile;
+      }
+      int startOffset = document.getLineStartOffset(lineNumber);
+      if(startOffset == -1) {
+        return null;
+      }
+
+      PsiElement rootElement = psiFile;
+
+      List<PsiFile> allFiles = psiFile.getViewProvider().getAllFiles();
+      if (allFiles.size() > 1) { // jsp & gsp
+        PsiClassOwner owner = ContainerUtil.findInstance(allFiles, PsiClassOwner.class);
+        if (owner != null) {
+          PsiClass[] classes = owner.getClasses();
+          if (classes.length == 1 && classes[0]  instanceof SyntheticElement) {
+            rootElement = classes[0];
+          }
+        }
+      }
+
+      PsiElement element;
+      while(true) {
+        final CharSequence charsSequence = document.getCharsSequence();
+        for (; startOffset < charsSequence.length(); startOffset++) {
+          char c = charsSequence.charAt(startOffset);
+          if (c != ' ' && c != '\t') {
+            break;
+          }
+        }
+        element = rootElement.findElementAt(startOffset);
+
+        if(element instanceof PsiComment) {
+          startOffset = element.getTextRange().getEndOffset() + 1;
+        }
+        else{
+          break;
+        }
+      }
+
+      if (element != null && element.getParent() instanceof PsiForStatement) {
+        return ((PsiForStatement)element.getParent()).getInitialization();
+      }
+      return element;
+    }
+  }
+
+  public static SourcePosition createFromLineComputable(final PsiFile file, final Computable<Integer> line) {
+    return new SourcePositionCache(file) {
+      @Override
+      protected int calcLine() {
+        return line.compute();
+      }
+    };
+  }
+
+  public static SourcePosition createFromLine(final PsiFile file, final int line) {
+    return new SourcePositionCache(file) {
+      @Override
+      protected int calcLine() {
+        return line;
+      }
+    };
+  }
+
+  public static SourcePosition createFromOffset(final PsiFile file, final int offset) {
+    return new SourcePositionCache(file) {
+
+      @Override
+      protected int calcOffset() {
+        return offset;
+      }
+    };
+  }
+     
+  public static SourcePosition createFromElement(PsiElement element) {
+    final PsiElement navigationElement = element.getNavigationElement();
+    final PsiFile psiFile;
+    if (JspPsiUtil.isInJspFile(navigationElement)) {
+      psiFile = JspPsiUtil.getJspFile(navigationElement);
+    }
+    else {
+      psiFile = navigationElement.getContainingFile();
+    }
+    return new SourcePositionCache(psiFile) {
+      @Override
+      protected PsiElement calcPsiElement() {
+        return navigationElement;
+      }
+
+      @Override
+      protected int calcOffset() {
+        return navigationElement.getTextOffset();
+      }
+    };
+  }
+
+  public boolean equals(Object o) {
+    if(o instanceof SourcePosition) {
+      SourcePosition sourcePosition = (SourcePosition)o;
+      return Comparing.equal(sourcePosition.getFile(), getFile()) && sourcePosition.getOffset() == getOffset();
+    }
+
+    return false;
+  }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java
new file mode 100644
index 0000000..bca8159
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.debugger.PositionManager;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
+import com.intellij.debugger.engine.managerThread.DebuggerManagerThread;
+import com.intellij.debugger.requests.RequestManager;
+import com.intellij.execution.ExecutionResult;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.sun.jdi.*;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author lex
+ */
+public interface DebugProcess {
+  @NonNls String JAVA_STRATUM = "Java";
+
+  <T> T    getUserData(Key<T> key);  
+  <T> void putUserData(Key<T> key, T value);
+
+  Project getProject();
+
+  RequestManager getRequestsManager();
+
+  PositionManager getPositionManager();
+
+  VirtualMachineProxy getVirtualMachineProxy();
+
+  void addDebugProcessListener(DebugProcessListener listener);
+
+  void removeDebugProcessListener(DebugProcessListener listener);
+
+  void appendPositionManager(PositionManager positionManager);
+
+  void waitFor();
+
+  void waitFor(long timeout);
+
+  void stop(boolean forceTerminate);
+
+  ExecutionResult getExecutionResult();
+
+  DebuggerManagerThread getManagerThread();
+
+  Value invokeMethod(EvaluationContext evaluationContext,
+                     ObjectReference objRef,
+                     Method method,
+                     List args) throws EvaluateException;
+
+  /**
+   * Is equivalent to invokeInstanceMethod(evaluationContext, classType, method, args, 0) 
+   */
+  Value invokeMethod(EvaluationContext evaluationContext,
+                     ClassType classType,
+                     Method method,
+                     List args) throws EvaluateException;
+
+  Value invokeInstanceMethod(EvaluationContext evaluationContext, 
+                             ObjectReference objRef, 
+                             Method method, 
+                             List args, 
+                             int invocationOptions) throws EvaluateException;
+
+  ReferenceType findClass(EvaluationContext evaluationContext,
+                          String name,
+                          ClassLoaderReference classLoader) throws EvaluateException;
+
+  ArrayReference newInstance(ArrayType arrayType,
+                             int dimension) throws EvaluateException;
+
+  ObjectReference newInstance(EvaluationContext evaluationContext,
+                              ClassType classType,
+                              Method constructor,
+                              List paramList) throws EvaluateException;
+
+  boolean isAttached();
+
+  boolean isDetached();
+
+  boolean isDetaching();
+
+  /**
+   * @return the search scope used by debugger to find sources corresponding to classes being executed
+   */
+  @NotNull
+  GlobalSearchScope getSearchScope();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcessAdapter.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcessAdapter.java
new file mode 100644
index 0000000..16c43c2
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcessAdapter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.RemoteConnection;
+import com.intellij.execution.configurations.RunProfileState;
+import com.sun.jdi.ThreadReference;
+
+public class DebugProcessAdapter implements DebugProcessListener{
+  //executed in manager thread
+  public void connectorIsReady() {
+  }
+
+  //executed in manager thread
+  public void paused(SuspendContext suspendContext) {
+
+  }
+
+  //executed in manager thread
+  public void resumed(SuspendContext suspendContext) {
+
+  }
+
+  //executed in manager thread
+  public void processDetached(DebugProcess process, boolean closedByUser) {
+
+  }
+
+  //executed in manager thread
+  public void processAttached(DebugProcess process) {
+
+  }
+
+  //executed in manager thread
+  public void threadStarted(DebugProcess proc, ThreadReference thread) {
+  }
+
+  //executed in manager thread
+  public void threadStopped(DebugProcess proc, ThreadReference thread) {
+  }
+
+  public void attachException(RunProfileState state, ExecutionException exception, RemoteConnection remoteConnection) {
+
+  }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcessListener.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcessListener.java
new file mode 100644
index 0000000..e992f25
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcessListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.RemoteConnection;
+import com.intellij.execution.configurations.RunProfileState;
+import com.sun.jdi.ThreadReference;
+
+import java.util.EventListener;
+
+
+public interface DebugProcessListener extends EventListener{
+  //executed in manager thread
+  void connectorIsReady();
+
+  //executed in manager thread
+  void paused(SuspendContext suspendContext);
+
+  //executed in manager thread
+  void resumed(SuspendContext suspendContext);
+
+  //executed in manager thread
+  void processDetached(DebugProcess process, boolean closedByUser);
+
+  //executed in manager thread
+  void processAttached(DebugProcess process);
+
+  void attachException(RunProfileState state, ExecutionException exception, RemoteConnection remoteConnection);
+  
+  void threadStarted(DebugProcess proc, ThreadReference thread);
+  
+  void threadStopped(DebugProcess proc, ThreadReference thread);
+}
+
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
new file mode 100644
index 0000000..418e442
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
@@ -0,0 +1,570 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.DebuggerContext;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.execution.ExecutionException;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.sun.jdi.*;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public abstract class DebuggerUtils {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebuggerUtils");
+  private static final Key<Method> TO_STRING_METHOD_KEY = new Key<Method>("CachedToStringMethod");
+  public static final Set<String> ourPrimitiveTypeNames = new HashSet<String>(Arrays.asList(
+      "byte", "short", "int", "long", "float", "double", "boolean", "char"
+  ));
+
+  public static void cleanupAfterProcessFinish(DebugProcess debugProcess) {
+    debugProcess.putUserData(TO_STRING_METHOD_KEY, null);
+  }
+
+  @NonNls
+  public static String getValueAsString(final EvaluationContext evaluationContext, Value value) throws EvaluateException {
+    try {
+      if (value == null) {
+        return "null";
+      }
+      if (value instanceof StringReference) {
+        return ((StringReference)value).value();
+      }
+      if (isInteger(value)) {
+        long v = ((PrimitiveValue)value).longValue();
+        return String.valueOf(v);
+      }
+      if (isNumeric(value)) {
+        double v = ((PrimitiveValue)value).doubleValue();
+        return String.valueOf(v);
+      }
+      if (value instanceof BooleanValue) {
+        boolean v = ((PrimitiveValue)value).booleanValue();
+        return String.valueOf(v);
+      }
+      if (value instanceof CharValue) {
+        char v = ((PrimitiveValue)value).charValue();
+        return String.valueOf(v);
+      }
+      if (value instanceof ObjectReference) {
+        if (value instanceof ArrayReference) {
+          final StringBuilder builder = new StringBuilder();
+          builder.append("[");
+          for (Iterator<Value> iterator = ((ArrayReference)value).getValues().iterator(); iterator.hasNext();) {
+            final Value element = iterator.next();
+            builder.append(getValueAsString(evaluationContext, element));
+            if (iterator.hasNext()) {
+              builder.append(",");
+            }
+          }
+          builder.append("]");
+          return builder.toString();
+        }
+
+        final ObjectReference objRef = (ObjectReference)value;
+        final DebugProcess debugProcess = evaluationContext.getDebugProcess();
+        Method toStringMethod = debugProcess.getUserData(TO_STRING_METHOD_KEY);
+        if (toStringMethod == null) {
+          try {
+            ReferenceType refType = objRef.virtualMachine().classesByName(CommonClassNames.JAVA_LANG_OBJECT).get(0);
+            toStringMethod = findMethod(refType, "toString", "()Ljava/lang/String;");
+            debugProcess.putUserData(TO_STRING_METHOD_KEY, toStringMethod);
+          }
+          catch (Exception e) {
+            throw EvaluateExceptionUtil.createEvaluateException(
+              DebuggerBundle.message("evaluation.error.cannot.evaluate.tostring", objRef.referenceType().name()));
+          }
+        }
+        if (toStringMethod == null) {
+          throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.cannot.evaluate.tostring", objRef.referenceType().name()));
+        }
+        final StringReference stringReference = (StringReference)debugProcess.invokeInstanceMethod(evaluationContext, objRef, toStringMethod, Collections.emptyList(), 0);
+        return  stringReference == null ? "null" : stringReference.value();
+      }
+      throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unsupported.expression.type"));
+    }
+    catch (ObjectCollectedException e) {
+      throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED;
+    }
+  }
+
+  public static final int MAX_DISPLAY_LABEL_LENGTH = 1024/*kb*/ *1024 /*bytes*/ / 2; // 1 Mb string
+
+  public static String convertToPresentationString(String str) {
+    if (str.length() > MAX_DISPLAY_LABEL_LENGTH) {
+      str = translateStringValue(str.substring(0, MAX_DISPLAY_LABEL_LENGTH));
+      StringBuilder buf = new StringBuilder();
+      buf.append(str);
+      if (!str.endsWith("...")) {
+        buf.append("...");
+      }
+      return buf.toString();
+    }
+    return translateStringValue(str);
+  }
+
+  @Nullable
+  public static Method findMethod(ReferenceType refType, @NonNls String methodName, @NonNls String methodSignature) {
+    if (refType instanceof ArrayType) {
+      // for array types methodByName() in JDI always returns empty list
+      final Method method = findMethod(refType.virtualMachine().classesByName(CommonClassNames.JAVA_LANG_OBJECT).get(0), methodName, methodSignature);
+      if (method != null) {
+        return method;
+      }
+    }
+
+    Method method = null;
+    if (methodSignature != null) {
+      if (refType instanceof ClassType) {
+        method = ((ClassType)refType).concreteMethodByName(methodName, methodSignature);
+      }
+      if (method == null) {
+        final List<Method> methods = refType.methodsByName(methodName, methodSignature);
+        if (methods.size() > 0) {
+          method = methods.get(0);
+        }
+      }
+    }
+    else {
+      List<Method> methods = null;
+      if (refType instanceof ClassType) {
+        methods = refType.methodsByName(methodName);
+      }
+      if (methods != null && methods.size() > 0) {
+        method = methods.get(0);
+      }
+    }
+    return method;
+  }
+
+  public static boolean isNumeric(Value value) {
+    return value != null &&
+           (isInteger(value) ||
+            value instanceof FloatValue ||
+            value instanceof DoubleValue
+           );
+  }
+
+  public static boolean isInteger(Value value) {
+    return value != null &&
+           (value instanceof ByteValue ||
+            value instanceof ShortValue ||
+            value instanceof LongValue ||
+            value instanceof IntegerValue
+           );
+  }
+
+  public static String translateStringValue(final String str) {
+    int length = str.length();
+    final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
+    try {
+      StringUtil.escapeStringCharacters(length, str, buffer);
+      if (str.length() > length) {
+        buffer.append("...");
+      }
+      return buffer.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(buffer);
+    }
+  }
+
+  protected static ArrayClass getArrayClass(String className) {
+    boolean searchBracket = false;
+    int dims = 0;
+    int pos;
+
+    for(pos = className.lastIndexOf(']'); pos >= 0; pos--){
+      char c = className.charAt(pos);
+
+      if (searchBracket) {
+        if (c == '[') {
+          dims++;
+          searchBracket = false;
+        }
+        else if (!Character.isWhitespace(c)) break;
+      }
+      else {
+        if (c == ']') {
+          searchBracket = true;
+        }
+        else if (!Character.isWhitespace(c)) break;
+      }
+    }
+
+    if (searchBracket) return null;
+
+    if(dims == 0) return null;
+
+    return new ArrayClass(className.substring(0, pos + 1), dims);
+  }
+
+  public static boolean instanceOf(String subType, String superType, Project project) {
+    if(project == null) {
+      return subType.equals(superType);
+    }
+
+    ArrayClass nodeClass = getArrayClass(subType);
+    ArrayClass rendererClass = getArrayClass(superType);
+    if (nodeClass == null || rendererClass == null) return false;
+
+    if (nodeClass.dims == rendererClass.dims) {
+      GlobalSearchScope scope = GlobalSearchScope.allScope(project);
+      PsiClass psiNodeClass = JavaPsiFacade.getInstance(project).findClass(nodeClass.className, scope);
+      PsiClass psiRendererClass = JavaPsiFacade.getInstance(project).findClass(rendererClass.className, scope);
+      return InheritanceUtil.isInheritorOrSelf(psiNodeClass, psiRendererClass, true);
+    }
+    else if (nodeClass.dims > rendererClass.dims) {
+      return rendererClass.className.equals(CommonClassNames.JAVA_LANG_OBJECT);
+    }
+    return false;
+  }
+
+  public static Type getSuperType(Type subType, String superType) {
+    if(CommonClassNames.JAVA_LANG_OBJECT.equals(superType)) {
+      List list = subType.virtualMachine().classesByName(CommonClassNames.JAVA_LANG_OBJECT);
+      if(list.size() > 0) {
+        return (ReferenceType)list.get(0);
+      }
+      return null;
+    }
+
+    return getSuperTypeInt(subType, superType);
+  }
+
+  private static Type getSuperTypeInt(Type subType, String superType) {
+    Type result;
+    if (subType == null) {
+      return null;
+    }
+
+    if (subType.name().equals(superType)) {
+      return subType;
+    }
+
+    if (subType instanceof ClassType) {
+      result = getSuperType(((ClassType)subType).superclass(), superType);
+      if (result != null) {
+        return result;
+      }
+
+      List ifaces = ((ClassType)subType).allInterfaces();
+      for (Iterator iterator = ifaces.iterator(); iterator.hasNext();) {
+        InterfaceType interfaceType = (InterfaceType)iterator.next();
+        if (interfaceType.name().equals(superType)) {
+          return interfaceType;
+        }
+      }
+      return null;
+    }
+
+    if (subType instanceof InterfaceType) {
+      List ifaces = ((InterfaceType)subType).superinterfaces();
+      for (Iterator iterator = ifaces.iterator(); iterator.hasNext();) {
+        InterfaceType interfaceType = (InterfaceType)iterator.next();
+        result = getSuperType(interfaceType, superType);
+        if (result != null) {
+          return result;
+        }
+      }
+    }
+    else if (subType instanceof ArrayType) {
+      if (superType.endsWith("[]")) {
+        try {
+          String superTypeItem = superType.substring(0, superType.length() - 2);
+          Type subTypeItem = ((ArrayType)subType).componentType();
+          return instanceOf(subTypeItem, superTypeItem) ? subType : null;
+        }
+        catch (ClassNotLoadedException e) {
+          LOG.debug(e);
+        }
+      }
+    }
+    else if (subType instanceof PrimitiveType) {
+      //noinspection HardCodedStringLiteral
+      if(superType.equals("java.lang.Primitive")) {
+        return subType;
+      }
+    }
+
+    //only for interfaces and arrays
+    if(CommonClassNames.JAVA_LANG_OBJECT.equals(superType)) {
+      List list = subType.virtualMachine().classesByName(CommonClassNames.JAVA_LANG_OBJECT);
+      if(list.size() > 0) {
+        return (ReferenceType)list.get(0);
+      }
+    }
+    return null;
+  }
+
+  public static boolean instanceOf(Type subType, String superType) {
+    return getSuperType(subType, superType) != null;
+  }
+
+  @Nullable
+  public static PsiClass findClass(final String className, Project project, final GlobalSearchScope scope) {
+    ApplicationManager.getApplication().assertReadAccessAllowed();
+    final PsiManager psiManager = PsiManager.getInstance(project);
+    final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(psiManager.getProject());
+    if (getArrayClass(className) != null) {
+      return javaPsiFacade.getElementFactory().getArrayClass(LanguageLevelProjectExtension.getInstance(psiManager.getProject()).getLanguageLevel());
+    }
+    if(project.isDefault()) {
+      return null;
+    }
+    final String _className = className.replace('$', '.');
+    PsiClass aClass = javaPsiFacade.findClass(_className, scope);
+    if (aClass == null) {
+      if (!_className.equals(className)) {
+        // try original name if it differs from the normalized name
+        aClass = javaPsiFacade.findClass(className, scope);
+      }
+    }
+    if (aClass == null) {
+      final GlobalSearchScope globalScope = GlobalSearchScope.allScope(project);
+      if (!globalScope.equals(scope)) {
+        aClass = javaPsiFacade.findClass(_className, globalScope);
+        if (aClass == null) {
+          if (!_className.equals(className)) {
+            // try original name with global scope if the original differs from the normalized name
+            aClass = javaPsiFacade.findClass(className, globalScope);
+          }
+        }
+      }
+    }
+    return aClass;
+  }
+
+  public static PsiType getType(String className, Project project) {
+    ApplicationManager.getApplication().assertReadAccessAllowed();
+
+    final PsiManager psiManager = PsiManager.getInstance(project);
+    try {
+      if (getArrayClass(className) != null) {
+        return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createTypeFromText(className, null);
+      }
+      if(project.isDefault()) {
+        return null;
+      }
+      final PsiClass aClass =
+        JavaPsiFacade.getInstance(psiManager.getProject()).findClass(className.replace('$', '.'), GlobalSearchScope.allScope(project));
+      return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createType(aClass);
+    }
+    catch (IncorrectOperationException e) {
+      LOG.error(e);
+    }
+    return null;
+  }
+
+  public static void checkSyntax(PsiCodeFragment codeFragment) throws EvaluateException {
+    PsiElement[] children = codeFragment.getChildren();
+
+    if(children.length == 0) throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.empty.code.fragment"));
+    for (int i = 0; i < children.length; i++) {
+      PsiElement child = children[i];
+      if(child instanceof PsiErrorElement) {
+        throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", child.getText()));
+      }
+    }
+  }
+
+  public static boolean hasSideEffects(PsiElement element) {
+    return hasSideEffectsOrReferencesMissingVars(element, null);
+  }
+  
+  public static boolean hasSideEffectsOrReferencesMissingVars(PsiElement element, @Nullable final Set<String> visibleLocalVariables) {
+    final Ref<Boolean> rv = new Ref<Boolean>(Boolean.FALSE);
+    element.accept(new JavaRecursiveElementWalkingVisitor() {
+      @Override 
+      public void visitPostfixExpression(final PsiPostfixExpression expression) {
+        rv.set(Boolean.TRUE);
+      }
+
+      @Override 
+      public void visitReferenceExpression(final PsiReferenceExpression expression) {
+        final PsiElement psiElement = expression.resolve();
+        if (psiElement instanceof PsiLocalVariable) {
+          if (visibleLocalVariables != null) {
+            if (!visibleLocalVariables.contains(((PsiLocalVariable)psiElement).getName())) {
+              rv.set(Boolean.TRUE);
+            }
+          }
+        }
+        else if (psiElement instanceof PsiMethod) {
+          rv.set(Boolean.TRUE);
+          //final PsiMethod method = (PsiMethod)psiElement;
+          //if (!isSimpleGetter(method)) {
+          //  rv.set(Boolean.TRUE);
+          //}
+        }
+        if (!rv.get().booleanValue()) {
+          super.visitReferenceExpression(expression);
+        }
+      }
+
+      @Override 
+      public void visitPrefixExpression(final PsiPrefixExpression expression) {
+        final IElementType op = expression.getOperationTokenType();
+        if (JavaTokenType.PLUSPLUS.equals(op) || JavaTokenType.MINUSMINUS.equals(op)) {
+          rv.set(Boolean.TRUE);
+        }
+        else {
+          super.visitPrefixExpression(expression);
+        }
+      }
+
+      @Override 
+      public void visitAssignmentExpression(final PsiAssignmentExpression expression) {
+        rv.set(Boolean.TRUE);
+      }
+
+      @Override 
+      public void visitCallExpression(final PsiCallExpression callExpression) {
+        rv.set(Boolean.TRUE);
+        //final PsiMethod method = callExpression.resolveMethod();
+        //if (method == null || !isSimpleGetter(method)) {
+        //  rv.set(Boolean.TRUE);
+        //}
+        //else {
+        //  super.visitCallExpression(callExpression);
+        //}
+      }
+    });
+    return rv.get().booleanValue();
+  }
+
+  public abstract String findAvailableDebugAddress(boolean useSockets) throws ExecutionException;
+
+  public static boolean isSynthetic(TypeComponent typeComponent) {
+    if (typeComponent == null) {
+      return false;
+    }
+    VirtualMachine machine = typeComponent.virtualMachine();
+    return machine != null && machine.canGetSyntheticAttribute() && typeComponent.isSynthetic();
+  }
+
+  public static boolean isSimpleGetter(PsiMethod method){
+    final PsiCodeBlock body = method.getBody();
+    if(body == null){
+      return false;
+    }
+
+    final PsiStatement[] statements = body.getStatements();
+    if(statements.length != 1){
+      return false;
+    }
+    
+    final PsiStatement statement = statements[0];
+    if(!(statement instanceof PsiReturnStatement)){
+      return false;
+    }
+    
+    final PsiExpression value = ((PsiReturnStatement)statement).getReturnValue();
+    if(!(value instanceof PsiReferenceExpression)){
+      return false;
+    }
+    
+    final PsiReferenceExpression reference = (PsiReferenceExpression)value;
+    final PsiExpression qualifier = reference.getQualifierExpression();
+    //noinspection HardCodedStringLiteral
+    if(qualifier != null && !"this".equals(qualifier.getText())) {
+      return false;
+    }
+    
+    final PsiElement referent = reference.resolve();
+    if(referent == null) {
+      return false;
+    }
+    
+    if(!(referent instanceof PsiField)) {
+      return false;
+    }
+    
+    return ((PsiField)referent).getContainingClass().equals(method.getContainingClass());
+  }
+
+  public static boolean isPrimitiveType(final String typeName) {
+    return ourPrimitiveTypeNames.contains(typeName);
+  }
+
+  protected static class ArrayClass {
+    public String className;
+    public int dims;
+
+    public ArrayClass(String className, int dims) {
+      this.className = className;
+      this.dims = dims;
+    }
+  }
+
+  public static DebuggerUtils getInstance() {
+    return ServiceManager.getService(DebuggerUtils.class);
+  }
+
+  public abstract PsiExpression substituteThis(PsiExpression expressionWithThis, PsiExpression howToEvaluateThis, Value howToEvaluateThisValue, StackFrameContext context) throws EvaluateException;
+
+  public abstract DebuggerContext getDebuggerContext (DataContext context);
+
+  public abstract Element writeTextWithImports(TextWithImports text);
+  public abstract TextWithImports readTextWithImports (Element element);
+
+  public abstract void writeTextWithImports(Element root, @NonNls String name, TextWithImports value);
+  public abstract TextWithImports readTextWithImports (Element root, @NonNls String name);
+
+  public abstract TextWithImports createExpressionWithImports(@NonNls String expression);
+
+  public abstract PsiElement getContextElement(final StackFrameContext context);
+
+  public abstract PsiClass chooseClassDialog(String title, Project project);
+
+  public static boolean supportsJVMDebugging(FileType type) {
+    return type instanceof LanguageFileType && ((LanguageFileType)type).isJVMDebuggingSupported();
+  }
+
+  public static boolean supportsJVMDebugging(PsiFile file) {
+    final JVMDebugProvider[] providers = Extensions.getExtensions(JVMDebugProvider.EP_NAME);
+    for (JVMDebugProvider provider : providers) {
+      if (provider.supportsJVMDebugging(file)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java
new file mode 100644
index 0000000..1697684
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.NoDataException;
+import com.intellij.debugger.PositionManager;
+import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.requests.ClassPrepareRequestor;
+import com.intellij.execution.process.ProcessOutputTypes;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.PsiFile;
+import com.sun.jdi.*;
+import com.sun.jdi.request.ClassPrepareRequest;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: May 23, 2006
+ */
+public abstract class JSR45PositionManager<Scope> implements PositionManager {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.JSR45PositionManager");
+  protected final DebugProcess      myDebugProcess;
+  protected final Scope myScope;
+  private final String myStratumId;
+  protected final SourcesFinder<Scope> mySourcesFinder;
+  protected final String GENERATED_CLASS_PATTERN;
+  protected Matcher myGeneratedClassPatternMatcher;
+  private final Set<LanguageFileType> myFileTypes;
+
+  public JSR45PositionManager(DebugProcess debugProcess, Scope scope, final String stratumId, final LanguageFileType[] acceptedFileTypes,
+                              final SourcesFinder<Scope> sourcesFinder) {
+    myDebugProcess = debugProcess;
+    myScope = scope;
+    myStratumId = stratumId;
+    myFileTypes = Collections.unmodifiableSet(new HashSet<LanguageFileType>(Arrays.asList(acceptedFileTypes)));
+    mySourcesFinder = sourcesFinder;
+    String generatedClassPattern = getGeneratedClassesPackage();
+    if(generatedClassPattern.length() == 0) {
+      generatedClassPattern = getGeneratedClassesNamePattern();
+    }
+    else {
+      generatedClassPattern = generatedClassPattern + "." + getGeneratedClassesNamePattern();
+    }
+    GENERATED_CLASS_PATTERN = generatedClassPattern;
+    myGeneratedClassPatternMatcher = Pattern.compile(generatedClassPattern.replaceAll("\\*", ".*")).matcher("");
+  }
+
+  @NonNls
+  protected abstract String getGeneratedClassesPackage();
+
+  protected String getGeneratedClassesNamePattern() {
+    return "*";
+  }
+
+  public final String getStratumId() {
+    return myStratumId;
+  }
+
+  public SourcePosition getSourcePosition(final Location location) throws NoDataException {
+    SourcePosition sourcePosition = null;
+
+    try {
+      String sourcePath = getRelativeSourcePathByLocation(location);
+      PsiFile file = mySourcesFinder.findSourceFile(sourcePath, myDebugProcess.getProject(), myScope);
+      if(file != null) {
+        int lineNumber = getLineNumber(location);
+        sourcePosition = SourcePosition.createFromLine(file, lineNumber - 1);
+      }
+    }
+    catch (AbsentInformationException ignored) { // ignored
+    }
+    catch (Throwable e) {
+      LOG.info(e);
+    }
+    if(sourcePosition == null) {
+      throw new NoDataException();
+    }
+    return sourcePosition;
+  }
+
+  protected String getRelativeSourcePathByLocation(final Location location) throws AbsentInformationException {
+    return getRelativePath(location.sourcePath(myStratumId));
+  }
+
+  protected int getLineNumber(final Location location) {
+    return location.lineNumber(myStratumId);
+  }
+
+  @NotNull
+  public List<ReferenceType> getAllClasses(SourcePosition classPosition) throws NoDataException {
+    checkSourcePositionFileType(classPosition);
+
+    final List<ReferenceType> referenceTypes = myDebugProcess.getVirtualMachineProxy().allClasses();
+
+    final List<ReferenceType> result = new ArrayList<ReferenceType>();
+
+    for (final ReferenceType referenceType : referenceTypes) {
+      myGeneratedClassPatternMatcher.reset(referenceType.name());
+      if (myGeneratedClassPatternMatcher.matches()) {
+        final List<Location> locations = locationsOfClassAt(referenceType, classPosition);
+        if (locations != null && locations.size() > 0) {
+          result.add(referenceType);
+        }
+      }
+    }
+
+    return result;
+  }
+
+  private void checkSourcePositionFileType(final SourcePosition classPosition) throws NoDataException {
+    final FileType fileType = classPosition.getFile().getFileType();
+    if(!myFileTypes.contains(fileType)) {
+      throw new NoDataException();
+    }
+  }
+
+  @NotNull
+  public List<Location> locationsOfLine(final ReferenceType type, final SourcePosition position) throws NoDataException {
+    List<Location> locations = locationsOfClassAt(type, position);
+    return locations != null ? locations : Collections.<Location>emptyList();
+
+  }
+
+  private List<Location> locationsOfClassAt(final ReferenceType type, final SourcePosition position) throws NoDataException {
+    checkSourcePositionFileType(position);
+
+    return ApplicationManager.getApplication().runReadAction(new Computable<List<Location>>() {
+      public List<Location> compute() {
+        try {
+          final List<String> relativePaths = getRelativeSourePathsByType(type);
+          for (String relativePath : relativePaths) {
+            final PsiFile file = mySourcesFinder.findSourceFile(relativePath, myDebugProcess.getProject(), myScope);
+            if(file != null && file.equals(position.getFile())) {
+              return getLocationsOfLine(type, getSourceName(file.getName(), type), relativePath, position.getLine() + 1);
+            }
+          }
+        }
+        catch(ObjectCollectedException ignored) {
+        }
+        catch(AbsentInformationException ignored) {
+        }
+        catch(ClassNotPreparedException ignored) {                                                                                                           
+        }
+        catch (InternalError e) {
+          myDebugProcess.getExecutionResult().getProcessHandler().notifyTextAvailable(
+            DebuggerBundle.message("internal.error.locations.of.line", type.name()), ProcessOutputTypes.SYSTEM);
+        }
+        return null;
+      }
+
+      // Finds exact server file name (from available in type)
+      // This is needed because some servers (e.g. WebSphere) put not exact file name such as 'A.jsp  '
+      private String getSourceName(final String name, final ReferenceType type) throws AbsentInformationException {
+        for(String sourceNameFromType: type.sourceNames(myStratumId)) {
+          if (sourceNameFromType.indexOf(name) >= 0) {
+            return sourceNameFromType;
+          }
+        }
+        return name;
+      }
+    });
+  }
+
+  protected List<String> getRelativeSourePathsByType(final ReferenceType type) throws AbsentInformationException {
+    final List<String> paths = type.sourcePaths(myStratumId);
+    final ArrayList<String> relativePaths = new ArrayList<String>();
+    for (String path : paths) {
+      relativePaths.add(getRelativePath(path));
+    }
+    return relativePaths;
+  }
+
+  protected List<Location> getLocationsOfLine(final ReferenceType type, final String fileName,
+                                              final String relativePath, final int lineNumber) throws AbsentInformationException {
+    return type.locationsOfLine(myStratumId, fileName, lineNumber);
+  }
+
+  public ClassPrepareRequest createPrepareRequest(final ClassPrepareRequestor requestor, final SourcePosition position)
+    throws NoDataException {
+    checkSourcePositionFileType(position);
+
+    return myDebugProcess.getRequestsManager().createClassPrepareRequest(new ClassPrepareRequestor() {
+      public void processClassPrepare(DebugProcess debuggerProcess, ReferenceType referenceType) {
+        onClassPrepare(debuggerProcess, referenceType, position, requestor);
+      }
+    }, GENERATED_CLASS_PATTERN);
+  }
+
+  protected void onClassPrepare(final DebugProcess debuggerProcess, final ReferenceType referenceType,
+                              final SourcePosition position, final ClassPrepareRequestor requestor) {
+    try {
+      if(locationsOfClassAt(referenceType, position) != null) {
+        requestor.processClassPrepare(debuggerProcess, referenceType);
+      }
+    }
+    catch (NoDataException e) {
+    }
+  }
+
+  protected String getRelativePath(String sourcePath) {
+
+    if (sourcePath != null) {
+      sourcePath = sourcePath.trim();
+      String generatedClassesPackage = getGeneratedClassesPackage();
+      final String prefix = generatedClassesPackage.replace('.', File.separatorChar);
+
+      if (sourcePath.startsWith(prefix)) {
+        sourcePath = sourcePath.substring(prefix.length());
+        if (sourcePath.startsWith(File.separator)) {
+          sourcePath = sourcePath.substring(1);
+        }
+      }
+    }
+
+    return sourcePath;
+  }
+
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/JVMDebugProvider.java b/java/debugger/openapi/src/com/intellij/debugger/engine/JVMDebugProvider.java
new file mode 100644
index 0000000..15fde83
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/JVMDebugProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiFile;
+
+/**
+ * @author Dennis.Ushakov
+ */
+public interface JVMDebugProvider {
+  ExtensionPointName<JVMDebugProvider> EP_NAME = ExtensionPointName.create("com.intellij.debugger.jvmDebugProvider");
+
+  boolean supportsJVMDebugging(PsiFile file);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/SourcesFinder.java b/java/debugger/openapi/src/com/intellij/debugger/engine/SourcesFinder.java
new file mode 100644
index 0000000..106499b
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/SourcesFinder.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: May 23, 2006
+ */
+public interface SourcesFinder<Scope> {
+  /**
+   * Searches for source file within the deployedModules
+   * @param relPath relative path of the source to be found (fetched from the class file)
+   * @param project
+   * @param scope a search scope
+   */
+  @Nullable
+  PsiFile findSourceFile(String relPath, Project project, Scope scope);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/StackFrameContext.java b/java/debugger/openapi/src/com/intellij/debugger/engine/StackFrameContext.java
new file mode 100644
index 0000000..442f2c7
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/StackFrameContext.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.debugger.engine.jdi.StackFrameProxy;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: lex
+ * Date: Jun 3, 2003
+ * Time: 5:58:58 PM
+ * To change this template use Options | File Templates.
+ */
+public interface StackFrameContext {
+  @Nullable
+  StackFrameProxy  getFrameProxy();
+  DebugProcess     getDebugProcess();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/SuspendContext.java b/java/debugger/openapi/src/com/intellij/debugger/engine/SuspendContext.java
new file mode 100644
index 0000000..ae89344
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/SuspendContext.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.debugger.engine.jdi.ThreadReferenceProxy;
+
+public interface SuspendContext extends StackFrameContext {
+  public int getSuspendPolicy();
+
+  ThreadReferenceProxy getThread();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/TopLevelParentClassProvider.java b/java/debugger/openapi/src/com/intellij/debugger/engine/TopLevelParentClassProvider.java
new file mode 100644
index 0000000..782bf34
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/TopLevelParentClassProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Max Medvedev
+ */
+public abstract class TopLevelParentClassProvider {
+  private static final ExtensionPointName<TopLevelParentClassProvider> EP_NAME =
+    ExtensionPointName.create("com.intellij.topLevelClassProvider");
+
+  public static PsiClass getTopLevelParentClass(PsiClass psiClass) {
+    for (TopLevelParentClassProvider provider : EP_NAME.getExtensions()) {
+      final PsiClass custom = provider.getCustomTopLevelParentClass(psiClass);
+      if (custom != null) return custom;
+    }
+
+    PsiClass enclosing = PsiTreeUtil.getParentOfType(psiClass, PsiClass.class, true);
+    while (enclosing != null) {
+      psiClass = enclosing;
+      enclosing = PsiTreeUtil.getParentOfType(enclosing, PsiClass.class, true);
+    }
+    return psiClass;
+  }
+
+  @Nullable
+  protected abstract PsiClass getCustomTopLevelParentClass(PsiClass psiClass);
+
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactory.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactory.java
new file mode 100644
index 0000000..f7ceafc
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation;
+
+import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaCodeFragment;
+import com.intellij.psi.PsiElement;
+
+public abstract class CodeFragmentFactory {
+  public static final ExtensionPointName<CodeFragmentFactory> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.debugger.codeFragmentFactory");
+
+  public abstract JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project);
+
+  public abstract JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project);
+
+  public abstract boolean isContextAccepted(PsiElement contextElement);
+
+  public abstract LanguageFileType getFileType();
+
+  /**
+   * In case if createCodeFragment returns java code use
+   * com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl#getInstance()
+   * @return builder, which can evaluate expression for your code fragment
+   */
+  public abstract EvaluatorBuilder getEvaluatorBuilder();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/CodeFragmentKind.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/CodeFragmentKind.java
new file mode 100644
index 0000000..34766d2
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/CodeFragmentKind.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation;
+public enum CodeFragmentKind {
+  EXPRESSION, CODE_BLOCK
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateException.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateException.java
new file mode 100644
index 0000000..30dac08
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import org.jetbrains.annotations.Nullable;
+
+public class EvaluateException extends Exception {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.EvaluateException");
+  private ObjectReference myTargetException;
+
+  public EvaluateException(final String message) {
+    super(message);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(message);
+    }
+  }
+
+  public EvaluateException(String msg, Throwable th) {
+    super(msg, th);
+    if (th instanceof EvaluateException) {
+      myTargetException = ((EvaluateException)th).getExceptionFromTargetVM();
+    }
+    else if(th instanceof InvocationException){
+      InvocationException invocationException = (InvocationException) th;
+      myTargetException = invocationException.exception();
+    }
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(msg);
+    }
+  }
+  
+  @Nullable
+  public ObjectReference getExceptionFromTargetVM() {
+    return myTargetException;
+  }
+
+  public void setTargetException(final ObjectReference targetException) {
+    myTargetException = targetException;
+  }
+
+  public String getMessage() {
+    final String errorMessage = super.getMessage();
+    if (errorMessage != null) {
+      return errorMessage;
+    }
+    final Throwable cause = getCause();
+    final String causeMessage = cause != null? cause.getMessage() : null;
+    if (causeMessage != null) {
+      return causeMessage;
+    }
+    return "unknown error";
+  }
+}
\ No newline at end of file
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java
new file mode 100644
index 0000000..4d5536c
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.sun.jdi.*;
+
+/**
+ * @author lex
+ */
+public class EvaluateExceptionUtil {
+  public static final EvaluateException INCONSISTEND_DEBUG_INFO = createEvaluateException(DebuggerBundle.message("evaluation.error.inconsistent.debug.info"));
+  public static final EvaluateException BOOLEAN_EXPECTED = createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.value.expected.in.condition"));
+  public static final EvaluateException PROCESS_EXITED = createEvaluateException(DebuggerBundle.message("evaluation.error.process.exited"));
+  public static final EvaluateException NULL_STACK_FRAME = createEvaluateException(DebuggerBundle.message("evaluation.error.stack.frame.unavailable"));
+  public static final EvaluateException NESTED_EVALUATION_ERROR = createEvaluateException(DebuggerBundle.message("evaluation.error.nested.evaluation"));
+  public static final EvaluateException INVALID_DEBUG_INFO = createEvaluateException(DebuggerBundle.message("evaluation.error.sources.out.of.sync"));
+  public static final EvaluateException CANNOT_FIND_SOURCE_CLASS = createEvaluateException(DebuggerBundle.message("evaluation.error.cannot.find.stackframe.source"));
+  public static final EvaluateException OBJECT_WAS_COLLECTED = createEvaluateException(DebuggerBundle.message("evaluation.error.object.collected"));
+  public static final EvaluateException ARRAY_WAS_COLLECTED = createEvaluateException(DebuggerBundle.message("evaluation.error.array.collected"));
+  public static final EvaluateException THREAD_WAS_RESUMED = createEvaluateException(DebuggerBundle.message("evaluation.error.thread.resumed"));
+  public static final EvaluateException DEBUG_INFO_UNAVAILABLE = createEvaluateException(DebuggerBundle.message("evaluation.error.debug.info.unavailable"));
+
+  private EvaluateExceptionUtil() {
+  }
+
+  public static EvaluateException createEvaluateException(Throwable th) {
+    return createEvaluateException(null, th);
+  }
+
+  public static EvaluateException createEvaluateException(String msg, Throwable th) {
+    final String message = msg != null? msg + ": " + reason(th) : reason(th);
+    return new EvaluateException(message, th instanceof EvaluateException ? th.getCause() : th);
+  }
+
+  public static EvaluateException createEvaluateException(String reason) {
+    return new EvaluateException(reason, null);
+  }
+
+  private static String reason(Throwable th) {
+    if(th instanceof InvalidTypeException) {
+      final String originalReason = th.getMessage();
+      return DebuggerBundle.message("evaluation.error.type.mismatch") + (originalReason != null? " " + originalReason : "");
+    }
+    else if(th instanceof AbsentInformationException) {
+      return DebuggerBundle.message("evaluation.error.debug.info.unavailable");
+    }
+    else if(th instanceof ClassNotLoadedException) {
+      return DebuggerBundle.message("evaluation.error.class.not.loaded", ((ClassNotLoadedException)th).className());
+    }
+    else if(th instanceof ClassNotPreparedException) {
+      return th.getMessage();
+    }
+    else if(th instanceof IncompatibleThreadStateException) {
+      return DebuggerBundle.message("evaluation.error.thread.not.at.breakpoint");
+    }
+    else if(th instanceof InconsistentDebugInfoException) {
+      return DebuggerBundle.message("evaluation.error.inconsistent.debug.info");
+    }
+    else if(th instanceof ObjectCollectedException) {
+      return DebuggerBundle.message("evaluation.error.object.collected");
+    }
+    else if(th instanceof InvocationException){
+      InvocationException invocationException = (InvocationException) th;
+      return DebuggerBundle.message("evaluation.error.method.exception", invocationException.exception().referenceType().name());
+    }
+    else if(th instanceof EvaluateException) {
+      return th.getMessage();
+    }
+    else {
+      return th.getClass().getName() + " : " + (th.getMessage() != null ? th.getMessage() : "");
+    }
+  }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java
new file mode 100644
index 0000000..e50ef43
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.intellij.debugger.engine.StackFrameContext;
+import com.intellij.debugger.engine.SuspendContext;
+import com.intellij.openapi.project.Project;
+import com.sun.jdi.ClassLoaderReference;
+import com.sun.jdi.Value;
+
+public interface EvaluationContext extends StackFrameContext{
+  DebugProcess getDebugProcess();
+
+  EvaluationContext createEvaluationContext(Value value);
+
+  SuspendContext getSuspendContext();
+
+  Project getProject();
+
+  ClassLoaderReference getClassLoader() throws EvaluateException;
+
+  Value getThisObject();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/TextWithImports.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/TextWithImports.java
new file mode 100644
index 0000000..0ae3e64
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/TextWithImports.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation;
+
+import com.intellij.openapi.fileTypes.FileType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface TextWithImports {
+  String getText();
+
+  void setText(String newText);
+
+  @NotNull
+  String getImports();
+
+  CodeFragmentKind getKind();
+
+  boolean isEmpty();
+
+  String toExternalForm();
+
+  @Nullable
+  FileType getFileType();
+
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilder.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilder.java
new file mode 100644
index 0000000..66bb45a
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation.expression;
+
+import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.psi.PsiElement;
+
+/**
+ * Main interface to extend evaluation for different JVM languages.
+ * @see com.intellij.debugger.engine.evaluation.CodeFragmentFactory
+ */
+public interface EvaluatorBuilder {
+  ExpressionEvaluator build(PsiElement codeFragment, final SourcePosition position) throws EvaluateException;
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluator.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluator.java
new file mode 100644
index 0000000..18528c2
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation.expression;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.sun.jdi.Value;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: lex
+ * Date: Jul 15, 2003
+ * Time: 1:44:35 PM
+ * To change this template use Options | File Templates.
+ */
+public interface ExpressionEvaluator {
+  //call evaluate before
+  public Value getValue();
+
+  //call evaluate before
+  public Modifier getModifier();
+
+  public Value evaluate(final EvaluationContext context) throws EvaluateException;
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/Modifier.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/Modifier.java
new file mode 100644
index 0000000..809feac
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/expression/Modifier.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Interface Modifier
+ * @author Jeka
+ */
+package com.intellij.debugger.engine.evaluation.expression;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.ui.tree.NodeDescriptor;
+import com.intellij.openapi.project.Project;
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.Type;
+import com.sun.jdi.Value;
+
+public interface Modifier {
+  boolean canInspect();
+
+  boolean canSetValue();
+  /**
+   * sets the value to the expression
+   */
+  void setValue(Value value) throws ClassNotLoadedException, InvalidTypeException, EvaluateException;
+
+  /**
+   * @return the expected type of the expression or null is class was not loaded
+   */
+  Type getExpectedType() throws ClassNotLoadedException, EvaluateException;
+
+  NodeDescriptor getInspectItem(Project project);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/LocalVariableProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/LocalVariableProxy.java
new file mode 100644
index 0000000..8efdaae
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/LocalVariableProxy.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.jdi;
+
+public interface LocalVariableProxy extends ObjectReferenceProxy{
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ObjectReferenceProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ObjectReferenceProxy.java
new file mode 100644
index 0000000..3ec95fb
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ObjectReferenceProxy.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.jdi;
+
+public interface ObjectReferenceProxy {
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java
new file mode 100644
index 0000000..7e0b6ee
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.jdi;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.sun.jdi.ClassLoaderReference;
+import com.sun.jdi.Location;
+import com.sun.jdi.StackFrame;
+
+public interface StackFrameProxy extends ObjectReferenceProxy{
+  StackFrame getStackFrame() throws EvaluateException;
+
+  int getFrameIndex() throws EvaluateException ;
+
+  VirtualMachineProxy getVirtualMachine();
+
+  Location location() throws EvaluateException;
+
+  ClassLoaderReference getClassLoader() throws EvaluateException;
+
+  LocalVariableProxy visibleVariableByName(String name) throws EvaluateException;
+
+  ThreadReferenceProxy threadProxy();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ThreadGroupReferenceProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ThreadGroupReferenceProxy.java
new file mode 100644
index 0000000..146ab75
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ThreadGroupReferenceProxy.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.jdi;
+
+import com.sun.jdi.ThreadGroupReference;
+
+public interface ThreadGroupReferenceProxy extends ObjectReferenceProxy{
+  ThreadGroupReference getThreadGroupReference();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ThreadReferenceProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ThreadReferenceProxy.java
new file mode 100644
index 0000000..9723516
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/ThreadReferenceProxy.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.jdi;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.sun.jdi.ThreadReference;
+
+public interface ThreadReferenceProxy extends ObjectReferenceProxy{
+  VirtualMachineProxy getVirtualMachine();
+  ThreadReference     getThreadReference();
+
+  StackFrameProxy frame(int i) throws EvaluateException;
+
+  int frameCount() throws EvaluateException;
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java
new file mode 100644
index 0000000..4f4cb82
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.jdi;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.sun.jdi.ReferenceType;
+
+import java.util.List;
+
+/**
+ * @author lex
+ */
+public interface VirtualMachineProxy {
+  List<ReferenceType> allClasses();
+
+  boolean versionHigher(String version);
+
+  boolean canWatchFieldModification();
+
+  boolean canWatchFieldAccess();
+
+  boolean canInvokeMethods();
+
+  DebugProcess getDebugProcess();
+
+  List<ReferenceType> nestedTypes(ReferenceType refType);
+
+  List<ReferenceType> classesByName(String s);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/DebuggerCommand.java b/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/DebuggerCommand.java
new file mode 100644
index 0000000..a39d83f
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/DebuggerCommand.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.managerThread;
+
+public interface DebuggerCommand {
+  void action();
+
+  void commandCancelled();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/DebuggerManagerThread.java b/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/DebuggerManagerThread.java
new file mode 100644
index 0000000..8d19667
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/DebuggerManagerThread.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.managerThread;
+
+public interface DebuggerManagerThread {
+  /**
+   * executes command in DebuggerManagerThread
+   *
+   * @param command
+   */
+  void invokeCommand(DebuggerCommand command);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/SuspendContextCommand.java b/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/SuspendContextCommand.java
new file mode 100644
index 0000000..13d75fe
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/managerThread/SuspendContextCommand.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.managerThread;
+
+import com.intellij.debugger.engine.SuspendContext;
+
+public interface SuspendContextCommand extends DebuggerCommand{
+  SuspendContext getSuspendContext();
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/package.html b/java/debugger/openapi/src/com/intellij/debugger/package.html
new file mode 100644
index 0000000..e9fa628
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/package.html
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for interacting with IDEA's debugger. The main extensibility
+point of the debugger is the possibility for a plugin to provide custom mapping of
+positions in compiled classes to source code lines, which is mostly necessary for
+JSP debugging. Such mapping is provided through the {@link PositionManager} interface.
+One standard implementation of this interface for application servers compatible
+with the JSR-45 specification is provided by the {@link JSR45PositionManager} class.
+Another implementation of this interface, which can be used as an example for the debugger
+API, is found in the Tomcat plugin.
+</body></html>
diff --git a/java/debugger/openapi/src/com/intellij/debugger/requests/ClassPrepareRequestor.java b/java/debugger/openapi/src/com/intellij/debugger/requests/ClassPrepareRequestor.java
new file mode 100644
index 0000000..e58e052
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/requests/ClassPrepareRequestor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.requests;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.sun.jdi.ReferenceType;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: lex
+ * Date: Jun 27, 2003
+ * Time: 7:27:41 PM
+ * To change this template use Options | File Templates.
+ */
+public interface ClassPrepareRequestor extends Requestor {
+  void processClassPrepare(DebugProcess debuggerProcess, final ReferenceType referenceType);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/requests/RequestManager.java b/java/debugger/openapi/src/com/intellij/debugger/requests/RequestManager.java
new file mode 100644
index 0000000..bd949fd
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/requests/RequestManager.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.requests;
+
+import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.sun.jdi.request.ClassPrepareRequest;
+import com.sun.jdi.request.EventRequest;
+
+public interface RequestManager {
+  void callbackOnPrepareClasses(ClassPrepareRequestor requestor, String classOrPatternToBeLoaded);
+  void callbackOnPrepareClasses(ClassPrepareRequestor requestor, SourcePosition classPosition) throws EvaluateException;
+
+  ClassPrepareRequest createClassPrepareRequest(ClassPrepareRequestor requestor, String pattern);  
+
+  void enableRequest(EventRequest request);
+
+  void setInvalid(Requestor requestor, String message);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/requests/Requestor.java b/java/debugger/openapi/src/com/intellij/debugger/requests/Requestor.java
new file mode 100644
index 0000000..9a13832
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/requests/Requestor.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.requests;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: lex
+ * Date: Jun 27, 2003
+ * Time: 8:06:36 PM
+ * To change this template use Options | File Templates.
+ */
+public interface Requestor {
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptor.java b/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptor.java
new file mode 100644
index 0000000..4ed6de6
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptor.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.ui.tree;
+
+import com.intellij.openapi.util.Key;
+
+public interface NodeDescriptor {
+
+  String getName();
+  String getLabel();
+
+  <T> T getUserData(Key<T> key);
+  <T> void putUserData(Key<T> key, T value);
+
+  void displayAs(NodeDescriptor descriptor);
+
+  void setAncestor(NodeDescriptor oldDescriptor);
+}