diff --git a/psi_demo.iml b/psi_demo.iml
new file mode 100644
index 000000000..e025b203c
--- /dev/null
+++ b/psi_demo.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
new file mode 100644
index 000000000..106ff0adb
--- /dev/null
+++ b/resources/META-INF/plugin.xml
@@ -0,0 +1,26 @@
+
+ com.jetbrains.psidemo
+ PSI demo
+ 1.0
+ YourCompany
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/intellij/tutorials/psi/PsiNavigationDemoAction.java b/src/com/intellij/tutorials/psi/PsiNavigationDemoAction.java
new file mode 100644
index 000000000..9eedf9be6
--- /dev/null
+++ b/src/com/intellij/tutorials/psi/PsiNavigationDemoAction.java
@@ -0,0 +1,54 @@
+package com.intellij.tutorials.psi;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+
+public class PsiNavigationDemoAction extends AnAction {
+ @Override
+ public void actionPerformed(AnActionEvent anActionEvent) {
+ Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
+ PsiFile psiFile = anActionEvent.getData(CommonDataKeys.PSI_FILE);
+ if (editor == null || psiFile == null) return;
+ int offset = editor.getCaretModel().getOffset();
+
+ final StringBuilder infoBuilder = new StringBuilder();
+ PsiElement element = psiFile.findElementAt(offset);
+ infoBuilder.append("Element at caret: ").append(element).append("\n");
+ if (element != null) {
+ PsiMethod containingMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
+ infoBuilder
+ .append("Containing method: ")
+ .append(containingMethod != null ? containingMethod.getName() : "none")
+ .append("\n");
+ if (containingMethod != null) {
+ PsiClass containingClass = containingMethod.getContainingClass();
+ infoBuilder
+ .append("Containing class: ")
+ .append(containingClass != null ? containingClass.getName() : "none")
+ .append("\n");
+
+ infoBuilder.append("Local variables:\n");
+ containingMethod.accept(new JavaRecursiveElementVisitor() {
+ @Override
+ public void visitLocalVariable(PsiLocalVariable variable) {
+ super.visitLocalVariable(variable);
+ infoBuilder.append(variable.getName()).append("\n");
+ }
+ });
+ }
+ }
+ Messages.showMessageDialog(anActionEvent.getProject(), infoBuilder.toString(), "PSI Info", null);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ Editor editor = e.getData(CommonDataKeys.EDITOR);
+ PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
+ e.getPresentation().setEnabled(editor != null && psiFile != null);
+ }
+}