/**
   * Computes file metrics.
   *
   * @param file File.
   * @return Map that contains key-value pairs if object metrics.
   */
  private Map<String, String> computeFileMetrics(IFile file) {
    // Adds statechange DevEvent.
    Map<String, String> statechangeKeyValueMap = new HashMap<String, String>();
    statechangeKeyValueMap.put(EclipseSensorConstants.SUBTYPE, "StateChange");
    // Process file size
    String sizeString = String.valueOf(activeBufferSize);
    statechangeKeyValueMap.put(PROP_CURRENT_SIZE, sizeString);

    if (file.getName().endsWith(EclipseSensorConstants.JAVA_EXT)) {
      // Fully qualified class path
      String className = this.getFullyQualifedClassName(file);
      statechangeKeyValueMap.put(PROP_CLASS_NAME, className);

      // Measure java file.
      JavaStatementMeter testCounter = measureJavaFile(file);

      this.class2FileMap.put(className, file.getLocationURI());
      String methodCountString = String.valueOf(testCounter.getNumOfMethods());
      statechangeKeyValueMap.put(PROP_CURRENT_METHODS, methodCountString);

      String statementCountString = String.valueOf(testCounter.getNumOfStatements());
      statechangeKeyValueMap.put(PROP_CURRENT_STATEMENTS, statementCountString);

      // Number of test method and assertion statements.
      if (testCounter.hasTest()) {
        String testMethodCount = String.valueOf(testCounter.getNumOfTestMethods());
        statechangeKeyValueMap.put(PROP_CURRENT_TEST_METHODS, testMethodCount);

        String testAssertionCount = String.valueOf(testCounter.getNumOfTestAssertions());
        statechangeKeyValueMap.put(PROP_CURRENT_TEST_ASSERTIONS, testAssertionCount);
      }
    }

    return statechangeKeyValueMap;
  }
    /**
     * Provides visitor pattern due to implement <code>IResourceDeltaVisitor</code>. This method
     * must not be called by client because it is called by EclipseSensorPlugin instance. Note that
     * <code>true</code> is returned if the parameter of IResourceDelta instance has children.
     * <code>false</code> is returned when either Project is opened, closed, or file is saved
     * because no more traverse of children of the IResourceDelta instance is needed.
     *
     * @param delta IResourceDelta instance to contains delta resource.
     * @return true if the resource delta's children should be visited; false if they should be
     *     skipped.
     * @throws CoreException if the visit fails for some reason.
     */
    public boolean visit(IResourceDelta delta) throws CoreException {
      IResource resource = delta.getResource();
      int flag = delta.getFlags();
      int kind = delta.getKind();

      // If there is compilation problem with the current java file then send out the activity data.
      if ((flag & IResourceDelta.MARKERS) != 0 && EclipseSensor.this.buildErrorSensor != null) {
        EclipseSensor.this.buildErrorSensor.findBuildProblem(delta);
      }

      // :RESOLVED: 26 May 2003
      // Note that the 147456 enumeration type is not listed in the IResourceDelta static filed.
      // However, its number is generated when Project is either opened or closed so that
      // it is checked in the logical condition.
      if (resource instanceof IProject && ((flag == IResourceDelta.OPEN) || (flag == 147456))) {
        IProject project = resource.getProject();
        String projectName = project.getName();
        URI projectResoruce = project.getFile(".project").getLocationURI();

        Map<String, String> keyValueMap = new HashMap<String, String>();
        keyValueMap.put(EclipseSensorConstants.UNIT_TYPE, "project");
        keyValueMap.put(EclipseSensorConstants.UNIT_NAME, projectName);

        if (((IProject) resource).isOpen()) {
          keyValueMap.put(EclipseSensorConstants.SUBTYPE, "Open");
          EclipseSensor.this.addDevEvent(
              EclipseSensorConstants.DEVEVENT_EDIT,
              projectResoruce,
              keyValueMap,
              projectResoruce.toString());
        } else {
          keyValueMap.put(EclipseSensorConstants.SUBTYPE, "Close");
          EclipseSensor.this.addDevEvent(
              EclipseSensorConstants.DEVEVENT_EDIT,
              projectResoruce,
              keyValueMap,
              projectResoruce.toString());
        }
        return false;
      }
      if ((kind == IResourceDelta.CHANGED)
          && (flag == IResourceDelta.CONTENT)
          && resource instanceof IFile) {
        if (resource.getLocation().toString().endsWith(EclipseSensorConstants.JAVA_EXT)) {
          IFile file = (IFile) resource;

          Map<String, String> keyValueMap = new HashMap<String, String>();

          keyValueMap.put("Language", "java");
          keyValueMap.put(EclipseSensorConstants.UNIT_TYPE, EclipseSensorConstants.FILE);

          // Fully qualified class path
          String className = EclipseSensor.this.getFullyQualifedClassName(file);
          keyValueMap.put("Class-Name", className);

          // Size of the file in buffer
          String bufferSize = String.valueOf(activeBufferSize);
          keyValueMap.put("Current-Size", bufferSize);

          // Measure java file.
          JavaStatementMeter testCounter = measureJavaFile(file);
          testCounter = measureJavaFile(file);
          String methodCount = String.valueOf(testCounter.getNumOfMethods());
          keyValueMap.put("Current-Methods", methodCount);

          String statementCount = String.valueOf(testCounter.getNumOfStatements());
          keyValueMap.put("Current-Statements", statementCount);

          // Number of test method and assertion statements.
          if (testCounter.hasTest()) {
            String testMethodCount = String.valueOf(testCounter.getNumOfTestMethods());
            keyValueMap.put("Current-Test-Methods", testMethodCount);

            String testAssertionCount = String.valueOf(testCounter.getNumOfTestAssertions());
            keyValueMap.put("Current-Test-Assertions", testAssertionCount);
          }

          // EclipseSensor.this.eclipseSensorShell.doCommand("Activity", activityData);
          // Construct message to display on Eclipse status bar.
          URI fileResource = file.getLocationURI();

          StringBuffer message = new StringBuffer("Save File");
          message.append(" : ").append(EclipseSensor.this.extractFileName(fileResource));

          keyValueMap.put(EclipseSensorConstants.SUBTYPE, "Save");
          EclipseSensor.this.addDevEvent(
              EclipseSensorConstants.DEVEVENT_EDIT, fileResource, keyValueMap, message.toString());
        }

        // Visit the children because it is not necessary for the saving file to be only one file.
        return true;
      }
      return true; // visit the children
    }