@Override
  public void perform(GraphRewrite event, EvaluationContext context, XmlFileModel payload) {
    EnvironmentReferenceService envRefService =
        new EnvironmentReferenceService(event.getGraphContext());

    XmlFileService xmlFileService = new XmlFileService(event.getGraphContext());
    JNDIResourceService jndiResourceService = new JNDIResourceService(event.getGraphContext());
    JmsDestinationService jmsDestinationService =
        new JmsDestinationService(event.getGraphContext());
    GraphService<EjbSessionBeanModel> ejbSessionBeanService =
        new GraphService<>(event.getGraphContext(), EjbSessionBeanModel.class);
    GraphService<EjbMessageDrivenModel> mdbService =
        new GraphService<>(event.getGraphContext(), EjbMessageDrivenModel.class);

    ClassificationService classificationService =
        new ClassificationService(event.getGraphContext());
    ClassificationModel classification =
        classificationService.attachClassification(
            context,
            payload,
            "WebSphere EJB Binding",
            "WebSphere Enterprise Java Bean Binding XML Descriptor");
    classification.setEffort(1);

    TechnologyTagService technologyTagService = new TechnologyTagService(event.getGraphContext());
    technologyTagService.addTagToFileModel(payload, "WebSphere EJB", TechnologyTagLevel.IMPORTANT);

    Document doc = xmlFileService.loadDocumentQuiet(context, payload);

    if (doc == null) {
      return;
    }

    VendorSpecificationExtensionService vendorSpecificationService =
        new VendorSpecificationExtensionService(event.getGraphContext());
    // mark as vendor extension; create reference to ejb-jar.xml
    vendorSpecificationService.associateAsVendorExtension(payload, "ejb-jar.xml");

    Set<ProjectModel> applications =
        ProjectTraversalCache.getApplicationsForProject(
            event.getGraphContext(), payload.getProjectModel());

    // register beans to JNDI
    for (Element resourceRef : $(doc).find("ejbBindings").get()) {
      String href = $(resourceRef).child("enterpriseBean").attr("href");
      String resourceId = StringUtils.substringAfterLast(href, "ejb-jar.xml#");
      String jndiLocation = $(resourceRef).attr("jndiName");

      // determine type:
      String type = $(resourceRef).child("enterpriseBean").attr("type");

      LOG.info("Type: " + type);

      if (StringUtils.isNotBlank(jndiLocation) && StringUtils.isNotBlank(resourceId)) {
        JNDIResourceModel resource = jndiResourceService.createUnique(applications, jndiLocation);
        LOG.info("JNDI Name: " + jndiLocation + " to Resource: " + resourceId);
        // now, look up the resource which is resolved by DiscoverEjbConfigurationXmlRuleProvider
        for (EnvironmentReferenceModel ref :
            envRefService.findAllByProperty(EnvironmentReferenceModel.REFERENCE_ID, resourceId)) {
          envRefService.associateEnvironmentToJndi(resource, ref);
        }

        for (EjbSessionBeanModel ejb :
            ejbSessionBeanService.findAllByProperty(EjbSessionBeanModel.EJB_ID, resourceId)) {
          ejb.setGlobalJndiReference(resource);
        }
      }
    }

    // register beans to JNDI
    for (Element resourceRef : $(doc).find("resRefBindings").get()) {
      processBinding(
          envRefService, jndiResourceService, applications, resourceRef, "bindingResourceRef");
    }
    for (Element resourceRef : $(doc).find("ejbRefBindings").get()) {
      processBinding(
          envRefService, jndiResourceService, applications, resourceRef, "bindingEjbRef");
    }
    for (Element resourceRef : $(doc).find("messageDestinationRefBindings").get()) {
      processBinding(
          envRefService,
          jndiResourceService,
          applications,
          resourceRef,
          "bindingMessageDestinationRef");
    }

    // Bind MDBs to Destinations
    for (Element resourceRef : $(doc).find("messageDestinationRefBindings").get()) {
      String jndiLocation = $(resourceRef).attr("jndiName");

      // get the parent, as that has the reference to the MDB...
      String mdbRef = $(resourceRef).siblings("enterpriseBean").attr("href");
      String mdbId = StringUtils.substringAfterLast(mdbRef, "ejb-jar.xml#");

      if (StringUtils.isNotBlank(mdbId)) {
        for (EjbMessageDrivenModel mdb :
            mdbService.findAllByProperty(EjbMessageDrivenModel.EJB_ID, mdbId)) {
          String destination = jndiLocation;
          if (StringUtils.isNotBlank(destination)) {
            JmsDestinationModel jndiRef =
                jmsDestinationService.createUnique(applications, destination);
            mdb.setDestination(jndiRef);
          }
        }
      }
    }
  }
  @Test
  public void testFindingClassifiedFiles() throws Exception {
    FileModel f1 = context.getFramed().addVertex(null, FileModel.class);
    f1.setFilePath("/f1");
    FileModel f2 = context.getFramed().addVertex(null, FileModel.class);
    f2.setFilePath("/f2");
    FileModel f3 = context.getFramed().addVertex(null, FileModel.class);
    f3.setFilePath("/f3");
    FileModel f4 = context.getFramed().addVertex(null, FileModel.class);
    f4.setFilePath("/f4");
    FileModel f5 = context.getFramed().addVertex(null, FileModel.class);
    f5.setFilePath("/f5");
    FileModel f6 = context.getFramed().addVertex(null, FileModel.class);
    f6.setFilePath("/f6");
    FileModel f7 = context.getFramed().addVertex(null, FileModel.class);
    f7.setFilePath("/f7");

    InlineHintModel b1 = context.getFramed().addVertex(null, InlineHintModel.class);
    InlineHintModel b1b = context.getFramed().addVertex(null, InlineHintModel.class);
    b1.setFile(f1);
    b1b.setFile(f1);

    InlineHintModel b2 = context.getFramed().addVertex(null, InlineHintModel.class);
    b2.setFile(f2);

    ClassificationModel c1 = context.getFramed().addVertex(null, ClassificationModel.class);
    ClassificationModel c1b = context.getFramed().addVertex(null, ClassificationModel.class);
    c1.addFileModel(f1);
    c1b.addFileModel(f1);

    ClassificationModel c2 = context.getFramed().addVertex(null, ClassificationModel.class);
    c2.addFileModel(f3);

    TechnologyTagService techTagService = new TechnologyTagService(context);
    techTagService.addTagToFileModel(f4, "TestTag", TechnologyTagLevel.IMPORTANT);

    List<Vertex> vertexList = new ArrayList<>();
    for (Vertex v : context.getQuery().type(FileModel.class).vertices()) {
      vertexList.add(v);
    }

    GremlinPipeline<Vertex, Vertex> pipeline =
        new GremlinPipeline<>(context.getQuery().type(FileModel.class).vertices());

    GraphRewrite event = new GraphRewrite(context);

    // manually execute this criterion (this just adds things to the pipeline)
    new FindSourceReportFilesGremlinCriterion().query(event, pipeline);

    List<FileModel> fileModels = new ArrayList<>();
    for (Vertex v : pipeline) {
      // Explicit cast here insures that the frame returned was actually a FileModel. If it is not,
      // a
      // ClassCastException will
      // occur and the test will fail.
      //
      // If we called frame(v, FileModel.class) directly, frames would happily force it to be a
      // FileModel
      // even if the underlying query were returning invalid results.
      FileModel fm = (FileModel) context.getFramed().frame(v, WindupVertexFrame.class);
      fileModels.add(fm);
    }

    boolean foundF1 = false;
    boolean foundF2 = false;
    boolean foundF3 = false;
    boolean foundF4 = false;
    Assert.assertEquals(4, fileModels.size());
    for (FileModel fm : fileModels) {
      if (fm.getFilePath().equals(f1.getFilePath())) {
        foundF1 = true;
      } else if (fm.getFilePath().equals(f2.getFilePath())) {
        foundF2 = true;
      } else if (fm.getFilePath().equals(f3.getFilePath())) {
        foundF3 = true;
      } else if (fm.getFilePath().equals(f4.getFilePath())) {
        foundF4 = true;
      }
    }
    Assert.assertTrue(foundF1);
    Assert.assertTrue(foundF2);
    Assert.assertTrue(foundF3);
    Assert.assertTrue(foundF4);
  }