src/main/java/org/perfidix/meter/AbstractMeter.java
public abstract class AbstractMeter {

    /**
     * Getting the current value for this meter.
     *
     * @return the current tick value.
     */
    public abstract double getValue();

    /**
     * Returns the unit in which this measure taker computes its results.
     *
     * @return the unit of this meter
     */
    public abstract String getUnit();

    /**
     * The long description of the unit. can be empty but if available, it should provide one or two words about the
     * measure taker.
     *
     * @return the long description of the unit in which measurement takes place.
     */
    public abstract String getUnitDescription();

    /**
     * A short name of the meter.
     *
     * @return the name.
     */
    public abstract String getName();

    /**
     * The String representation of this meter with its current value.
     *
     * @return a string representation of this meter.
     */
    @Override
    public final String toString() {

        return getName() + "[" + getUnit() + "]";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public abstract int hashCode();

    /**
     * {@inheritDoc}
     */
    @Override
    public abstract boolean equals(final Object obj);

}
src/main/java/org/perfidix/result/AbstractResult.java
public abstract class AbstractResult {

    /**
     * Related element of this container. Can be a method or a class.
     */
    private transient final Object relatedElement;

    /**
     * Results mapped to the meters.
     */
    private transient final Map<AbstractMeter, Collection<Double>> meterResults;

    /**
     * Constructor with a given name.
     *
     * @param paramElement element to this result.
     */
    AbstractResult(final Object paramElement) {
        this.relatedElement = paramElement;
        this.meterResults = new Hashtable<AbstractMeter, Collection<Double>>();

    }

    /**
     * Returns the name of the related element where these results belong to.
     *
     * @return the name as a String.
     */
    protected abstract String getElementName();

    /**
     * an array of all data items in the structure.
     *
     * @param meter for the results wanted
     * @return the result set.
     */
    public final Collection<Double> getResultSet(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        return this.meterResults.get(meter);
    }

    /**
     * Getting all meters registered in this result.
     *
     * @return a set of all meters.
     */
    public final Set<AbstractMeter> getRegisteredMeters() {
        return this.meterResults.keySet();
    }

    /**
     * Returns the arithmetic mean of the result set. avg() is an alias for this method.
     *
     * @param meter the meter of the mean
     * @return the mean value.
     */
    public final double mean(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic mean = new Mean();
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return mean.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Computes the square sum of the elements.
     *
     * @param meter the meter of the mean
     * @return the square sum.
     */
    public final double squareSum(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic sqrSum = new SumOfSquares();
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return sqrSum.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Computes the standard deviation.
     *
     * @param meter the meter of the mean
     * @return the standard deviation
     */
    public final double getStandardDeviation(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic stdDev = new StandardDeviation();
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return stdDev.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Computes the sum over all data items.
     *
     * @param meter the meter of the mean
     * @return the sum of all runs.
     */
    public final double sum(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic sum = new Sum();
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return sum.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Computes the minimum.
     *
     * @param meter the meter of the mean
     * @return the minimum result value.
     */
    public final double min(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic min = new Min();
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return min.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Computes the confidence 05 interval-factor. This value has to be combined with the mean to get the
     * confidence-interval.
     *
     * @param meter the meter for the 05-confidence interval factor
     * @return the 99% confidence
     */
    public final double getConf05(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic conf05 = new Percentile(5.0);
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return conf05.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);

    }

    /**
     * Computes the confidence 95 interval-factor. This value has to be combined with the mean to get the
     * confidence-interval.
     *
     * @param meter the meter for the 95-confidence interval factor
     * @return the 95% confidence
     */
    public final double getConf95(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic conf95 = new Percentile(95.0);
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return conf95.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Computes the maximum.
     *
     * @param meter the meter of the mean
     * @return the maximum result value.
     */
    public final double max(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        final AbstractUnivariateStatistic max = new Max();
        final CollectionDoubleCollection doubleColl = new CollectionDoubleCollection(this.meterResults.get(meter));
        return max.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
    }

    /**
     * Returning the number of results for one specific meter.
     *
     * @param meter to get the number of results
     * @return the number of results of one meter
     */
    public final int getNumberOfResult(final AbstractMeter meter) {
        checkIfMeterExists(meter);
        return meterResults.get(meter).size();
    }

    /**
     * Getter for the related element where this container corresponds to.
     *
     * @return the relatedElement
     */
    public final Object getRelatedElement() {
        return relatedElement;
    }

    /**
     * Adding a data to a meter.
     *
     * @param meter the related meter
     * @param data  the data to be added
     */
    final void addData(final AbstractMeter meter, final double data) {
        checkIfMeterExists(meter);
        meterResults.get(meter).add(data);
    }

    /**
     * Checking method if meter is registered, otherwise inserting a suitable data structure.
     *
     * @param meter to be checked
     */
    private void checkIfMeterExists(final AbstractMeter meter) {
        if (!meterResults.containsKey(meter)) {
            meterResults.put(meter, new LinkedList<Double>());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return getElementName() + "\nmeters: " + getRegisteredMeters() + "\nresults: " + meterResults;
    }

}
src/main/java/org/perfidix/element/BenchmarkMethod.java
public final class BenchmarkMethod {

	/**
	 * Method to be benched.
	 */
	private transient final Method methodToBench;

	/**
	 * Getting dataprovider method.
	 */
	private transient Method dataProvider;

	/**
	 * Constructor, with a definite method to bench. The method has to be
	 * checked with {@link BenchmarkMethod#isBenchmarkable(Method)} first,
	 * otherwise an IllegalArgumentException could arise.
	 *
	 * @param paramMethod
	 *            method to be benched (eventually)
	 * @throws PerfidixMethodCheckException
	 *             if method is not benchmarkable
	 */
	public BenchmarkMethod(final Method paramMethod)
			throws PerfidixMethodCheckException {
		methodToBench = paramMethod;
		setDataProvider(findDataProvider());
	}

	/**
	 * Getting the number of runs corresponding to a given method. The method
	 * MUST be a benchmarkable method, otherwise an IllegalStateException
	 * exception arises. The number of runs of an annotated method is more
	 * powerful than the number of runs as denoted by the benchclass annotation.
	 *
	 * @param meth
	 *            to be checked
	 * @return the number of runs of this benchmarkable-method
	 */
	public static int getNumberOfAnnotatedRuns(final Method meth) {
		if (!isBenchmarkable(meth)) {
			throw new IllegalArgumentException("Method " + meth
					+ " must be a benchmarkable method.");
		}
		final Bench benchAnno = meth.getAnnotation(Bench.class);
		final BenchClass benchClassAnno = meth.getDeclaringClass()
				.getAnnotation(BenchClass.class);
		int returnVal;
		if (benchAnno == null) {
			returnVal = benchClassAnno.runs();
		} else {
			returnVal = benchAnno.runs();
			// use runs from @BenchClass if none is set on method (issue #4)
			if ((returnVal == Bench.NONE_RUN) && (benchClassAnno != null)) {
				returnVal = benchClassAnno.runs();
			}
		}
		return returnVal;
	}

	/**
	 * This class finds any method with a given annotation. The method is
	 * allowed to occur only once in the class and should match the requirements
	 * for Perfidix for an execution by reflection.
	 *
	 * @param anno
	 *            of the method to be found
	 * @param clazz
	 *            class to be searched
	 * @return a method annotated by the annotation given. The method occurs
	 *         only once in the class and matched the requirements of
	 *         perfidix-reflective-invocation.
	 * @throws PerfidixMethodCheckException
	 *             if these integrity checks fail
	 */
	public static Method findAndCheckAnyMethodByAnnotation(
			final Class<?> clazz, final Class<? extends Annotation> anno)
			throws PerfidixMethodCheckException {
		// needed variables, one for check for duplicates
		Method anyMethod = null;

		// Scanning all methods
		final Method[] possAnnoMethods = clazz.getDeclaredMethods();
		for (final Method meth : possAnnoMethods) {
			if (meth.getAnnotation(anno) != null) {
				// Check if there are multiple annotated methods, throwing
				// IllegalAccessException otherwise.
				if (anyMethod == null) {
					// Check if method is valid (no param, no returnval,
					// etc.), throwing IllegalAccessException otherwise.
					if (isReflectedExecutable(meth, anno)) {
						anyMethod = meth;
					} else {
						throw new PerfidixMethodCheckException(
								new IllegalAccessException(anno.toString()
										+ "-annotated method " + meth
										+ " is not executable."), meth, anno);
					}
				} else {
					throw new PerfidixMethodCheckException(
							new IllegalAccessException("Please use only one "
									+ anno.toString()
									+ "-annotation in one class."), meth, anno);
				}
			}
		}

		return anyMethod;
	}

	/**
	 * This method should act as a check to guarantee that only specific
	 * Benchmarkables are used for benching.
	 *
	 * @param meth
	 *            method to be checked.
	 * @return true if an instance of this interface is benchmarkable, false
	 *         otherwise.
	 */
	public static boolean isBenchmarkable(final Method meth) {
		boolean returnVal = true;

		// Check if bench-anno is given. For testing purposes against
		// before/after annos
		final Bench benchAnno = meth.getAnnotation(Bench.class);

		// if method is annotated with SkipBench, the method is never
		// benchmarkable.
		final SkipBench skipBenchAnno = meth.getAnnotation(SkipBench.class);
		if (skipBenchAnno != null) {
			returnVal = false;
		}

		// Check if method is defined as beforeClass, beforeFirstRun,
		// beforeEachRun, afterEachRun, afterLastRun, afterClass. A method can
		// either be a before/after class or afterwards be benchmarkable through
		// the BenchClass annotation.
		final BeforeBenchClass beforeClass = meth
				.getAnnotation(BeforeBenchClass.class);
		if (beforeClass != null && benchAnno == null) {
			returnVal = false;
		}

		final BeforeFirstRun beforeFirstRun = meth
				.getAnnotation(BeforeFirstRun.class);
		if (beforeFirstRun != null && benchAnno == null) {
			returnVal = false;
		}

		final BeforeEachRun beforeEachRun = meth
				.getAnnotation(BeforeEachRun.class);
		if (beforeEachRun != null && benchAnno == null) {
			returnVal = false;
		}

		final AfterEachRun afterEachRun = meth
				.getAnnotation(AfterEachRun.class);
		if (afterEachRun != null && benchAnno == null) {
			returnVal = false;
		}

		final AfterLastRun afterLastRun = meth
				.getAnnotation(AfterLastRun.class);
		if (afterLastRun != null && benchAnno == null) {
			returnVal = false;
		}

		final AfterBenchClass afterClass = meth
				.getAnnotation(AfterBenchClass.class);
		if (afterClass != null && benchAnno == null) {
			returnVal = false;
		}

		// if method is not annotated with Bench and class is not annotated with
		// BenchClass, the method is never benchmarkable.
		final BenchClass classBenchAnno = meth.getDeclaringClass()
				.getAnnotation(BenchClass.class);
		if (benchAnno == null && classBenchAnno == null) {
			returnVal = false;
		}

		// check if method is executable for perfidix purposes.
		if (!isReflectedExecutable(meth, Bench.class)) {
			returnVal = false;
		}
		return returnVal;
	}

	/**
	 * Checks if this method is executable via reflection for perfidix purposes.
	 * That means that the method has no parameters (except for , no
	 * return-value, is non-static, is public and throws no exceptions.
	 *
	 * @param meth
	 *            method to be checked
	 * @param anno
	 *            anno for method to be check, necessary since different
	 *            attributes are possible depending on the anno
	 * @return true if method matches requirements.
	 */
	public static boolean isReflectedExecutable(final Method meth,
			final Class<? extends Annotation> anno) {
		boolean returnVal = true;
		// Check if DataProvider is valid if set.
		if (anno.equals(DataProvider.class)
				&& !meth.getReturnType().isAssignableFrom(Object[][].class)) {
			returnVal = false;
		}
		// for all other methods, the return type must be void
		if (!anno.equals(DataProvider.class)
				&& !meth.getGenericReturnType().equals(Void.TYPE)) {
			returnVal = false;
		}

		// if method is static, the method is not benchmarkable
		if (!(anno.equals(BeforeBenchClass.class))
				&& Modifier.isStatic(meth.getModifiers())) {
			returnVal = false;
		}
		// if method is not public, the method is not benchmarkable
		if (!Modifier.isPublic(meth.getModifiers())) {
			returnVal = false;
		}

		return returnVal;
	}

	/**
	 * Method to find a {@link BeforeFirstRun} annotation. This method should be
	 * invoked for all methods. The corresponding class is searched after
	 * suitable methods and checks for integrity are made. If there are multiple
	 * {@link BeforeFirstRun} -annotated methods available, an exception is
	 * thrown. If there are designated special {@link BeforeFirstRun} methods as
	 * given in the parameter of the {@link Bench}-annotation, this method is
	 * taken with any further checking of the other methods in the class.
	 *
	 * @return Annotated method with BeforeFirstRun annotation, null of none
	 *         exists
	 * @throws PerfidixMethodCheckException
	 *             if integrity check of class and method fails.
	 * @see BeforeFirstRun
	 * @see Bench
	 */
	public Method[] findBeforeFirstRun() throws PerfidixMethodCheckException {

		Method method = null;

		final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class);
		if (benchAnno != null && !benchAnno.beforeFirstRun().equals("")) {
			List<Method> returnval = new ArrayList<Method>();

			try {
				// variable to instantiate the method by name.
				final Class<?>[] setUpParams = {};

				String[] methods = benchAnno.beforeFirstRun().split(",");
				for (String methodString : methods) {
					// getting the method by name
					method = getMethodToBench()
							.getDeclaringClass()
							.getDeclaredMethod(methodString.trim(), setUpParams);

					if (isReflectedExecutable(method, BeforeFirstRun.class)) {
						returnval.add(method);
					} else {
						throw new PerfidixMethodCheckException(
								new IllegalAccessException(
										"Failed to execute BeforeFirstRun-annotated method "
												+ method), method,
								BeforeFirstRun.class);
					}
				}
				return returnval.toArray(new Method[returnval.size()]);

			} catch (final SecurityException e) {
				throw new PerfidixMethodCheckException(e, method,
						BeforeFirstRun.class);
			} catch (final NoSuchMethodException e) {
				throw new PerfidixMethodCheckException(e, method,
						BeforeFirstRun.class);
			}
		}

		// if there was no name, a scan over the class occurs, otherwise the
		// designated method is checked.
		else {
			Method meth = findAndCheckAnyMethodByAnnotation(getMethodToBench()
					.getDeclaringClass(), BeforeFirstRun.class);
			if (meth == null) {
				return new Method[0];
			} else {
				return new Method[] { meth };
			}
		}

	}

	/**
	 * Method to find a {@link BeforeEachRun} annotation. This method should be
	 * invoked for all methods. The corresponding class is searched after
	 * suitable methods and checks for integrity are made. If there are multiple
	 * {@link BeforeEachRun} -annotated methods available, an exception is
	 * thrown. If there are designated special {@link BeforeEachRun} methods as
	 * given in the parameter of the {@link Bench}-annotation, this method is
	 * taken with any further checking of the other methods in the class.
	 *
	 * @return Annotated method with BeforeEachRun annotation, null of none
	 *         exists
	 * @throws PerfidixMethodCheckException
	 *             if integrity check of class and method fails.
	 * @see BeforeEachRun
	 * @see Bench
	 */
	public Method[] findBeforeEachRun() throws PerfidixMethodCheckException {

		Method method = null;

		final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class);
		if (benchAnno != null && !benchAnno.beforeEachRun().equals("")) {
			final List<Method> returnval = new ArrayList<>();
			try {

				String[] methods = benchAnno.beforeEachRun().split(",");
				for (String methodString : methods) {

					// getting the method by name
					method = getMethodToBench().getDeclaringClass()
							.getDeclaredMethod(methodString.trim());
					if (isReflectedExecutable(method, BeforeEachRun.class)) {
						returnval.add(method);
					} else {
						throw new PerfidixMethodCheckException(
								new IllegalAccessException(
										"Failed to execute BeforeEachRun-annotated method "
												+ method), method,
								BeforeEachRun.class);
					}
				}
				return returnval.toArray(new Method[returnval.size()]);

			} catch (SecurityException e) {
				throw new PerfidixMethodCheckException(e, method,
						BeforeEachRun.class);
			} catch (NoSuchMethodException e) {
				throw new PerfidixMethodCheckException(e, method,
						BeforeEachRun.class);
			}
		} else {

			// if there was no name, a scan over the class occurs, otherwise the
			// designated method is checked.
			Method meth = findAndCheckAnyMethodByAnnotation(getMethodToBench()
					.getDeclaringClass(), BeforeEachRun.class);
			if (meth == null) {
				return new Method[0];
			} else {
				return new Method[] { meth };
			}

		}
	}

	/**
	 * Method to find a {@link AfterEachRun} annotation. This method should be
	 * invoked for all methods. The corresponding class is searched after
	 * suitable methods and checks for integrity are made. If there are multiple
	 * {@link AfterEachRun} -annotated methods available, an exception is
	 * thrown. If there are designated special {@link AfterEachRun} methods as
	 * given in the parameter of the {@link Bench}-annotation, this method is
	 * taken with any further checking of the other methods in the class.
	 *
	 * @return Annotated method with AfterEachRun annotation, null of none
	 *         exists
	 * @throws PerfidixMethodCheckException
	 *             if integrity check of class and method fails.
	 * @see AfterEachRun
	 * @see Bench
	 */
	public Method[] findAfterEachRun() throws PerfidixMethodCheckException {

		Method method = null;

		final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class);
		if (benchAnno != null && !benchAnno.afterEachRun().equals("")) {
			List<Method> returnval = new ArrayList<Method>();
			try {

				String[] methods = benchAnno.afterEachRun().split(",");
				for (String methodString : methods) {

					// getting the method by name
					method = getMethodToBench().getDeclaringClass()
							.getDeclaredMethod(methodString.trim());
					if (isReflectedExecutable(method, AfterEachRun.class)) {
						returnval.add(method);
					} else {
						throw new PerfidixMethodCheckException(
								new IllegalAccessException(
										"AfterEachRun-annotated method "
												+ method
												+ " is not executable."),
								method, AfterEachRun.class);
					}
				}
				return returnval.toArray(new Method[returnval.size()]);
			} catch (SecurityException e) {
				throw new PerfidixMethodCheckException(e, method,
						AfterEachRun.class);
			} catch (NoSuchMethodException e) {
				throw new PerfidixMethodCheckException(e, method,
						AfterEachRun.class);
			}
		} else {
			// if there was no name, a scan over the class occurs, otherwise the
			// designated method is checked.
			Method meth = findAndCheckAnyMethodByAnnotation(getMethodToBench()
					.getDeclaringClass(), AfterEachRun.class);
			if (meth == null) {
				return new Method[0];
			} else {
				return new Method[] { meth };
			}

		}
	}

	/**
	 * Method to find a {@link AfterLastRun} annotation. This method should be
	 * invoked for all methods. The corresponding class is searched after
	 * suitable methods and checks for integrity are made. If there are multiple
	 * {@link AfterLastRun} -annotated methods available, an exception is
	 * thrown. If there are designated special {@link AfterLastRun} methods as
	 * given in the parameter of the {@link Bench}-annotation, this method is
	 * taken with any further checking of the other methods in the class.
	 *
	 * @return Annotated method with AfterLastRun annotation, null of none
	 *         exists
	 * @throws PerfidixMethodCheckException
	 *             if integrity check of class and method fails.
	 * @see AfterLastRun
	 * @see Bench
	 */
	public Method[] findAfterLastRun() throws PerfidixMethodCheckException {

		Method method = null;

		final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class);
		if (benchAnno != null && !benchAnno.afterLastRun().equals("")) {
			List<Method> returnval = new ArrayList<Method>();
			try {
				// variable to instantiate the method by name.
				final Class<?>[] setUpParams = {};

				String[] methods = benchAnno.afterLastRun().split(",");
				for (String methodString : methods) {
					// getting the method by name
					method = getMethodToBench()
							.getDeclaringClass()
							.getDeclaredMethod(methodString.trim(), setUpParams);

					if (isReflectedExecutable(method, AfterLastRun.class)) {
						returnval.add(method);
					} else {
						throw new PerfidixMethodCheckException(
								new IllegalAccessException(
										"AfterLastRun-annotated method "
												+ method
												+ " is not executable."),
								method, AfterLastRun.class);
					}
				}
				return returnval.toArray(new Method[returnval.size()]);
			} catch (final SecurityException e) {
				throw new PerfidixMethodCheckException(e, method,
						AfterLastRun.class);
			} catch (final NoSuchMethodException e) {
				throw new PerfidixMethodCheckException(e, method,
						AfterLastRun.class);
			}
		} else {
			// if there was no name, a scan over the class occurs, otherwise the
			// designated method is checked.
			Method meth = findAndCheckAnyMethodByAnnotation(getMethodToBench()
					.getDeclaringClass(), AfterLastRun.class);
			if (meth == null) {
				return new Method[0];
			} else {
				return new Method[] { meth };
			}
		}
	}

	/**
	 * This method checks whether a method uses a data provider for dynamic
	 * input
	 *
	 * @return true if method is parameterized, false otherwise
	 * @throws PerfidixMethodCheckException
	 */
	private Method findDataProvider() throws PerfidixMethodCheckException {

		final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class);
		Method dataProvider = null;
		if (benchAnno != null && !benchAnno.dataProvider().equals("")) {
			try {
				// Getting the String name for the dataProvider
				final String dataProviderIdentifier = benchAnno.dataProvider();
				// Check if there is a Dataprovider with the name as identifier
				for (final Method eachMeth : getMethodToBench()
						.getDeclaringClass().getMethods()) {
					DataProvider anno = eachMeth
							.getAnnotation(DataProvider.class);
					if (anno != null
							&& anno.name().equals(dataProviderIdentifier)) {
						if (dataProvider == null) {
							dataProvider = eachMeth;
						} else {
							throw new PerfidixMethodCheckException(
									new RuntimeException(
											"Only one Dataprovider allowed, but found "
													+ dataProvider + " and "
													+ eachMeth), eachMeth,
									DataProvider.class);
						}
					}
				}
				// if not, try to find a method with the name
				if (dataProvider == null) {
					dataProvider = getMethodToBench().getDeclaringClass()
							.getDeclaredMethod(dataProviderIdentifier);
				}

				// perform the checks same as testng: two dimensional array for
				// return val, parameter is mapping of
				// class, array of instances.
				// checking return types of dataprovider method
				final Class<?> returnType = dataProvider.getReturnType();
				// final Class<?>[] parameters = meth.getParameterTypes();
				if (Object[][].class.isAssignableFrom(returnType)) {
					// checking input types of bench method against the return
					// types of the parameter
					// Class<Object[][]> castedReturnType = (Class<Object[][]>)
					// returnType;
					// TODO implement check
				}
			} catch (NoSuchMethodException | SecurityException e) {
				// no data provider method, will be returned as false anyhow
			}
		}
		return dataProvider;
	}

	/**
	 * Simple getter for encapsulated method.
	 *
	 * @return the methodToBench
	 */
	public Method getMethodToBench() {
		return methodToBench;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		if (methodToBench == null) {
			result = prime * result;
		} else {
			result = prime * result + methodToBench.hashCode();
		}

		return result;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals(final Object obj) {
		return obj.hashCode() == this.hashCode();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {
		return methodToBench.getName();
	}

	/**
	 * This method returns the fully qualified name consisting of its own name
	 * and its class name
	 *
	 * @return the {@link String} name von the bench method consisting of fully
	 *         qualified name of its class and its own name
	 */
	public String getMethodWithClassName() {
		return methodToBench.getDeclaringClass().getName() + "."
				+ methodToBench.getName();
	}

	public Method getDataProvider() {
		return dataProvider;
	}

	void setDataProvider(Method dataProvider) {
		this.dataProvider = dataProvider;
	}

}
src/main/java/org/perfidix/result/MethodResult.java
public final class MethodResult extends AbstractResult {

    /**
     * Simple Constructor.
     *
     * @param meth , the method related to these results
     */
    public MethodResult(final BenchmarkMethod meth) {
        super(meth);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getElementName() {
        return ((BenchmarkMethod) getRelatedElement()).getMethodToBench().getName();
    }

}
src/main/java/org/perfidix/exceptions/PerfidixMethodInvocationException.java
public final class PerfidixMethodInvocationException extends AbstractPerfidixMethodException {

    /**
     * serializable id.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Constructor.
     *
     * @param paramExec       encapsulated exception
     * @param paramMeth       the method where the error occured
     * @param paramAnnotation the related annotation of the method
     */
    public PerfidixMethodInvocationException(final Throwable paramExec, final Method paramMeth, final Class<? extends Annotation> paramAnnotation) {
        super(paramExec, paramMeth, paramAnnotation);
    }

    /**
     * Constructor.
     *
     * @param paramExec       encapsulated exception
     * @param paramAnnotation the related annotation of the method
     */
    public PerfidixMethodInvocationException(final Throwable paramExec, final Class<? extends Annotation> paramAnnotation) {
        this(paramExec, null, paramAnnotation);
    }

}
src/main/java/org/perfidix/result/BenchmarkResult.java
public final class BenchmarkResult extends AbstractResultContainer<ClassResult> {

    /**
     * All occured exceptions.
     */
    private transient final Set<AbstractPerfidixMethodException> exceptions;

    /**
     * Outputs for listeners.
     */
    private transient final AbstractOutput[] outputs;

    /**
     * Constructor.
     *
     * @param paramOutputs {@link AbstractOutput} instances for listener
     */
    public BenchmarkResult(final AbstractOutput... paramOutputs) {
        super(null);
        this.exceptions = new HashSet<AbstractPerfidixMethodException>();
        outputs = paramOutputs;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getElementName() {
        return "Benchmark";
    }

    /**
     * Adding a dataset to a given meter and adapting the underlaying result model.
     *
     * @param meth  where the result is corresponding to
     * @param meter where the result is corresponding to
     * @param data  the data itself
     */
    public void addData(final BenchmarkMethod meth, final AbstractMeter meter, final double data) {

        final Class<?> clazz = meth.getMethodToBench().getDeclaringClass();
        if (!elements.containsKey(clazz)) {
            elements.put(clazz, new ClassResult(clazz));
        }

        final ClassResult clazzResult = elements.get(clazz);

        if (!clazzResult.elements.containsKey(meth)) {
            clazzResult.elements.put(meth, new MethodResult(meth));
        }

        final MethodResult methodResult = clazzResult.elements.get(meth);
        methodResult.addData(meter, data);
        clazzResult.addData(meter, data);
        this.addData(meter, data);

        for (final AbstractOutput output : outputs) {
            output.listenToResultSet(meth, meter, data);
        }

    }

    /**
     * Adding an exception to this result.
     *
     * @param exec the exception stored to this result
     */
    public void addException(final AbstractPerfidixMethodException exec) {
        this.getExceptions().add(exec);
        for (final AbstractOutput output : outputs) {
            output.listenToException(exec);
        }
    }

    /**
     * Getter for member exceptions.
     *
     * @return the exceptions
     */
    public Set<AbstractPerfidixMethodException> getExceptions() {
        return exceptions;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return super.toString() + "\nexceptions: " + getExceptions();
    }

}
src/main/java/org/perfidix/exceptions/AbstractPerfidixMethodException.java
public abstract class AbstractPerfidixMethodException extends Exception {
    /**
     * Serial because of serializable.
     */
    private static final long serialVersionUID = 5251116501564408317L;

    /**
     * Encapsulated Exception.
     */
    private transient final Throwable exec;

    /**
     * Related method.
     */
    private transient final Method meth;

    /**
     * Related annotation to this method.
     */
    private transient final Class<? extends Annotation> relatedAnno;

    /**
     * Simple Constructor.
     *
     * @param paramExec       the exception to be hold in this container.
     * @param paramMeth       the related method to the exception.
     * @param paramAnnotation the related annotation to this method
     */
    AbstractPerfidixMethodException(final Throwable paramExec, final Method paramMeth, final Class<? extends Annotation> paramAnnotation) {
        super();
        this.exec = paramExec;
        this.meth = paramMeth;
        this.relatedAnno = paramAnnotation;
    }

    /**
     * Getter for the related {@link Method}.
     *
     * @return the method for this exception.
     */
    public final Method getMethod() {
        return meth;
    }

    /**
     * Getter for the encapsulated {@link Exception}.
     *
     * @return the exec which is hold in this container.
     */
    public final Throwable getExec() {
        return exec;
    }

    /**
     * Getter for annotation.
     *
     * @return the related annotation for this errored method
     */
    public final Class<? extends Annotation> getRelatedAnno() {
        return relatedAnno;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int hashCode() {
        final int prime = 31;
        int result = 1;
        if (exec == null) {
            result = prime * result;
        } else {
            result = prime * result + exec.hashCode();
        }
        if (meth == null) {
            result = prime * result;
        } else {
            result = prime * result + meth.hashCode();
        }
        if (relatedAnno == null) {
            result = prime * result;
        } else {
            result = prime * result + relatedAnno.hashCode();
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean equals(final Object obj) {
        boolean returnVal = true;
        if (this == obj) {
            returnVal = true;
        }
        if (obj == null) {
            returnVal = false;
        }
        if (getClass() != obj.getClass()) {
            returnVal = false;
        }
        final AbstractPerfidixMethodException other = (AbstractPerfidixMethodException) obj;
        if (exec == null) {
            if (other.exec != null) {
                returnVal = false;
            }
        } else {
            if (!exec.equals(other.exec)) {
                returnVal = false;
            }
        }
        if (meth == null) {
            if (other.meth != null) {
                returnVal = false;
            }
        } else {
            if (!meth.equals(other.meth)) {
                returnVal = false;
            }
        }
        if (relatedAnno == null) {
            if (other.relatedAnno != null) {
                returnVal = false;
            }
        } else {
            if (!relatedAnno.equals(other.relatedAnno)) {
                returnVal = false;
            }
        }
        return returnVal;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        return this.getClass().getSimpleName() + ":" + this.exec.getClass().getSimpleName() + ":" + this.relatedAnno.getClass().getSimpleName() + ":" + this.meth.getName();
    }

}
src/main/java/org/perfidix/result/ClassResult.java
public final class ClassResult extends AbstractResultContainer<MethodResult> {

    /**
     * Constructor.
     *
     * @param paramClass class of these results
     */
    public ClassResult(final Class<?> paramClass) {
        super(paramClass);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getElementName() {
        return ((Class<?>) getRelatedElement()).getSimpleName();
    }
}
src/main/java/org/perfidix/ouput/asciitable/NiceTable.java
public final class NiceTable {

	/**
	 * Container for all rows.
	 */
	private transient final List<AbstractTabularComponent> rows;

	/**
	 * Storing the length of chars in the different columns.
	 */
	private transient final int[] columnLengths;

	/**
	 * An array holding the orientations of columns.
	 */
	private transient final Alignment[] orientations;

	/**
	 * Constructor. needs the number of columns to show.
	 *
	 * @param numberOfColumns
	 *            the number of columns to display.
	 */
	public NiceTable(final int numberOfColumns) {

		columnLengths = new int[numberOfColumns];
		orientations = new Alignment[numberOfColumns];
		rows = new ArrayList<AbstractTabularComponent>();
	}

	/**
	 * Adds a header.
	 *
	 * @param title
	 *            the text to display within the header
	 */
	public void addHeader(final String title) {
		addHeader(title, '=', Alignment.Left);
	}

	/**
	 * Adds a header row to the table. can be used to give a table some title.
	 * 
	 * <pre>
	 *  addHeader(&quot;hello&quot;,'.',NiceTable.LEFT)
	 *  would produce a row like
	 *  ... hello ..........................
	 *   {rows in here.}
	 * </pre>
	 *
	 * @param title
	 *            the string to display as a header
	 * @param mark
	 *            the mark to use for the rest of the column
	 * @param orientation
	 *            the orientation of the header column.
	 */
	public void addHeader(final String title, final char mark,
			final Alignment orientation) {
		final Header header = new Header(title, mark, orientation, this);
		rows.add(header);
	}

	/**
	 * Adds a string row. checks that the strings added do not contain newlines,
	 * because if so, it has to split them in order to make them fit the row.
	 *
	 * @param data
	 *            the array of data.
	 */
	public void addRow(final String[] data) {
		if (anyStringContainsNewLine(data)) {
			final String[][] theMatrix = Util.createMatrix(data);
			for (int i = 0; i < theMatrix.length; i++) {
				addRow(theMatrix[i]);
			}
		} else {
			final Row myRow = new Row(this, data);
			rows.add(myRow);
		}

	}

	/**
	 * allows the addition of lines. think of it as a horizontal rule in a
	 * table.
	 *
	 * @param fill
	 *            any character with which to draw the line.
	 */
	public void addLine(final char fill) {
		rows.add(new DynamicLine(fill, this));
	}

	/**
	 * the main method doing the work. draws everyting.
	 *
	 * @return the formatted table.
	 */
	@Override
	public String toString() {

		final StringBuilder builder = new StringBuilder();

		for (int i = 0; i < rows.size(); i++) {
			final AbstractTabularComponent myObj = rows.get(i);
			builder.append(myObj.draw());
		}
		return builder.toString();
	}

	/**
	 * Returns the global column width at index columnIndex.
	 *
	 * @param columnIndex
	 *            the index of the column for which to fetch the width.
	 * @return the width (in number of chars) for the column index.
	 */
	int getColumnWidth(final int columnIndex) {

		return columnLengths[columnIndex];
	}

	/**
	 * Performs an update on the column lengths.
	 *
	 * @param index
	 *            the index of the column
	 * @param newSize
	 *            the new size of the column
	 */
	void updateColumnWidth(final int index, final int newSize) {
		columnLengths[index] = Math.max(columnLengths[index], newSize);
	}

	/**
	 * Returns the actual number of columns this table has got.
	 *
	 * @return the number of columns the table may contain.
	 */
	private int numColumns() {
		return this.columnLengths.length;
	}

	/**
	 * Returns the orientation of a column.
	 *
	 * @param columnIndex
	 *            integer
	 * @return Alignment for the column
	 */
	Alignment getOrientation(final int columnIndex) {

		return orientations[columnIndex];
	}

	/**
	 * Returns the row width.
	 *
	 * @return int the width of the row
	 */
	private int getRowWidth() {
		int returnVal = 1;
		if (rows.size() < 1) {
			returnVal = 0;
		}
		for (int i = 0; i < rows.size(); i++) {
			if (rows.get(i) instanceof Row) {
				returnVal = ((Row) rows.get(i)).getRowWidth();
			}
		}
		return returnVal;
	}

	/**
	 * Returns the total width of the table.
	 *
	 * @return int the width of the table
	 */
	int getTotalWidth() {
		return this.getRowWidth() + 3 * numColumns() + 1;
	}

	/**
	 * Tests whether any string contains a newline symbol.
	 *
	 * @param data
	 *            the array to check.
	 * @return whether any of the strings contains a newline symbol.
	 */
	private boolean anyStringContainsNewLine(final String[] data) {
		boolean returnVal = false;
		for (int i = 0; i < data.length; i++) {
			if (Util.containsNewlines(data[i])) {
				returnVal = true;
			}
		}
		return returnVal;
	}

}
src/main/java/org/perfidix/ouput/asciitable/AbstractTabularComponent.java
public enum Alignment {
    /**
     * Left alignement.
     */
    Left,
    /**
     * Right alignement.
     */
    Right,
    /**
     * Center alignement.
     */
    Center
}


Question: import java.io.PrintStream;
import java.lang.reflect.Method;
import org.perfidix.element.BenchmarkMethod;
import org.perfidix.exceptions.AbstractPerfidixMethodException;
import org.perfidix.exceptions.PerfidixMethodInvocationException;
import org.perfidix.meter.AbstractMeter;
import org.perfidix.ouput.asciitable.AbstractTabularComponent.Alignment;
import org.perfidix.ouput.asciitable.NiceTable;
import org.perfidix.result.AbstractResult;
import org.perfidix.result.BenchmarkResult;
import org.perfidix.result.ClassResult;
import org.perfidix.result.MethodResult;
/**
 * Copyright (c) 2012, University of Konstanz, Distributed Systems Group All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 * following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or other materials provided with the
 * distribution. * Neither the name of the University of Konstanz nor the names of its contributors may be used to
 * endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.perfidix.ouput;





/**
 * Summary output using the {@link NiceTable} to format. Just giving an overview of statistical analysis over the
 * results.
 *
 * @author Sebastian Graf, University of Konstanz
 */
public final class TabularSummaryOutput extends AbstractOutput {

    /**
     * Print stream where the result should end.
     */
    private transient final PrintStream out;

    /**
     * Constructor for piping the result to elsewhere.
     *
     * @param paramOut an {@link PrintStream} to pipe to.
     */
    public TabularSummaryOutput(final PrintStream paramOut) {
        super();
        out = paramOut;
    }

    /**
     * Constructor, just giving out on the {@link System#out}.
     */
    public TabularSummaryOutput() {
        this(System.out);
    }

    /**
     * {@inheritDoc}
     */
    @Override
Answer:     public void visitBenchmark(final BenchmarkResult benchRes) {