public PsiElement createFromTemplate(
      final Project project,
      final PsiDirectory directory,
      String fileName,
      final FileTemplate template,
      final String templateText,
      final Properties props)
      throws IncorrectOperationException {
    fileName = checkAppendExtension(fileName, template);

    if (FileTypeManager.getInstance().isFileIgnored(fileName)) {
      throw new IncorrectOperationException(
          "This filename is ignored (Settings | File Types | Ignore files and folders)");
    }

    directory.checkCreateFile(fileName);
    PsiFile file = PsiFileFactory.getInstance(project).createFileFromText(fileName, templateText);

    if (template.isReformatCode()) {
      CodeStyleManager.getInstance(project).reformat(file);
    }

    file = (PsiFile) directory.add(file);
    return file;
  }
  @Nullable
  private XmlFile createAnnotationsXml(
      @NotNull VirtualFile root, @NonNls @NotNull String packageName) {
    final String[] dirs = packageName.split("[\\.]");
    for (String dir : dirs) {
      if (dir.isEmpty()) break;
      VirtualFile subdir = root.findChild(dir);
      if (subdir == null) {
        try {
          subdir = root.createChildDirectory(null, dir);
        } catch (IOException e) {
          LOG.error(e);
        }
      }
      root = subdir;
    }
    final PsiDirectory directory = myPsiManager.findDirectory(root);
    if (directory == null) return null;

    final PsiFile psiFile = directory.findFile(ANNOTATIONS_XML);
    if (psiFile instanceof XmlFile) {
      return (XmlFile) psiFile;
    }

    try {
      final PsiFileFactory factory = PsiFileFactory.getInstance(myPsiManager.getProject());
      return (XmlFile)
          directory.add(
              factory.createFileFromText(ANNOTATIONS_XML, XmlFileType.INSTANCE, "<root></root>"));
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
    return null;
  }
  public static PsiFile createFromTemplate(
      final PsiDirectory directory,
      final String name,
      String fileName,
      String templateName,
      @NonNls String... parameters)
      throws IncorrectOperationException {
    log.debug("createFromTemplate: dir:" + directory + ", filename: " + fileName);

    final FileTemplate template = FileTemplateManager.getInstance().getTemplate(templateName);

    Properties properties =
        new Properties(FileTemplateManager.getInstance().getDefaultProperties());

    String text;

    try {
      text = template.getText(properties);
    } catch (Exception e) {
      throw new RuntimeException(
          "Unable to load template for "
              + FileTemplateManager.getInstance().internalTemplateToSubject(templateName),
          e);
    }

    final PsiFileFactory factory = PsiFileFactory.getInstance(directory.getProject());

    log.debug("Create file from text");
    final PsiFile file = factory.createFileFromText(fileName, MoonFileType.MOON_FILE_TYPE, text);

    log.debug("Adding file to directory");
    return (PsiFile) directory.add(file);
  }
  @NotNull
  private static PsiClass createBeanClass(final WizardData wizardData) throws MyException {
    final PsiManager psiManager = PsiManager.getInstance(wizardData.myProject);

    final ProjectRootManager projectRootManager =
        ProjectRootManager.getInstance(wizardData.myProject);
    final ProjectFileIndex fileIndex = projectRootManager.getFileIndex();
    final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(wizardData.myFormFile);
    if (sourceRoot == null) {
      throw new MyException(UIDesignerBundle.message("error.form.file.is.not.in.source.root"));
    }

    final PsiDirectory rootDirectory = psiManager.findDirectory(sourceRoot);
    LOG.assertTrue(rootDirectory != null);

    final PsiPackage aPackage =
        JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(wizardData.myPackageName);
    if (aPackage == null) {
      throw new MyException(
          UIDesignerBundle.message("error.package.does.not.exist", wizardData.myPackageName));
    }

    PsiDirectory targetDir = null;

    final PsiDirectory[] directories = aPackage.getDirectories();
    for (final PsiDirectory psiDirectory : directories) {
      if (PsiTreeUtil.isAncestor(rootDirectory, psiDirectory, false)) {
        targetDir = psiDirectory;
        break;
      }
    }

    if (targetDir == null) {
      // todo
      throw new MyException(
          UIDesignerBundle.message("error.cannot.find.package", wizardData.myPackageName));
    }

    //noinspection HardCodedStringLiteral
    final String body =
        "public class "
            + wizardData.myShortClassName
            + "{\n"
            + "public "
            + wizardData.myShortClassName
            + "(){}\n"
            + "}";

    try {
      PsiFile sourceFile =
          PsiFileFactory.getInstance(psiManager.getProject())
              .createFileFromText(wizardData.myShortClassName + ".java", body);
      sourceFile = (PsiFile) targetDir.add(sourceFile);

      final PsiClass beanClass = ((PsiJavaFile) sourceFile).getClasses()[0];

      final ArrayList<String> properties = new ArrayList<String>();
      final HashMap<String, String> property2fqClassName = new HashMap<String, String>();

      final FormProperty2BeanProperty[] bindings = wizardData.myBindings;
      for (final FormProperty2BeanProperty binding : bindings) {
        if (binding == null || binding.myBeanProperty == null) {
          continue;
        }

        properties.add(binding.myBeanProperty.myName);

        // todo: handle "casts" ?

        final String propertyClassName = binding.myFormProperty.getComponentPropertyClassName();

        property2fqClassName.put(binding.myBeanProperty.myName, propertyClassName);
      }

      generateBean(beanClass, ArrayUtil.toStringArray(properties), property2fqClassName);

      return beanClass;
    } catch (IncorrectOperationException e) {
      throw new MyException(e.getMessage());
    }
  }
  private PsiClass buildClass() {
    if (existingClass != null) {
      return existingClass;
    }
    final ParameterObjectBuilder beanClassBuilder = new ParameterObjectBuilder();
    beanClassBuilder.setVisibility(myCreateInnerClass ? PsiModifier.PRIVATE : PsiModifier.PUBLIC);
    beanClassBuilder.setProject(myProject);
    beanClassBuilder.setTypeArguments(typeParams);
    beanClassBuilder.setClassName(className);
    beanClassBuilder.setPackageName(packageName);
    for (ParameterChunk parameterChunk : parameters) {
      final VariableData parameter = parameterChunk.parameter;
      final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable);
      beanClassBuilder.addField(
          (PsiParameter) parameter.variable, parameter.name, parameter.type, setterRequired);
    }
    final String classString = beanClassBuilder.buildBeanClass();

    try {
      final PsiFileFactory factory = PsiFileFactory.getInstance(method.getProject());
      final PsiJavaFile newFile =
          (PsiJavaFile)
              factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString);
      if (myCreateInnerClass) {
        final PsiClass containingClass = method.getContainingClass();
        final PsiClass[] classes = newFile.getClasses();
        assert classes.length > 0 : classString;
        final PsiClass innerClass = (PsiClass) containingClass.add(classes[0]);
        PsiUtil.setModifierProperty(innerClass, PsiModifier.STATIC, true);
        return (PsiClass)
            JavaCodeStyleManager.getInstance(newFile.getProject())
                .shortenClassReferences(innerClass);
      } else {
        final PsiFile containingFile = method.getContainingFile();
        final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
        final PsiDirectory directory;
        if (myMoveDestination != null) {
          directory = myMoveDestination.getTargetDirectory(containingDirectory);
        } else {
          final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
          directory =
              PackageUtil.findOrCreateDirectoryForPackage(
                  module, packageName, containingDirectory, true, true);
        }

        if (directory != null) {

          final CodeStyleManager codeStyleManager =
              CodeStyleManager.getInstance(method.getManager().getProject());
          final PsiElement shortenedFile =
              JavaCodeStyleManager.getInstance(newFile.getProject())
                  .shortenClassReferences(newFile);
          final PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile);
          return ((PsiJavaFile) directory.add(reformattedFile)).getClasses()[0];
        }
      }
    } catch (IncorrectOperationException e) {
      logger.info(e);
    }
    return null;
  }
  private PsiClass buildClass() {
    final PsiManager manager = sourceClass.getManager();
    final Project project = sourceClass.getProject();
    final ExtractedClassBuilder extractedClassBuilder = new ExtractedClassBuilder();
    extractedClassBuilder.setProject(myProject);
    extractedClassBuilder.setClassName(newClassName);
    extractedClassBuilder.setPackageName(newPackageName);
    extractedClassBuilder.setOriginalClassName(sourceClass.getQualifiedName());
    extractedClassBuilder.setRequiresBackPointer(requiresBackpointer);
    extractedClassBuilder.setExtractAsEnum(enumConstants);
    for (PsiField field : fields) {
      extractedClassBuilder.addField(field);
    }
    for (PsiMethod method : methods) {
      extractedClassBuilder.addMethod(method);
    }
    for (PsiClass innerClass : innerClasses) {
      extractedClassBuilder.addInnerClass(
          innerClass, innerClassesToMakePublic.contains(innerClass));
    }
    extractedClassBuilder.setTypeArguments(typeParams);
    final List<PsiClass> interfaces = calculateInterfacesSupported();
    extractedClassBuilder.setInterfaces(interfaces);

    if (myGenerateAccessors) {
      final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4ExtractedClass();
      sourceClass.accept(visitor);
      extractedClassBuilder.setFieldsNeedingGetters(visitor.getFieldsNeedingGetter());
      extractedClassBuilder.setFieldsNeedingSetters(visitor.getFieldsNeedingSetter());
    }

    final String classString = extractedClassBuilder.buildBeanClass();
    if (extractInnerClass) {
      final PsiFileFactory factory = PsiFileFactory.getInstance(project);
      final PsiJavaFile newFile =
          (PsiJavaFile)
              factory.createFileFromText(
                  newClassName + ".java", JavaFileType.INSTANCE, classString);
      final PsiClass psiClass = newFile.getClasses()[0];
      if (!psiClass.isEnum()) {
        final PsiModifierList modifierList = psiClass.getModifierList();
        assert modifierList != null;
        modifierList.setModifierProperty(PsiModifier.STATIC, true);
      }
      final PsiElement addedClass = sourceClass.add(psiClass);
      return (PsiClass)
          CodeStyleManager.getInstance(manager)
              .reformat(
                  JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedClass));
    }

    try {
      final PsiFile containingFile = sourceClass.getContainingFile();
      final PsiDirectory directory;
      final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
      if (myMoveDestination != null) {
        directory = myMoveDestination.getTargetDirectory(containingDirectory);
      } else {
        final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
        assert module != null;
        directory =
            PackageUtil.findOrCreateDirectoryForPackage(
                module, newPackageName, containingDirectory, false, true);
      }
      if (directory != null) {
        final PsiFileFactory factory = PsiFileFactory.getInstance(project);
        final PsiFile newFile =
            factory.createFileFromText(newClassName + ".java", JavaFileType.INSTANCE, classString);
        final PsiElement addedFile = directory.add(newFile);
        final CodeStyleManager codeStyleManager =
            CodeStyleManager.getInstance(manager.getProject());
        final PsiElement shortenedFile =
            JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedFile);
        return ((PsiJavaFile) codeStyleManager.reformat(shortenedFile)).getClasses()[0];
      } else {
        return null;
      }
    } catch (IncorrectOperationException e) {
      return null;
    }
  }