package org.jbehave.scenario.steps;

import java.lang.reflect.Method;
import java.util.ArrayList;

import org.jbehave.scenario.annotations.Given;
import org.jbehave.scenario.annotations.Then;
import org.jbehave.scenario.annotations.When;
import org.jbehave.scenario.parser.StepPatternBuilder;

/**
 * <p>
 * Extend this class to provide the definition of steps that match the scenario
 * you want to run.
 * </p>
 * <p>
 * You can define the methods that should be run when each step is performed by
 * annotating them with @Given, @When or @Then, and providing a value for each
 * annotation that matches the step. By default, the match is performed using a
 * '$' prefix to pick up parameters.
 * </p>
 * <p>
 * For instance, you could define a method as: <code lang="java">
 * 
 * @When(&quot; I log in as $username with password: $password&quot;) public
 *                void logIn(String username, String password) { //... } </code>
 *                and this would match the step:
 *                <code>When I log in as Liz with password: Pa55word</code>
 *                <p>
 *                When the step is perfomed, the parameters in the scenario
 *                definition will be passed to the class, so in this case the
 *                effect will be <code>mySteps.logIn("Liz", "Pa55word");</code>
 *                </p>
 *                <p>
 *                ParameterConverters can be used to convert parameters from any
 *                String format to another class. Custom converters can be
 *                provided here in addition to the defaults.
 *                </p>
 */
public class Steps {

    private final StepPatternBuilder patternBuilder;
    private final StepMonitor stepMonitor;
    private final ParameterConverters parameterConverters;
    private final String[] startingWords;

    /**
     * Creates Steps with default configuration
     */
    public Steps() {
        this(new StepsConfiguration());
    }

    /**
     * Creates Steps with all default configuration except for custom starting
     * keywords
     * 
     * @param startingWords the words with which we expect steps in the
     *            scenarios to start
     */
    public Steps(String... startingWords) {
        this(new StepsConfiguration(startingWords));
    }

    /**
     * Creates Steps with all custom dependencies
     * 
     * @param configuration the StepsConfiguration
     */
    public Steps(StepsConfiguration configuration) {
        this.patternBuilder = configuration.getPatternBuilder();
        this.stepMonitor = configuration.getMonitor();
        this.parameterConverters = configuration.getParameterConverters();
        this.startingWords = configuration.getStartingWords();
    }

    /**
     * @return all the steps that can be performed by this class
     */
    public CandidateStep[] getSteps() {
        ArrayList<CandidateStep> steps = new ArrayList<CandidateStep>();
        for (Method method : this.getClass().getMethods()) {
            if (method.isAnnotationPresent(Given.class)) {
                createCandidateStep(steps, method, method.getAnnotation(Given.class).value());
            }
            if (method.isAnnotationPresent(When.class)) {
                createCandidateStep(steps, method, method.getAnnotation(When.class).value());
            }
            if (method.isAnnotationPresent(Then.class)) {
                createCandidateStep(steps, method, method.getAnnotation(Then.class).value());
            }
        }
        return steps.toArray(new CandidateStep[steps.size()]);
    }

    private void createCandidateStep(ArrayList<CandidateStep> steps, Method method, String stepAsString) {
        steps.add(new CandidateStep(stepAsString, method, this, patternBuilder, stepMonitor, parameterConverters,
                startingWords));
    }
}

@@ -90,16 +90,39 @@
 rayList;
+%0Aimport java.util.List;
 %0A%0Aimport
@@ -257,63 +257,8 @@
 hen;
-%0Aimport org.jbehave.scenario.parser.StepPatternBuilder;
 %0A%0A/*
@@ -719,16 +719,29 @@
 hod as: 
+%0A * %3Cpre%3E%0A * 
 %3Ccode la
@@ -750,19 +750,16 @@
 =%22java%22%3E
-%0A *
  %0A * @Wh
@@ -765,15 +765,9 @@
 hen(
-&quot; 
+%22
 I lo
@@ -812,40 +812,27 @@
 word
-&quot;) public%0A *               
+%22) %3Cbr/%3E %0A * public
  voi
@@ -883,16 +883,20 @@
 //... %7D 
+%0A * 
 %3C/code%3E%0A
@@ -898,30 +898,25 @@
 ode%3E%0A * 
-              
+%3C/pre%3E%0A *
  and thi
@@ -946,29 +946,17 @@
 %0A * 
-               %3Ccode%3E
+%3Cpre%3E%0A * 
 When
@@ -999,56 +999,33 @@
 word
-%3C/code%3E%0A *                %3Cp%3E%0A *                
+%0A * %3C/pre%3E%0A * %3C/p%3E%0A * %3Cp%3E
 When
@@ -1080,31 +1080,16 @@
 nario%0A *
-               
  definit
@@ -1143,31 +1143,16 @@
 e the%0A *
-               
  effect 
@@ -1162,15 +1162,21 @@
 l be
- %3Ccode%3E
+%0A * %3Cpre%3E%0A * 
 mySt
@@ -1189,314 +1189,211 @@
 gIn(
-%22Liz%22, %22Pa55word%22);%3C/code%3E%0A *                %3C/p%3E%0A *                %3Cp%3E%0A *                ParameterConverters can be used to convert parameters from any%0A *                String format to another class. Custom converters can be%0A *                provided here in addition to the default
+&quot;Liz&quot;, &quot;Pa55word&quot;);%0A * %3C/pre%3E%0A * %3C/p%3E%0A * %3Cp%3E%0A * StepsConfiguration can be used to provide customization to the defaults configuration%0A * elements, eg custom parameters converter
 s.
+ 
 %0A *
-               
  %3C/p
@@ -1446,181 +1446,36 @@
 Step
-PatternBuilder patternBuilder;%0A    private final StepMonitor stepMonitor;%0A    private final ParameterConverters parameterConverters;%0A    private final String%5B%5D startingWords
+sConfiguration configuration
 ;%0A%0A 
@@ -2132,251 +2132,37 @@
 his.
-patternBuilder = configuration.getPatternBuilder();%0A        this.stepMonitor = configuration.getMonitor();%0A        this.parameterConverters = configuration.getParameterConverters();%0A        this.startingWords = configuration.getStartingWords()
+configuration = configuration
 ;%0A  
@@ -2295,21 +2295,16 @@
         
-Array
 List%3CCan
@@ -3033,21 +3033,16 @@
 ateStep(
-Array
 List%3CCan
@@ -3166,75 +3166,146 @@
 is, 
-patternBuilder, stepMonitor, parameterConverters,%0A                s
+configuration.getPatternBuilder(), configuration%0A                .getMonitor(), configuration.getParameterConverters(), configuration.getS
 tart
@@ -3304,28 +3304,30 @@
 getStartingWords
+()
 ));%0A    %7D%0A%7D%0A

Use configuration as member variable.