@Override
  public void apply(ICompletionReporter reporter) throws BadLocationException {

    ViewPathArgumentContext context = (ViewPathArgumentContext) getContext();
    CompletionRequestor req = context.getCompletionRequestor();

    if (req.getClass() == PHPCompletionProposalCollector.class) {
      return;
    }

    if (workaroundCount == 0) {
      workaroundCount++;

    } else {
      workaroundCount = 0;
      return;
    }

    SymfonyModelAccess model = SymfonyModelAccess.getDefault();
    ISourceModule module = context.getSourceModule();
    ViewPath viewPath = context.getViewPath();

    String bundle = viewPath.getBundle();
    String controller = viewPath.getController();
    String template = viewPath.getTemplate();
    SourceRange range = getReplacementRange(context);
    IDLTKSearchScope projectScope =
        SearchEngine.createSearchScope(context.getSourceModule().getScriptProject());

    String prefix = context.getPrefix();

    // complete the bundle part
    if (bundle == null && controller == null && template == null) {

      List<Bundle> bundles = model.findBundles(context.getSourceModule().getScriptProject());

      for (Bundle b : bundles) {

        IType[] bundleTypes =
            PhpModelAccess.getDefault()
                .findTypes(b.getElementName(), MatchRule.EXACT, 0, 0, projectScope, null);

        if (bundleTypes.length == 1) {

          ModelElement bType = (ModelElement) bundleTypes[0];

          if (CodeAssistUtils.startsWithIgnoreCase(bType.getElementName(), prefix)) {
            Bundle bundleType = new Bundle(bType, b.getElementName());
            reporter.reportType(bundleType, ":", range);
          }
        }
      }

      // complete the controller part: "Bundle:|
    } else if (controller == null && template == null) {

      IType[] controllers = model.findBundleControllers(bundle, module.getScriptProject());

      if (controllers != null) {
        for (IType ctrl : controllers) {

          String name = ctrl.getElementName().replace("Controller", "");
          if (!name.endsWith("\\")) {
            Controller con = new Controller((ModelElement) ctrl, name);
            reporter.reportType(con, ":", range);
          }
        }
      }

      // complete template path: "Bundle:Controller:|
    } else if (bundle != null && controller != null && template == null) {

      IModelElement[] templates =
          model.findTemplates(bundle, controller, module.getScriptProject());

      if (templates != null) {
        for (IModelElement tpl : templates) {

          if (CodeAssistUtils.startsWithIgnoreCase(tpl.getElementName(), prefix)) {
            Template t = new Template((ModelElement) tpl, tpl.getElementName());
            reporter.reportType(t, "", range);
          }
        }
      }

      // project root: "::|
    } else if (bundle == null && controller == null && template != null) {

      IModelElement[] templates = model.findRootTemplates(module.getScriptProject());

      if (templates != null) {
        for (IModelElement tpl : templates) {

          if (CodeAssistUtils.startsWithIgnoreCase(tpl.getElementName(), prefix)) {
            Template t = new Template((ModelElement) tpl, tpl.getElementName());
            reporter.reportType(t, "", range);
          }
        }
      }

      // bundle root: "AcmeDemoBundle::|
    } else if (bundle != null && controller == null && template != null) {

      IModelElement[] templates = model.findBundleRootTemplates(bundle, module.getScriptProject());

      if (templates != null) {
        for (IModelElement tpl : templates) {

          if (CodeAssistUtils.startsWithIgnoreCase(tpl.getElementName(), prefix)) {
            Template t = new Template((ModelElement) tpl, tpl.getElementName());
            reporter.reportType(t, "", range);
          }
        }
      }
    }
  }