/**
  * Creates a new {@link ProjectCallback} to be used with the layout lib.
  *
  * @param layoutLib The layout library this callback is going to be invoked from
  * @param projectRes the {@link ProjectResources} for the project.
  * @param project the project.
  * @param credential the sandbox credential
  */
 public ProjectCallback(
     LayoutLibrary layoutLib,
     ProjectResources projectRes,
     IProject project,
     Object credential,
     GraphicalEditorPart editor) {
   mLayoutLib = layoutLib;
   mParentClassLoader = layoutLib.getClassLoader();
   mProjectRes = projectRes;
   mProject = project;
   mCredential = credential;
   mEditor = editor;
 }
  /**
   * Looks at the parent-chain of the view and if it finds a custom view, or a CalendarView, within
   * the given distance then it returns true. A ListView within a CalendarView should not be
   * assigned a custom list view type because it sets its own and then attempts to cast the layout
   * to its own type which would fail if the normal default list item binding is used.
   */
  private boolean isWithinIllegalParent(Object viewObject, int depth) {
    String fqcn = viewObject.getClass().getName();
    if (fqcn.endsWith(CALENDAR_VIEW) || !fqcn.startsWith(ANDROID_PKG_PREFIX)) {
      return true;
    }

    if (depth > 0) {
      Result result = mLayoutLib.getViewParent(viewObject);
      if (result.isSuccess()) {
        Object parent = result.getData();
        if (parent != null) {
          return isWithinIllegalParent(parent, depth - 1);
        }
      }
    }

    return false;
  }
  private boolean loadLibrary(@NotNull IAndroidTarget target)
      throws RenderingException, IOException {
    final String layoutLibJarPath = target.getPath(IAndroidTarget.LAYOUT_LIB);
    final VirtualFile layoutLibJar = LocalFileSystem.getInstance().findFileByPath(layoutLibJarPath);
    if (layoutLibJar == null || layoutLibJar.isDirectory()) {
      throw new RenderingException(
          AndroidBundle.message(
              "android.file.not.exist.error", FileUtil.toSystemDependentName(layoutLibJarPath)));
    }

    final String resFolderPath = target.getPath(IAndroidTarget.RESOURCES);
    final VirtualFile resFolder = LocalFileSystem.getInstance().findFileByPath(resFolderPath);
    if (resFolder == null || !resFolder.isDirectory()) {
      throw new RenderingException(
          AndroidBundle.message(
              "android.directory.cannot.be.found.error",
              FileUtil.toSystemDependentName(resFolderPath)));
    }

    final String fontFolderPath = target.getPath(IAndroidTarget.FONTS);
    final VirtualFile fontFolder = LocalFileSystem.getInstance().findFileByPath(fontFolderPath);
    if (fontFolder == null || !fontFolder.isDirectory()) {
      throw new RenderingException(
          AndroidBundle.message(
              "android.directory.cannot.be.found.error",
              FileUtil.toSystemDependentName(fontFolderPath)));
    }

    final String platformFolderPath =
        target.isPlatform() ? target.getLocation() : target.getParent().getLocation();
    final File platformFolder = new File(platformFolderPath);
    if (!platformFolder.isDirectory()) {
      throw new RenderingException(
          AndroidBundle.message(
              "android.directory.cannot.be.found.error",
              FileUtil.toSystemDependentName(platformFolderPath)));
    }

    final File buildProp = new File(platformFolder, SdkConstants.FN_BUILD_PROP);
    if (!buildProp.isFile()) {
      throw new RenderingException(
          AndroidBundle.message(
              "android.file.not.exist.error", FileUtil.toSystemDependentName(buildProp.getPath())));
    }

    final SimpleLogger logger = new SimpleLogger(LOG);

    myLibrary =
        LayoutLibrary.load(
            layoutLibJar.getPath(),
            logger,
            ApplicationNamesInfo.getInstance().getFullProductName());
    if (myLibrary.getStatus() != LoadStatus.LOADED) {
      throw new RenderingException(myLibrary.getLoadMessage());
    }

    myResources = loadPlatformResources(new File(resFolder.getPath()), logger);

    final Map<String, String> buildPropMap =
        ProjectProperties.parsePropertyFile(new BufferingFileWrapper(buildProp), logger);
    return myLibrary.init(buildPropMap, new File(fontFolder.getPath()), myEnumMap, logger);
  }