private void importFile(File file, IProject project, List<IBuildpathEntry> entries) {

    try {

      level++;

      // handle windows path separators
      String path = file.getAbsolutePath().replace("\\", "/").replace(symfonyPath, "");

      // import the directory
      if (file.isDirectory() && !file.isHidden()) {

        IFolder folder = project.getFolder(path);

        if (!folder.exists()) {
          folder.create(true, true, null);
        }

        // add root folders to buildpath
        if (level == 1 && !folder.getFullPath().toString().endsWith("bin")) {

          IPath[] exclusion = {};

          if (folder.getName().equals(SymfonyCoreConstants.APP_PATH)) {
            exclusion =
                new IPath[] {
                  new Path(SymfonyCoreConstants.CACHE_PATH), new Path(SymfonyCoreConstants.LOG_PATH)
                };
          } else if (folder.getName().equals(SymfonyCoreConstants.VENDOR_PATH)) {
            exclusion = new IPath[] {new Path(SymfonyCoreConstants.SKELETON_PATH)};
          }

          IBuildpathEntry entry = DLTKCore.newSourceEntry(folder.getFullPath(), exclusion);
          entries.add(entry);
        }

        // now import recursively
        for (File f : file.listFiles()) {
          importFile(f, project, entries);
        }

        // create the project file
      } else if (file.isFile() && ".gitkeep".equals(file.getName()) == false) {

        FileInputStream fis = new FileInputStream(file);
        IFile iFile = project.getFile(path);
        iFile.create(fis, true, null);
      }

      level--;

    } catch (CoreException e) {
      e.printStackTrace();
      Logger.logException(e);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
      Logger.logException(e);
    }
  }
  public void installSymfony(IProgressMonitor monitor) {

    if (monitor == null) monitor = new NullProgressMonitor();

    SymfonyProjectWizardFirstPage firstPage = (SymfonyProjectWizardFirstPage) fFirstPage;
    monitor.beginTask("Installing symfony...", 100);
    monitor.worked(10);

    IProject projectHandle = fFirstPage.getProjectHandle();
    final IScriptProject scriptProject = DLTKCore.create(projectHandle);

    File file = null;
    final List<IBuildpathEntry> entries = new ArrayList<IBuildpathEntry>();

    level = 0;

    try {

      file = new File(firstPage.getLibraryPath());
      symfonyPath = new Path(firstPage.getLibraryPath()).toString();

      if (file.isDirectory()) {

        final File[] files = file.listFiles();

        if (!scriptProject.isOpen()) {
          scriptProject.open(monitor);
        }

        if (files != null && scriptProject != null && scriptProject.isOpen()) {

          for (File f : files) {
            importFile(f, scriptProject.getProject(), entries);
          }

          BuildPathUtils.addEntriesToBuildPath(scriptProject, entries);
          monitor.worked(90);
        }
      }
    } catch (ModelException e) {
      e.printStackTrace();
      Logger.logException(e);
    } catch (Exception e) {
      e.printStackTrace();
      Logger.logException(e);
    } finally {

      monitor.worked(100);
      monitor.done();
    }
  }
  private IHyperlink getTemplateLink(ViewPath viewPath, IRegion wordRegion) {

    IScriptFolder folder =
        SymfonyModelAccess.getDefault()
            .findBundleFolder(viewPath.getBundle(), input.getScriptProject());

    if (folder == null) {
      Logger.debugMSG("Unable to resolve template link: " + viewPath);
      return null;
    }

    String path = "Resources/views/";

    if (viewPath.getController() != null) {
      path += viewPath.getController() + "/";
    }

    path += viewPath.getTemplate();
    ISourceModule module = folder.getSourceModule(path);

    if (module != null) {
      return new ModelElementHyperlink(wordRegion, module, new OpenAction(editor));
    }

    return null;
  }
  @Override
  public String resolve(IScriptFolder container) {

    if (container == null) {
      Logger.log(Logger.WARNING, "Unable to resolve namespace, no container available");
      return null;
    }

    // Try composer first - Symfony 2.1
    try {
      IPath path = ModelAccess.getInstance().resolve(container.getResource());
      if (path != null) {
        return path.toString().replace("/", "\\");
      }
    } catch (Exception e) {
      Logger.logException(e);
    }

    // fallback to Symfony 2.0
    return SymfonyModelAccess.getDefault()
        .findNameSpace(container.getScriptProject(), container.getPath());
  }
  protected void createProjectSettings(IProject project, String containerPath, String consolePath)
      throws BackingStoreException {

    IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(SymfonyCorePlugin.ID);
    String executable = preferences.get(Keys.PHP_EXECUTABLE, null);
    IEclipsePreferences node = new ProjectScope(project).getNode(SymfonyCorePlugin.ID);
    if (executable != null) {
      node.put(Keys.PHP_EXECUTABLE, executable);
      Logger.log(Logger.WARNING, "Executable not found!");
    }
    node.put(Keys.CONSOLE, consolePath);
    node.put(Keys.USE_PROJECT_PHAR, Boolean.FALSE.toString());
    node.put(Keys.DUMPED_CONTAINER, containerPath);
    node.flush();
  }
  @Override
  public void build(IBuildContext context) throws CoreException {

    try {

      IFile file = context.getFile();

      ModuleDeclaration module = getModuleDeclaration(context);

      if (file.getFileExtension().equals("php")) {
        module.traverse(new AnnotationVisitor(context));
      }

    } catch (Exception e) {

      Logger.logException(e);
    }
  }
  @Override
  public boolean performFinish() {

    final IPath sourcePath = firstPage.getSourcePath();
    final IPath containerPath = firstPage.getContainerPath();
    final IPath consolePath = firstPage.getConsolePath();
    final String projectName = firstPage.getProjectName();
    final PHPVersion phpVersion = firstPage.getPHPVersion();
    final SymfonyVersion symfonyVersion = firstPage.getSymfonyVersion();

    IRunnableWithProgress op =
        new IRunnableWithProgress() {
          @Override
          public void run(IProgressMonitor monitor)
              throws InvocationTargetException, InterruptedException {
            IWorkspace workspace = ResourcesPlugin.getWorkspace();
            IWorkspaceRoot root = workspace.getRoot();
            IProject project = root.getProject(projectName);
            monitor.beginTask("Importing Symfony project", 5);

            try {

              IProjectDescription description = null;

              if (sourcePath.append(".project").toFile().exists()) {
                ProjectDescriptionReader reader = new ProjectDescriptionReader(project);
                description = reader.read(sourcePath.append(".project"));
                description.setName(projectName);
              } else {
                description = workspace.newProjectDescription(projectName);
              }

              // If it is under the root use the default location
              if (Platform.getLocation().isPrefixOf(sourcePath)) {
                description.setLocation(null);
              } else {
                description.setLocation(sourcePath);
              }

              monitor.worked(1);
              project.create(description, monitor);
              project.open(monitor);
              monitor.worked(1);

              applyNatures(new String[] {PHPNature.ID, SymfonyNature.NATURE_ID}, project, monitor);

              IScriptProject scriptProject = DLTKCore.create(project);
              IFile vendorPath = project.getFile(SymfonyCoreConstants.VENDOR_PATH);

              if (vendorPath != null && vendorPath.getRawLocation().toFile().exists()) {
                IBuildpathEntry sourceEntry =
                    DLTKCore.newSourceEntry(
                        vendorPath.getFullPath(),
                        new IPath[] {
                          new Path(SymfonyCoreConstants.SKELETON_PATTERN),
                          new Path(SymfonyCoreConstants.TEST_PATTERN),
                          new Path(SymfonyCoreConstants.CG_FIXTURE_PATTERN)
                        });
                BuildPathManager.setExclusionPattern(scriptProject, sourceEntry);
              }

              FacetManager.installFacets(project, phpVersion, symfonyVersion, monitor);
              monitor.worked(1);
              createProjectSettings(project, containerPath.toString(), consolePath.toString());

              project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
              monitor.worked(2);
            } catch (Exception e) {
              Logger.logException(e);
              // cleanup on failure
              if (project != null) {
                try {
                  if (project.isOpen()) {
                    project.close(monitor);
                  }
                  if (project.exists()) {
                    project.delete(true, monitor);
                  }
                } catch (CoreException e1) {
                  Logger.logException(e1);
                }
                throw new InvocationTargetException(e);
              }
            } finally {
              monitor.done();
            }
          }
        };

    try {
      getContainer().run(false, true, op);
    } catch (InvocationTargetException e) {
      String message = e.getMessage();
      if (message == null || message.length() == 0) {
        message = "An error occurred during import. Please see the workspace logs for details.";
      }
      MessageDialog.openError(getShell(), "Error importing project", message);
      return false;
    } catch (InterruptedException e) {
      Logger.logException(e);
      return true;
    }

    return true;
  }
  @Override
  public IHyperlink[] detectHyperlinks(
      ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {

    editor = org.eclipse.php.internal.ui.util.EditorUtility.getPHPEditor(textViewer);

    if (editor == null || region == null) {
      return null;
    }

    input = EditorUtility.getEditorInputModelElement(editor, false);

    if (input == null) {
      editor = null;
      return null;
    }

    try {
      if (input.getScriptProject() == null
          || !input.getScriptProject().getProject().hasNature(SymfonyNature.NATURE_ID)) {
        return null;
      }
    } catch (CoreException e1) {
      return null;
    }

    IDocument document = textViewer.getDocument();
    int offset = region.getOffset();

    try {

      IRegion wordRegion = findWord(document, offset);

      if (wordRegion == null) {
        return null;
      }

      String path = document.get(wordRegion.getOffset(), wordRegion.getLength());
      if (wordRegion.getOffset() > 0) {
        String start = document.get(wordRegion.getOffset() - 1, 1);
        if (!start.equals("'") && !start.equals("\"") && !start.equals(",")) {
          // this is not a string. Might be static member access
          return null;
        }
      }
      ViewPath viewPath = new ViewPath(path);

      // 	"AcmeDemoBundle::layout.html.twig" 2 part viewpath
      // link the whole thing to the template
      if (path.contains("::")) {

        String[] parts = path.split("::");

        if (parts.length == 2) {
          IHyperlink link = getTemplateLink(viewPath, wordRegion);
          if (link != null) {
            return new IHyperlink[] {link};
          }
        }

        // "AcmeDemoBundle:Demo:index.html.twig" 3 part viewpath
        // link the controller and the template separately
      } else if (path.contains(":")) {

        String[] parts = path.split(":");

        if (parts.length == 3) {

          int controllerLength = parts[0].length() + parts[1].length() + 1;
          int deltaOffset = offset - wordRegion.getOffset();

          if (deltaOffset < controllerLength) {

            Region controllerRegion = new Region(wordRegion.getOffset(), controllerLength);
            IHyperlink link = getControllerlink(viewPath, controllerRegion);

            if (link != null) {
              return new IHyperlink[] {link};
            }

          } else {

            Region templateRegion =
                new Region(wordRegion.getOffset() + controllerLength + 1, parts[2].length());
            IHyperlink link = getTemplateLink(viewPath, templateRegion);

            if (link != null) {
              return new IHyperlink[] {link};
            }
          }
        }
      }

    } catch (Exception e) {
      Logger.logException(e);
    } finally {
      input = null;
      editor = null;
    }

    return null;
  }