@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;
  }
  @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());
    }
  }