diff --git a/smalidea/META-INF/plugin.xml b/smalidea/META-INF/plugin.xml
index 1229db1f..d166f2de 100644
--- a/smalidea/META-INF/plugin.xml
+++ b/smalidea/META-INF/plugin.xml
@@ -24,6 +24,7 @@
+
diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java
new file mode 100644
index 00000000..3a46396b
--- /dev/null
+++ b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.smalidea.debugging;
+
+import com.google.common.collect.Maps;
+import com.intellij.debugger.DebuggerManagerEx;
+import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.DebugProcessImpl;
+import com.intellij.debugger.engine.evaluation.*;
+import com.intellij.debugger.engine.events.DebuggerCommandImpl;
+import com.intellij.debugger.impl.DebuggerContextImpl;
+import com.intellij.debugger.jdi.StackFrameProxyImpl;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaCodeFragment;
+import com.intellij.psi.JavaRecursiveElementVisitor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiLocalVariable;
+import com.sun.jdi.*;
+import com.sun.tools.jdi.LocalVariableImpl;
+import com.sun.tools.jdi.LocationImpl;
+import org.jf.dexlib2.analysis.AnalyzedInstruction;
+import org.jf.dexlib2.analysis.RegisterType;
+import org.jf.smalidea.SmaliFileType;
+import org.jf.smalidea.psi.impl.SmaliInstruction;
+import org.jf.smalidea.psi.impl.SmaliMethod;
+
+import java.lang.reflect.Constructor;
+import java.util.Map;
+
+public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
+ @Override
+ public JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project) {
+ return super.createCodeFragment(item, wrapContext(project, context), project);
+ }
+
+ @Override
+ public JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project) {
+ return super.createPresentationCodeFragment(item, wrapContext(project, context), project);
+ }
+
+ @Override public LanguageFileType getFileType() {
+ return SmaliFileType.INSTANCE;
+ }
+
+ private PsiElement wrapContext(final Project project, final PsiElement originalContext) {
+ if (project.isDefault()) return originalContext;
+
+ final DebuggerContextImpl debuggerContext = DebuggerManagerEx.getInstanceEx(project).getContext();
+
+ SourcePosition position = debuggerContext.getSourcePosition();
+ SmaliInstruction currentInstruction = (SmaliInstruction)position.getElementAt();
+
+ final SmaliMethod containingMethod = currentInstruction.getParentMethod();
+ AnalyzedInstruction analyzedInstruction = currentInstruction.getAnalyzedInstruction();
+
+ final Map registerMap = Maps.newHashMap();
+ StringBuilder variablesText = new StringBuilder();
+ for (int i=0; i localVariableConstructor = LocalVariableImpl.class.getDeclaredConstructor(
+ VirtualMachine.class, Method.class, Integer.TYPE, Location.class, Location.class, String.class,
+ String.class, String.class);
+ localVariableConstructor.setAccessible(true);
+
+ Constructor locationConstructor = LocationImpl.class.getDeclaredConstructor(
+ VirtualMachine.class, Method.class, Long.TYPE);
+ locationConstructor.setAccessible(true);
+
+ // TODO: use frameProxy.location().method().locationOfCodeIndex() here
+ Location endLocation = locationConstructor.newInstance(vm, method, Integer.MAX_VALUE);
+
+ LocalVariable localVariable = localVariableConstructor.newInstance(vm,
+ method,
+ mapRegisterForArt(smaliMethod, registerNum),
+ frameProxy.location().method().locationOfCodeIndex(0),
+ endLocation,
+ String.format("v%d", registerNum), type, null);
+
+ ret[0] = frameProxy.getStackFrame().getValue(localVariable);
+ }
+ }
+ );
+
+ return ret[0];
+ }
+
+ private static int mapRegisterForArt(SmaliMethod smaliMethod, int register) {
+ int totalRegisters = smaliMethod.getRegisterCount();
+ int parameterRegisters = smaliMethod.getParameterRegisterCount();
+
+ // For ART, the parameter registers are rotated to the front
+ if (register >= (totalRegisters - parameterRegisters)) {
+ return register - (totalRegisters - parameterRegisters);
+ }
+ return register + parameterRegisters;
+ }
+}
+