diff --git a/base/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java b/base/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java
index 42ee110..1e002f4 100644
--- a/base/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java
+++ b/base/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java
@@ -35,21 +35,21 @@
 
 class FrameworkPerformanceMethod extends FrameworkMethod {
 
-	private Object target;
-	private PerformanceSuiteState performanceSuiteState;
-	private PerformanceRunner.ReportLevel reportLevel = PerformanceRunner.ReportLevel.ClassLevel;
+    private Object target;
+    private PerformanceSuiteState performanceSuiteState;
+    private PerformanceRunner.ReportLevel reportLevel = PerformanceRunner.ReportLevel.ClassLevel;
     private String testCaseName = "";
     private String className;
 
-	public FrameworkPerformanceMethod(Method method, Object target,
-			PerformanceSuiteState performanceSuiteState, PerformanceRunner.ReportLevel reportLevel) {
-		super(method);
-		this.target = target;
-		this.performanceSuiteState = performanceSuiteState;
-		this.reportLevel = reportLevel;
+    public FrameworkPerformanceMethod(Method method, Object target,
+            PerformanceSuiteState performanceSuiteState, PerformanceRunner.ReportLevel reportLevel) {
+        super(method);
+        this.target = target;
+        this.performanceSuiteState = performanceSuiteState;
+        this.reportLevel = reportLevel;
         if (target instanceof IdentifiableTestCase) {
             this.testCaseName = ((IdentifiableTestCase) target).testCaseName();
-	    }
+        }
 
         // Name of the test class, as the report logger needs it
         // This can be overwritten by tests by implementing IdentifiableTestClass
@@ -61,284 +61,284 @@
 
     }
 
-	@Override
-	public Object invokeExplosively(Object target, Object... params)
-			throws Throwable {
-		// Executes the test method on the supplied target
+    @Override
+    public Object invokeExplosively(Object target, Object... params)
+            throws Throwable {
+        // Executes the test method on the supplied target
 
-		// Check if this is the first test running from this specific
-		// PerformanceSuite
-		// and run the BeforeSuite methods
-		if ((performanceSuiteState != null)
-				&& (performanceSuiteState.getBeforeSuiteMethod() != null)
-				&& (performanceSuiteState.getTargetObjectSuite() != null)
-				&& (performanceSuiteState.getNumberOfExecutedMethods() == 0)
-				&& !performanceSuiteState.testSuiteName
-						.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
-			performanceSuiteState.getBeforeSuiteMethod().invoke(
-					performanceSuiteState.getTargetObjectSuite());
-		}
+        // Check if this is the first test running from this specific
+        // PerformanceSuite
+        // and run the BeforeSuite methods
+        if ((performanceSuiteState != null)
+                && (performanceSuiteState.getBeforeSuiteMethod() != null)
+                && (performanceSuiteState.getTargetObjectSuite() != null)
+                && (performanceSuiteState.getNumberOfExecutedMethods() == 0)
+                && !performanceSuiteState.testSuiteName
+                        .equals(ParameterizedTestList.TEST_CASE_ONLY)) {
+            performanceSuiteState.getBeforeSuiteMethod().invoke(
+                    performanceSuiteState.getTargetObjectSuite());
+        }
 
-		// In case of a PerformanceSuite we need to run the methods annotated
-		// with Before and After
-		// ourselves as JUnit can't find them (JUnit is looking for them in the
-		// test suite class);
-		// in case we don't have to deal with a PerformanceSuite just skip this
-		// as JUnit will run the methods itself
-		if ((performanceSuiteState != null)
-				&& !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
+        // In case of a PerformanceSuite we need to run the methods annotated
+        // with Before and After
+        // ourselves as JUnit can't find them (JUnit is looking for them in the
+        // test suite class);
+        // in case we don't have to deal with a PerformanceSuite just skip this
+        // as JUnit will run the methods itself
+        if ((performanceSuiteState != null)
+                && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
 
-			recursiveCallSpecificMethod(this.target.getClass(), this.target, Before.class);
-		}
+            recursiveCallSpecificMethod(this.target.getClass(), this.target, Before.class);
+        }
 
-		// Need to count the number of tests run from the PerformanceSuite
-		// so that we can call the AfterSuite method after the last test from
-		// the suite
-		// has run and the AfterSuite needs to run
-		performanceSuiteState.incrementNumberOfExecutedTestMethods();
+        // Need to count the number of tests run from the PerformanceSuite
+        // so that we can call the AfterSuite method after the last test from
+        // the suite
+        // has run and the AfterSuite needs to run
+        performanceSuiteState.incrementNumberOfExecutedTestMethods();
 
-		Object response = null;
+        Object response = null;
 
-		Method testMethodToInvoke = this.getMethod();
+        Method testMethodToInvoke = this.getMethod();
 
-		PerformanceTest performanceAnnotation = testMethodToInvoke
-				.getAnnotation(PerformanceTest.class);
+        PerformanceTest performanceAnnotation = testMethodToInvoke
+                .getAnnotation(PerformanceTest.class);
 
-		// retrieve the test configuration options
-		int warmuptime = performanceAnnotation.warmuptime();
-		int runtime = performanceAnnotation.runtime();
-		int warmupinvocations = performanceAnnotation.warmupinvocations();
-		int runinvocations = performanceAnnotation.runinvocations();
+        // retrieve the test configuration options
+        int warmuptime = performanceAnnotation.warmuptime();
+        int runtime = performanceAnnotation.runtime();
+        int warmupinvocations = performanceAnnotation.warmupinvocations();
+        int runinvocations = performanceAnnotation.runinvocations();
 
-		DescriptiveStatistics statistics = new DescriptiveStatistics();
+        DescriptiveStatistics statistics = new DescriptiveStatistics();
 
-		if (warmupinvocations != 0) {
-			// Run the number of invocation specified in the annotation
-			// for warming up the system
-			for (int invocationIndex = 0; invocationIndex < warmupinvocations; invocationIndex++) {
+        if (warmupinvocations != 0) {
+            // Run the number of invocation specified in the annotation
+            // for warming up the system
+            for (int invocationIndex = 0; invocationIndex < warmupinvocations; invocationIndex++) {
 
-				recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeMethodInvocation.class);
+                recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeMethodInvocation.class);
 
-				// TODO: implement the method to run a before a specific test
-				// method
-				// recursiveCallSpecificMethod(this.target.getClass(),
-				// this.target, BeforeSpecificTest.class);
+                // TODO: implement the method to run a before a specific test
+                // method
+                // recursiveCallSpecificMethod(this.target.getClass(),
+                // this.target, BeforeSpecificTest.class);
 
-				response = super.invokeExplosively(this.target, params);
+                response = super.invokeExplosively(this.target, params);
 
-				// TODO: implement the method to run a after a specific test
-				// method
-				// recursiveCallSpecificMethod(this.target.getClass(),
-				// this.target, AfterSpecificTest.class);
+                // TODO: implement the method to run a after a specific test
+                // method
+                // recursiveCallSpecificMethod(this.target.getClass(),
+                // this.target, AfterSpecificTest.class);
 
-				recursiveCallSpecificMethod(this.target.getClass(),
-						this.target, AfterMethodInvocation.class);
-			}
-		} else {
-			// Run a few iterations to warm up the system
-			long warmupEnd = System.currentTimeMillis() + warmuptime * 1000;
-			while (System.currentTimeMillis() < warmupEnd) {
-				recursiveCallSpecificMethod(this.target.getClass(),
-						this.target, BeforeMethodInvocation.class);
+                recursiveCallSpecificMethod(this.target.getClass(),
+                        this.target, AfterMethodInvocation.class);
+            }
+        } else {
+            // Run a few iterations to warm up the system
+            long warmupEnd = System.currentTimeMillis() + warmuptime * 1000;
+            while (System.currentTimeMillis() < warmupEnd) {
+                recursiveCallSpecificMethod(this.target.getClass(),
+                        this.target, BeforeMethodInvocation.class);
 
-				// TODO: implement the method to run a before a specific test
-				// method
-				// recursiveCallSpecificMethod(this.target.getClass(),
-				// this.target, BeforeSpecificTest.class);
+                // TODO: implement the method to run a before a specific test
+                // method
+                // recursiveCallSpecificMethod(this.target.getClass(),
+                // this.target, BeforeSpecificTest.class);
 
-				response = super.invokeExplosively(this.target, params);
+                response = super.invokeExplosively(this.target, params);
 
-				// recursiveCallSpecificMethod(this.target.getClass(),
-				// this.target, AfterSpecificTest.class);
-				// TODO: implement the method to run a after a specific test
-				// method
+                // recursiveCallSpecificMethod(this.target.getClass(),
+                // this.target, AfterSpecificTest.class);
+                // TODO: implement the method to run a after a specific test
+                // method
 
-				recursiveCallSpecificMethod(this.target.getClass(),
-						this.target, AfterMethodInvocation.class);
-			}
-		}
+                recursiveCallSpecificMethod(this.target.getClass(),
+                        this.target, AfterMethodInvocation.class);
+            }
+        }
 
-		// System.out.println("Warmup ended - test :" +
-		// testMethodToInvoke.getName());
-		if (runinvocations != 0) {
-			// Run the specified number of iterations and capture the execution
-			// times
-			for (int invocationIndex = 0; invocationIndex < runinvocations; invocationIndex++) {
+        // System.out.println("Warmup ended - test :" +
+        // testMethodToInvoke.getName());
+        if (runinvocations != 0) {
+            // Run the specified number of iterations and capture the execution
+            // times
+            for (int invocationIndex = 0; invocationIndex < runinvocations; invocationIndex++) {
 
-				response = this.invokeTimedTestMethod(testMethodToInvoke,
-						statistics, params);
-			}
-		} else {
-			// Run test iterations and capture the execution times
-			long runtimeEnd = System.currentTimeMillis() + runtime * 1000;
+                response = this.invokeTimedTestMethod(testMethodToInvoke,
+                        statistics, params);
+            }
+        } else {
+            // Run test iterations and capture the execution times
+            long runtimeEnd = System.currentTimeMillis() + runtime * 1000;
 
-			while (System.currentTimeMillis() < runtimeEnd) {
+            while (System.currentTimeMillis() < runtimeEnd) {
 
-				response = this.invokeTimedTestMethod(testMethodToInvoke,
-						statistics, params);
+                response = this.invokeTimedTestMethod(testMethodToInvoke,
+                        statistics, params);
 
-			}
-		}
+            }
+        }
 
-		if (statistics.getN() > 0) {
-		    ReportLogger.writeReport(this.performanceSuiteState.testSuiteName, testCaseName, className, getMethod().getName(),
+        if (statistics.getN() > 0) {
+            ReportLogger.writeReport(this.performanceSuiteState.testSuiteName, testCaseName, className, getMethod().getName(),
                     statistics, ReportLogger.ReportType.TXT, reportLevel);
-		}
+        }
 
-		// In case of a PerformanceSuite we need to run the methods annotated
-		// with Before and After
-		// ourselves as JUnit can't find them; in case we don't have to deal
-		// with a PerformanceSuite
-		// just skip this as JUnit will run the methods itself
-		if ((performanceSuiteState != null)
-				&& !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
+        // In case of a PerformanceSuite we need to run the methods annotated
+        // with Before and After
+        // ourselves as JUnit can't find them; in case we don't have to deal
+        // with a PerformanceSuite
+        // just skip this as JUnit will run the methods itself
+        if ((performanceSuiteState != null)
+                && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
 
-			recursiveCallSpecificMethod(this.target.getClass(), this.target, After.class);
-		}
+            recursiveCallSpecificMethod(this.target.getClass(), this.target, After.class);
+        }
 
-		// Check if this is the last test running from a PerformanceSuite
-		// and run the AfterSuite method
-		if ((performanceSuiteState != null)
-				&& (performanceSuiteState.getAfterSuiteMethod() != null)
-				&& (performanceSuiteState.getTargetObjectSuite() != null)
-				&& (performanceSuiteState.getNumberOfExecutedMethods() == performanceSuiteState.getNumberOfMethodsInSuite())
-				&& !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
-			performanceSuiteState.getAfterSuiteMethod().invoke(performanceSuiteState.getTargetObjectSuite());
-		}
+        // Check if this is the last test running from a PerformanceSuite
+        // and run the AfterSuite method
+        if ((performanceSuiteState != null)
+                && (performanceSuiteState.getAfterSuiteMethod() != null)
+                && (performanceSuiteState.getTargetObjectSuite() != null)
+                && (performanceSuiteState.getNumberOfExecutedMethods() == performanceSuiteState.getNumberOfMethodsInSuite())
+                && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
+            performanceSuiteState.getAfterSuiteMethod().invoke(performanceSuiteState.getTargetObjectSuite());
+        }
 
-		return response;
-	}
+        return response;
+    }
 
-	/**
-	 * Method that runs 1 invocation of the timed test method
-	 * 
-	 * @param testMethodToInvoke
-	 *            the test method to invoke
-	 * @param statistics
-	 *            the statistics object that collects the results
-	 * @param params
-	 *            the parameters for the invocation of the test method
-	 * @return the response from the method invocation
-	 * @throws Throwable
-	 */
-	private Object invokeTimedTestMethod(Method testMethodToInvoke,
-			DescriptiveStatistics statistics, Object... params)
-			throws Throwable {
+    /**
+     * Method that runs 1 invocation of the timed test method
+     *
+     * @param testMethodToInvoke
+     *            the test method to invoke
+     * @param statistics
+     *            the statistics object that collects the results
+     * @param params
+     *            the parameters for the invocation of the test method
+     * @return the response from the method invocation
+     * @throws Throwable
+     */
+    private Object invokeTimedTestMethod(Method testMethodToInvoke,
+            DescriptiveStatistics statistics, Object... params)
+            throws Throwable {
 
-		Object response = null;
+        Object response = null;
 
-		recursiveCallSpecificMethod(this.target.getClass(), this.target,
-				BeforeMethodInvocation.class);
+        recursiveCallSpecificMethod(this.target.getClass(), this.target,
+                BeforeMethodInvocation.class);
 
-		// TODO: implement the method to run a before a specific test method
-		// recursiveCallSpecificMethod(this.target.getClass(), this.target,
-		// BeforeSpecificTest.class);
+        // TODO: implement the method to run a before a specific test method
+        // recursiveCallSpecificMethod(this.target.getClass(), this.target,
+        // BeforeSpecificTest.class);
 
-		// timing the test method execution
-		// System.out.println("Start test: " + testMethodToInvoke.getName());
-		long start = System.nanoTime();
-		response = super.invokeExplosively(this.target, params);
-		long timeMilliseconds = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);
-		statistics.addValue(timeMilliseconds);
+        // timing the test method execution
+        // System.out.println("Start test: " + testMethodToInvoke.getName());
+        long start = System.nanoTime();
+        response = super.invokeExplosively(this.target, params);
+        long timeMilliseconds = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);
+        statistics.addValue(timeMilliseconds);
 
-		// System.out.println("End test: " + testMethodToInvoke.getName());
+        // System.out.println("End test: " + testMethodToInvoke.getName());
 
-		// System.out.println("Test execution time (ms): " + timeMilliseconds);
+        // System.out.println("Test execution time (ms): " + timeMilliseconds);
 
-		// TODO: implement the method to run a after a specific test method
-		// recursiveCallSpecificMethod(this.target.getClass(), this.target,
-		// AfterSpecificTest.class);
+        // TODO: implement the method to run a after a specific test method
+        // recursiveCallSpecificMethod(this.target.getClass(), this.target,
+        // AfterSpecificTest.class);
 
-		recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterMethodInvocation.class);
+        recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterMethodInvocation.class);
 
-		return response;
-	}
+        return response;
+    }
 
-	/**
-	 * Recursively call a specific method annotated with a custom annotation
-	 * 
-	 * @param test
-	 *            the test class that contains the method
-	 * @param instance
-	 *            the instance on which will run the method
-	 * @param methodAnnotation
-	 *            the method annotation to look for
-	 * @throws InvocationTargetException
-	 * @throws InvalidAttributesException
-	 * @throws IllegalAccessException
-	 * @throws InstantiationException
-	 */
-	@SuppressWarnings({ "rawtypes" })
-	private void recursiveCallSpecificMethod(Class test, Object instance,
-			Class<? extends Annotation> methodAnnotation)
-			throws InvocationTargetException, InvalidAttributesException,
-			IllegalAccessException, InstantiationException {
-		if (test.getSuperclass() != null) {
-			recursiveCallSpecificMethod(test.getSuperclass(), instance,
-					methodAnnotation);
-		}
+    /**
+     * Recursively call a specific method annotated with a custom annotation
+     *
+     * @param test
+     *            the test class that contains the method
+     * @param instance
+     *            the instance on which will run the method
+     * @param methodAnnotation
+     *            the method annotation to look for
+     * @throws InvocationTargetException
+     * @throws InvalidAttributesException
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    @SuppressWarnings({ "rawtypes" })
+    private void recursiveCallSpecificMethod(Class test, Object instance,
+            Class<? extends Annotation> methodAnnotation)
+            throws InvocationTargetException, InvalidAttributesException,
+            IllegalAccessException, InstantiationException {
+        if (test.getSuperclass() != null) {
+            recursiveCallSpecificMethod(test.getSuperclass(), instance,
+                    methodAnnotation);
+        }
 
-		Method testMethod = getSpecificTestMethod(test, methodAnnotation);
-		if (testMethod != null) {
-			if (!testMethod.isAccessible()) {
-				testMethod.setAccessible(true);
-			}
-			testMethod.invoke(instance);
-		}
-	}
+        Method testMethod = getSpecificTestMethod(test, methodAnnotation);
+        if (testMethod != null) {
+            if (!testMethod.isAccessible()) {
+                testMethod.setAccessible(true);
+            }
+            testMethod.invoke(instance);
+        }
+    }
 
-	/**
-	 * Get the method annotated with the custom annotation
-	 * 
-	 * @param testClass
-	 *            the test class on which to look for the method
-	 * @param methodAnnotation
-	 *            the method annotation to look for
-	 * @return
-	 * @throws InvalidAttributesException
-	 * @throws IllegalAccessException
-	 * @throws InstantiationException
-	 */
-	@SuppressWarnings({ "rawtypes" })
-	private Method getSpecificTestMethod(Class testClass,
-			Class<? extends Annotation> methodAnnotation)
-			throws InvalidAttributesException, IllegalAccessException,
-			InstantiationException {
+    /**
+     * Get the method annotated with the custom annotation
+     *
+     * @param testClass
+     *            the test class on which to look for the method
+     * @param methodAnnotation
+     *            the method annotation to look for
+     * @return
+     * @throws InvalidAttributesException
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    @SuppressWarnings({ "rawtypes" })
+    private Method getSpecificTestMethod(Class testClass,
+            Class<? extends Annotation> methodAnnotation)
+            throws InvalidAttributesException, IllegalAccessException,
+            InstantiationException {
 
-		Method[] methodsToReturn = getSpecificMethods(testClass, methodAnnotation);
-		Method methodToReturn = null;
-		if (methodsToReturn.length == 1) {
-			methodToReturn = methodsToReturn[0];
-		} else if (methodsToReturn.length > 1) {
-			throw new InvalidAttributesException("Only 1 non parameterized before method accepted");
-		}
+        Method[] methodsToReturn = getSpecificMethods(testClass, methodAnnotation);
+        Method methodToReturn = null;
+        if (methodsToReturn.length == 1) {
+            methodToReturn = methodsToReturn[0];
+        } else if (methodsToReturn.length > 1) {
+            throw new InvalidAttributesException("Only 1 non parameterized before method accepted");
+        }
 
-		return methodToReturn;
-	}
+        return methodToReturn;
+    }
 
-	/**
-	 * Retrieve all the specific methods from test class
-	 * 
-	 * @param testClass
-	 *            the test class that we need to search in
-	 * @param annotation
-	 *            the annotation that we should look for
-	 * @return the list with the methods that have the specified annotation
-	 */
-	@SuppressWarnings({ "rawtypes" })
-	private Method[] getSpecificMethods(Class testClass,
-			Class<? extends Annotation> annotation) {
-		Method[] allMethods = testClass.getDeclaredMethods();
+    /**
+     * Retrieve all the specific methods from test class
+     *
+     * @param testClass
+     *            the test class that we need to search in
+     * @param annotation
+     *            the annotation that we should look for
+     * @return the list with the methods that have the specified annotation
+     */
+    @SuppressWarnings({ "rawtypes" })
+    private Method[] getSpecificMethods(Class testClass,
+            Class<? extends Annotation> annotation) {
+        Method[] allMethods = testClass.getDeclaredMethods();
 
-		List<Method> methodListResult = new ArrayList<Method>();
+        List<Method> methodListResult = new ArrayList<Method>();
 
-		for (Method testMethod : allMethods) {
-			if (testMethod.isAnnotationPresent(annotation)) {
-				methodListResult.add(testMethod);
-			}
-		}
-		return methodListResult.toArray(new Method[] {});
-	}
+        for (Method testMethod : allMethods) {
+            if (testMethod.isAnnotationPresent(annotation)) {
+                methodListResult.add(testMethod);
+            }
+        }
+        return methodListResult.toArray(new Method[] {});
+    }
 
     @Override
     public String getName() {
diff --git a/base/src/main/java/org/apache/sling/performance/PerformanceRunner.java b/base/src/main/java/org/apache/sling/performance/PerformanceRunner.java
index ecd1bbc..bb646fe 100644
--- a/base/src/main/java/org/apache/sling/performance/PerformanceRunner.java
+++ b/base/src/main/java/org/apache/sling/performance/PerformanceRunner.java
@@ -50,80 +50,80 @@
 
 
 public class PerformanceRunner extends BlockJUnit4ClassRunner {
-	protected LinkedList<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
-	private List<PerformanceSuiteState> suitesState = new ArrayList<PerformanceSuiteState>();
-	public ReportLevel reportLevel = ReportLevel.ClassLevel;
-	
-	public static enum ReportLevel{
-		ClassLevel,
-		MethodLevel
-	}
-	
-	@Retention(RetentionPolicy.RUNTIME)
-	@Target(ElementType.TYPE)
-	public @interface Parameters {
-		public ReportLevel reportLevel() default ReportLevel.ClassLevel;
-	}
-	
-	public PerformanceRunner(Class<?> clazz) throws InitializationError {
-		super(clazz);
-		
-		// set the report level for the tests that are run with the PerformanceRunner
-		// by default set to class level for legacy tests compatibility
-		if (clazz.getAnnotation(Parameters.class) != null){
-			reportLevel = clazz.getAnnotation(Parameters.class).reportLevel();
-		}
-		
-		try {
-			computeTests();
-		} catch (Exception e) {
-			throw new InitializationError(e);
-		}
-	}
+    protected LinkedList<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
+    private List<PerformanceSuiteState> suitesState = new ArrayList<PerformanceSuiteState>();
+    public ReportLevel reportLevel = ReportLevel.ClassLevel;
 
-	/**
-	 * Compute the tests that will be run
-	 * 
-	 * @throws Exception
-	 */
-	protected void computeTests() throws Exception {
-		// add normal JUnit tests
-		tests.addAll(super.computeTestMethods());
+    public static enum ReportLevel{
+        ClassLevel,
+        MethodLevel
+    }
 
-		// add the performance tests
-		tests.addAll(computePerformanceTests());
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE)
+    public @interface Parameters {
+        public ReportLevel reportLevel() default ReportLevel.ClassLevel;
+    }
 
-		// This is called here to ensure the test class constructor is called at
-		// least
-		// once during testing.
-		createTest();
-	}
+    public PerformanceRunner(Class<?> clazz) throws InitializationError {
+        super(clazz);
 
-	/**
-	 * Compute performance tests
-	 * 
-	 * @return the list containing the performance test methods
-	 * @throws Exception
-	 */
-	protected Collection<? extends FrameworkMethod> computePerformanceTests()
-			throws Exception {
-		List<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
+        // set the report level for the tests that are run with the PerformanceRunner
+        // by default set to class level for legacy tests compatibility
+        if (clazz.getAnnotation(Parameters.class) != null){
+            reportLevel = clazz.getAnnotation(Parameters.class).reportLevel();
+        }
 
-		List<Object> testObjects = new ArrayList<Object>();
-		List<Object> testObjectsTmp = new ArrayList<Object>();
+        try {
+            computeTests();
+        } catch (Exception e) {
+            throw new InitializationError(e);
+        }
+    }
+
+    /**
+     * Compute the tests that will be run
+     *
+     * @throws Exception
+     */
+    protected void computeTests() throws Exception {
+        // add normal JUnit tests
+        tests.addAll(super.computeTestMethods());
+
+        // add the performance tests
+        tests.addAll(computePerformanceTests());
+
+        // This is called here to ensure the test class constructor is called at
+        // least
+        // once during testing.
+        createTest();
+    }
+
+    /**
+     * Compute performance tests
+     *
+     * @return the list containing the performance test methods
+     * @throws Exception
+     */
+    protected Collection<? extends FrameworkMethod> computePerformanceTests()
+            throws Exception {
+        List<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
+
+        List<Object> testObjects = new ArrayList<Object>();
+        List<Object> testObjectsTmp = new ArrayList<Object>();
 
 
-		ParameterizedTestList testCenter = new ParameterizedTestList();
+        ParameterizedTestList testCenter = new ParameterizedTestList();
 
-		// Retrieve the test objects included in the Performance test suite
-		for (FrameworkMethod method : getTestClass().getAnnotatedMethods(
-				PerformanceTestSuite.class)) {
-			Object targetObject = getTestClass().getJavaClass().newInstance();
-			if (method.getMethod().getReturnType()
-					.equals(ParameterizedTestList.class)) {
-				testCenter = (ParameterizedTestList) method.getMethod().invoke(
-						targetObject);
-				testObjectsTmp = testCenter.getTestObjectList();
+        // Retrieve the test objects included in the Performance test suite
+        for (FrameworkMethod method : getTestClass().getAnnotatedMethods(
+                PerformanceTestSuite.class)) {
+            Object targetObject = getTestClass().getJavaClass().newInstance();
+            if (method.getMethod().getReturnType()
+                    .equals(ParameterizedTestList.class)) {
+                testCenter = (ParameterizedTestList) method.getMethod().invoke(
+                        targetObject);
+                testObjectsTmp = testCenter.getTestObjectList();
 
                 // Iterate through all the test cases and see if they have a factory
                 for (Object testObject : testObjectsTmp) {
@@ -156,138 +156,138 @@
                         testObjects.add(testObject);
                     }
                 }
-			} else {
-				throw new InitializationError(
-						"Wrong signature for the @PerformanceTestSuite method");
-			}
-		}
+            } else {
+                throw new InitializationError(
+                        "Wrong signature for the @PerformanceTestSuite method");
+            }
+        }
 
-		// Retrieve the methods before running the methods from the test suite
-		List<FrameworkMethod> beforeSuiteMethods = getTestClass()
-				.getAnnotatedMethods(BeforeSuite.class);
-		if (beforeSuiteMethods.size() > 1) {
-			throw new InitializationError(
-					"Only one @BeforeSuite method is allowed for a @PerformanceSuite");
-		}
+        // Retrieve the methods before running the methods from the test suite
+        List<FrameworkMethod> beforeSuiteMethods = getTestClass()
+                .getAnnotatedMethods(BeforeSuite.class);
+        if (beforeSuiteMethods.size() > 1) {
+            throw new InitializationError(
+                    "Only one @BeforeSuite method is allowed for a @PerformanceSuite");
+        }
 
-		// Retrieve the methods before running the methods from the test suite
-		List<FrameworkMethod> afterSuiteMethods = getTestClass()
-				.getAnnotatedMethods(AfterSuite.class);
-		if (afterSuiteMethods.size() > 1) {
-			throw new InitializationError(
-					"Only one @AfterSuite method is allowed for a @PerformanceSuite");
-		}
+        // Retrieve the methods before running the methods from the test suite
+        List<FrameworkMethod> afterSuiteMethods = getTestClass()
+                .getAnnotatedMethods(AfterSuite.class);
+        if (afterSuiteMethods.size() > 1) {
+            throw new InitializationError(
+                    "Only one @AfterSuite method is allowed for a @PerformanceSuite");
+        }
 
-		PerformanceSuiteState current = null;
-		boolean suiteAlreadyRegistered = false;
+        PerformanceSuiteState current = null;
+        boolean suiteAlreadyRegistered = false;
 
-		for (PerformanceSuiteState suiteState : suitesState) {
-			if (suiteState.testSuiteName.equals(testCenter.getTestSuiteName())) {
-				suiteAlreadyRegistered = true;
-				suiteState.incrementNumberOfTestMethodsInSuite();
-				current = suiteState;
-				break;
-			}
-		}
+        for (PerformanceSuiteState suiteState : suitesState) {
+            if (suiteState.testSuiteName.equals(testCenter.getTestSuiteName())) {
+                suiteAlreadyRegistered = true;
+                suiteState.incrementNumberOfTestMethodsInSuite();
+                current = suiteState;
+                break;
+            }
+        }
 
-		// Create a new PerformanceSuiteState object
-		PerformanceSuiteState newSuite = new PerformanceSuiteState(
-				testCenter.getTestSuiteName());
+        // Create a new PerformanceSuiteState object
+        PerformanceSuiteState newSuite = new PerformanceSuiteState(
+                testCenter.getTestSuiteName());
 
-		if (!suiteAlreadyRegistered) {
-			if (beforeSuiteMethods.size() == 1) {
-				newSuite.setBeforeSuiteMethod(beforeSuiteMethods.get(0).getMethod());
-			}
-			if (afterSuiteMethods.size() == 1) {
-				newSuite.setAfterSuiteMethod(afterSuiteMethods.get(0).getMethod());
-			}
+        if (!suiteAlreadyRegistered) {
+            if (beforeSuiteMethods.size() == 1) {
+                newSuite.setBeforeSuiteMethod(beforeSuiteMethods.get(0).getMethod());
+            }
+            if (afterSuiteMethods.size() == 1) {
+                newSuite.setAfterSuiteMethod(afterSuiteMethods.get(0).getMethod());
+            }
 
-			current = newSuite;
-			newSuite.setTargetObjectSuite(getTestClass().getJavaClass().newInstance());
+            current = newSuite;
+            newSuite.setTargetObjectSuite(getTestClass().getJavaClass().newInstance());
 
-		}
+        }
 
-		// In case there are any objects retrieved from the Performance Suite
-		// we should add them to the tests that will be run and increase the
-		// number of methods
-		// contained in the PerformanceSuite
-		if (!testObjects.isEmpty()) {
-			for (Object testObject : testObjects) {
+        // In case there are any objects retrieved from the Performance Suite
+        // we should add them to the tests that will be run and increase the
+        // number of methods
+        // contained in the PerformanceSuite
+        if (!testObjects.isEmpty()) {
+            for (Object testObject : testObjects) {
 
-				// retrieve the test methods from the test classes
-				Method[] testMethods = getSpecificMethods(testObject.getClass(), PerformanceTest.class);
+                // retrieve the test methods from the test classes
+                Method[] testMethods = getSpecificMethods(testObject.getClass(), PerformanceTest.class);
 
-				for (Method method : testMethods) {
-					FrameworkPerformanceMethod performaceTestMethod =
+                for (Method method : testMethods) {
+                    FrameworkPerformanceMethod performaceTestMethod =
                             new FrameworkPerformanceMethod(method, testObject, current, reportLevel);
-					tests.add(performaceTestMethod);
-				}
+                    tests.add(performaceTestMethod);
+                }
 
                 if (!suiteAlreadyRegistered) {
-					newSuite.incrementNumberOfTestMethodsInSuite();
-				}
-			}
+                    newSuite.incrementNumberOfTestMethodsInSuite();
+                }
+            }
 
-			// add the new suite to the list of suites
-			suitesState.add(newSuite);
-		}
+            // add the new suite to the list of suites
+            suitesState.add(newSuite);
+        }
 
-		// Retrieve the performance tests in the case we don't have a
-		// performance test suite
-		for (FrameworkMethod method : getTestClass().getAnnotatedMethods(PerformanceTest.class)) {
-			Object targetObject = getTestClass().getJavaClass().newInstance();
-			FrameworkPerformanceMethod performanceTestMethod = new FrameworkPerformanceMethod(
-					method.getMethod(), targetObject, current, reportLevel);
-			tests.add(performanceTestMethod);
-		}
+        // Retrieve the performance tests in the case we don't have a
+        // performance test suite
+        for (FrameworkMethod method : getTestClass().getAnnotatedMethods(PerformanceTest.class)) {
+            Object targetObject = getTestClass().getJavaClass().newInstance();
+            FrameworkPerformanceMethod performanceTestMethod = new FrameworkPerformanceMethod(
+                    method.getMethod(), targetObject, current, reportLevel);
+            tests.add(performanceTestMethod);
+        }
 
-		return tests;
-	}
+        return tests;
+    }
 
 
-		/**
-	 * Retrieve specific method from test class
-	 * 
-	 * @param testClass
-	 *            the test class that we need to search in
-	 * @param annotation
-	 *            the annotation that we should look for
-	 * @return the list with the methods that have the specified annotation
-	 */
-	@SuppressWarnings({ "rawtypes" })
-	private Method[] getSpecificMethods(Class testClass,
-			Class<? extends Annotation> annotation) {
-		Method[] allMethods = testClass.getDeclaredMethods();
+        /**
+     * Retrieve specific method from test class
+     *
+     * @param testClass
+     *            the test class that we need to search in
+     * @param annotation
+     *            the annotation that we should look for
+     * @return the list with the methods that have the specified annotation
+     */
+    @SuppressWarnings({ "rawtypes" })
+    private Method[] getSpecificMethods(Class testClass,
+            Class<? extends Annotation> annotation) {
+        Method[] allMethods = testClass.getDeclaredMethods();
 
-		List<Method> methodListResult = new ArrayList<Method>();
+        List<Method> methodListResult = new ArrayList<Method>();
 
-		for (Method testMethod : allMethods) {
-			if (testMethod.isAnnotationPresent(annotation)) {
-				methodListResult.add(testMethod);
-			}
-		}
-		return methodListResult.toArray(new Method[] {});
-	}
+        for (Method testMethod : allMethods) {
+            if (testMethod.isAnnotationPresent(annotation)) {
+                methodListResult.add(testMethod);
+            }
+        }
+        return methodListResult.toArray(new Method[] {});
+    }
 
-	/**
-	 * {@inheritDoc}
-	 * 
-	 * @see org.junit.runners.BlockJUnit4ClassRunner#computeTestMethods()
-	 */
-	@Override
-	protected List<FrameworkMethod> computeTestMethods() {
-		return tests;
-	}
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.junit.runners.BlockJUnit4ClassRunner#computeTestMethods()
+     */
+    @Override
+    protected List<FrameworkMethod> computeTestMethods() {
+        return tests;
+    }
 
-	/**
-	 * Need to override method otherwise the validation will fail because of
-	 * some hardcoded conditions in JUnit
-	 */
-	@Override
-	protected void validateInstanceMethods(List<Throwable> errors) {
-		validatePublicVoidNoArgMethods(After.class, false, errors);
-		validatePublicVoidNoArgMethods(Before.class, false, errors);
-		validateTestMethods(errors);
-	}
+    /**
+     * Need to override method otherwise the validation will fail because of
+     * some hardcoded conditions in JUnit
+     */
+    @Override
+    protected void validateInstanceMethods(List<Throwable> errors) {
+        validatePublicVoidNoArgMethods(After.class, false, errors);
+        validatePublicVoidNoArgMethods(Before.class, false, errors);
+        validateTestMethods(errors);
+    }
 
 }
diff --git a/base/src/main/java/org/apache/sling/performance/ReportLogger.java b/base/src/main/java/org/apache/sling/performance/ReportLogger.java
index ac4ed49..64dccd9 100644
--- a/base/src/main/java/org/apache/sling/performance/ReportLogger.java
+++ b/base/src/main/java/org/apache/sling/performance/ReportLogger.java
@@ -19,9 +19,9 @@
     
     public static final String REPORTS_DIR = "performance-reports";
 
-	public enum ReportType {
-		TXT
-	}
+    public enum ReportType {
+        TXT
+    }
 
     /**
      * Method the writes the performance report after a test is run
@@ -36,54 +36,54 @@
      */
     public static void writeReport(String testSuiteName, String testCaseName, String className, String methodName,
             DescriptiveStatistics statistics, ReportType reportType, PerformanceRunner.ReportLevel reportLevel) throws Exception {
-		switch (reportType) {
+        switch (reportType) {
             case TXT:
                 writeReportTxt(testSuiteName, testCaseName, className, methodName, statistics, reportLevel);
                 break;
             default:
                 throw new Exception("The specified reporting format is not yet supported");
-		}
-	}
+        }
+    }
 
-	/**
+    /**
      * Method the writes the performance report after a test is run, in text format
-	 * 
+     *
      * @param testSuiteName
      * @param testCaseName
      * @param className
      * @param methodName
-	 * @param statistics
+     * @param statistics
      * @param reportLevel
      * @throws Exception
-	 */
+     */
     public static void writeReportTxt(String testSuiteName, String testCaseName, String className, String methodName,
             DescriptiveStatistics statistics, PerformanceRunner.ReportLevel reportLevel) throws Exception {
 
         File reportDir = new File("target/" + REPORTS_DIR);
-		if (!reportDir.exists() && !reportDir.mkdir()) {
+        if (!reportDir.exists() && !reportDir.mkdir()) {
                 throw new IOException("Unable to create " + REPORTS_DIR + " directory");
-		}
+        }
 
-		// need this in the case a user wants to set the suite name from the
-		// command line
-		// useful if we run the test cases from the command line for example
-		// by using maven
-		if (testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
-			if (System.getProperty("testsuitename") != null) {
-				testSuiteName = System.getProperty("testsuitename");
-			}
-		}
+        // need this in the case a user wants to set the suite name from the
+        // command line
+        // useful if we run the test cases from the command line for example
+        // by using maven
+        if (testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)) {
+            if (System.getProperty("testsuitename") != null) {
+                testSuiteName = System.getProperty("testsuitename");
+            }
+        }
 
-		if (reportLevel.equals(PerformanceRunner.ReportLevel.ClassLevel)) {
+        if (reportLevel.equals(PerformanceRunner.ReportLevel.ClassLevel)) {
             String resultFileName = className;
             writeReportClassLevel(resultFileName, testSuiteName, statistics);
         } else if (reportLevel.equals(PerformanceRunner.ReportLevel.MethodLevel)) {
             String resultFileName = className + "." + methodName;
             writeReportMethodLevel(resultFileName, testSuiteName, testCaseName, className, methodName, statistics);
         }
-	}
-	
-	/**
+    }
+
+    /**
      * Write report for class level tests
      *
      * @param resultFileName the name of the result file (without extension)
@@ -92,28 +92,28 @@
      */
     private static void writeReportClassLevel(String resultFileName, String testSuiteName,
             DescriptiveStatistics statistics) throws IOException {
-    	
+
         File report = getReportFile(resultFileName, ".txt");
-		boolean needsPrefix = !report.exists();
-	    PrintWriter writer = new PrintWriter(
-	    		new FileWriterWithEncoding(report, "UTF-8", true));
-	    try {
-	    	if (needsPrefix) {
-	    		writer.format("# %-50.50s     min     10%%     50%%     90%%     max%n", resultFileName);
-	    	}
-	    	
-	    	writer.format(
-	    			"%-52.52s  %6.0f  %6.0f  %6.0f  %6.0f  %6.0f%n",
-	    			testSuiteName,
-	    			statistics.getMin(),
-	    			statistics.getPercentile(10.0),
-	    			statistics.getPercentile(50.0),
-	    			statistics.getPercentile(90.0),
-	    			statistics.getMax());
+        boolean needsPrefix = !report.exists();
+        PrintWriter writer = new PrintWriter(
+                new FileWriterWithEncoding(report, "UTF-8", true));
+        try {
+            if (needsPrefix) {
+                writer.format("# %-50.50s     min     10%%     50%%     90%%     max%n", resultFileName);
+            }
+
+            writer.format(
+                    "%-52.52s  %6.0f  %6.0f  %6.0f  %6.0f  %6.0f%n",
+                    testSuiteName,
+                    statistics.getMin(),
+                    statistics.getPercentile(10.0),
+                    statistics.getPercentile(50.0),
+                    statistics.getPercentile(90.0),
+                    statistics.getMax());
         } finally {
             writer.close();
         }
-	}
+    }
     
     /**
      * Write report for method level tests
@@ -128,56 +128,56 @@
     private static void writeReportMethodLevel(String resultFileName, String testSuiteName, String testCaseName, String className,
             String methodName, DescriptiveStatistics statistics) throws IOException {
         File report = getReportFile(resultFileName, ".txt");
-	
-    	boolean needsPrefix = !report.exists();
-    	PrintWriter writer = new PrintWriter(
-    			new FileWriterWithEncoding(report, "UTF-8", true));
-    	try {
-    		if (needsPrefix) {
-    			writer.format(
-                        "%-40.40s|%-120.120s|%-80.80s|%-40.40s|      DateTime      |  min  |   10%%   |   50%%   |   90%%   |   max%n",
-    					"Test Suite",
-                        "Test Case",
-    					"Test Class",
-    					"Test Method");
-    		}
-    		
-    		writer.format(
-                    "%-40.40s|%-120.120s|%-80.80s|%-40.40s|%-20.20s|%7.0f|%9.0f|%9.0f|%9.0f|%9.0f%n",
-    				testSuiteName,
-                    (testCaseName.length() < 120) ? (testCaseName) : (testCaseName.substring(0, 115) + "[...]"),
-    				className,
-    				methodName,
-    				getDate(),
-    				statistics.getMin(),
-    				statistics.getPercentile(10.0),
-    				statistics.getPercentile(50.0),
-    				statistics.getPercentile(90.0),
-    				statistics.getMax());
-    		} finally {
-    			writer.close();
-    		}
-    }
-	    
-	
-	/**
-	 * Get the date that will be written into the result file
-	 */
-	private static String getDate() {
-		DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
-		Date date = new Date();
 
-		return dateFormat.format(date);
-	}
-	
-	private static File getReportFile(String resultFileName, String extension) {
-	    final String folder = "target/" + REPORTS_DIR;
-	    final String filename =  resultFileName + extension;
-	    if(!reportFolderLogged) {
-	        logger.info("Writing performance test results under {}", folder);
-	        reportFolderLogged = true;
-	    }
-	    return new File(folder, filename);
-	}
+        boolean needsPrefix = !report.exists();
+        PrintWriter writer = new PrintWriter(
+                new FileWriterWithEncoding(report, "UTF-8", true));
+        try {
+            if (needsPrefix) {
+                writer.format(
+                        "%-40.40s|%-120.120s|%-80.80s|%-40.40s|      DateTime      |  min  |   10%%   |   50%%   |   90%%   |   max%n",
+                        "Test Suite",
+                        "Test Case",
+                        "Test Class",
+                        "Test Method");
+            }
+
+            writer.format(
+                    "%-40.40s|%-120.120s|%-80.80s|%-40.40s|%-20.20s|%7.0f|%9.0f|%9.0f|%9.0f|%9.0f%n",
+                    testSuiteName,
+                    (testCaseName.length() < 120) ? (testCaseName) : (testCaseName.substring(0, 115) + "[...]"),
+                    className,
+                    methodName,
+                    getDate(),
+                    statistics.getMin(),
+                    statistics.getPercentile(10.0),
+                    statistics.getPercentile(50.0),
+                    statistics.getPercentile(90.0),
+                    statistics.getMax());
+            } finally {
+                writer.close();
+            }
+    }
+
+
+    /**
+     * Get the date that will be written into the result file
+     */
+    private static String getDate() {
+        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+        Date date = new Date();
+
+        return dateFormat.format(date);
+    }
+
+    private static File getReportFile(String resultFileName, String extension) {
+        final String folder = "target/" + REPORTS_DIR;
+        final String filename =  resultFileName + extension;
+        if(!reportFolderLogged) {
+            logger.info("Writing performance test results under {}", folder);
+            reportFolderLogged = true;
+        }
+        return new File(folder, filename);
+    }
 
 }
\ No newline at end of file
