diff --git a/src/main/java/com/lmax/simpledsl/api/DslArg.java b/src/main/java/com/lmax/simpledsl/api/DslArg.java
index a3e7d25..6f2e8b0 100644
--- a/src/main/java/com/lmax/simpledsl/api/DslArg.java
+++ b/src/main/java/com/lmax/simpledsl/api/DslArg.java
@@ -37,7 +37,7 @@ public interface DslArg
 
     /**
      * Get a default value for this argument.
-     *
+     * <p>
      * If the argument is required, this method will throw an {@link IllegalArgumentException}.
      *
      * @return the default value for the argument
diff --git a/src/main/java/com/lmax/simpledsl/api/DslValues.java b/src/main/java/com/lmax/simpledsl/api/DslValues.java
index 9f09c1d..a8469da 100644
--- a/src/main/java/com/lmax/simpledsl/api/DslValues.java
+++ b/src/main/java/com/lmax/simpledsl/api/DslValues.java
@@ -22,6 +22,9 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -276,6 +279,34 @@ default String valueAsParam(final String name)
         return value != null ? name + ": " + value : null;
     }
 
+    /**
+     * Retrieve the value supplied for a parameter formatted as a parameter with the given name.
+     * For example, if the parameter {@literal user} was given the value {@literal jenny}, then
+     * {@code valueAsParamNamed("user", "person")} would return {@code person: jenny}.
+     * <p>
+     * This is useful when reusing DSL methods to build higher level functions. e.g.
+     *
+     * <pre>{@code
+     *   public void createUserAndLogin(String... args) {
+     *     DslParams params = new DslParams(args,
+     *                                      new RequiredParam("user"),
+     *                                      new RequiredParam("accountType"));
+     *     generateRandomUser(params.valueAsParamNamed("user", "rememberUserAs"));
+     *     login(params.valueAsParam("user"), "password: password");
+     *   }
+     * }</pre>
+     *
+     * @param oldParamName the name of the parameter.
+     * @param newParamName the new name of the parameter.
+     * @return the value supplied for that parameter, formatted as a parameter ready to pass on to another method that uses Simple-DSL.
+     * @throws IllegalArgumentException if {@code name} does not match the name of a supported parameter or if the parameter supports multiple values.
+     */
+    default String valueAsParamNamed(final String oldParamName, final String newParamName)
+    {
+        final String value = value(oldParamName);
+        return value != null ? newParamName + ": " + value : null;
+    }
+
     /**
      * Retrieve the values supplied for a parameter as a {@link List}. Returns an empty list if the parameter is optional and a value has not been supplied.
      *
@@ -305,7 +336,7 @@ default <T> List<T> valuesAsListOf(final String name, final Function<String, T>
     /**
      * Retrieve the values supplied for a parameter as an {@link Optional} {@link List}.
      * <p>
-     * Returns an empty Optional if the parameter is optional and a value has not been supplied.
+     * Returns an {@link Optional#empty() empty Optional} if the parameter is optional and a value has not been supplied.
      * <p>
      * In most cases {@link #valuesAsList} is the more suitable method.
      * This variant is useful if there is an important difference between a parameter being set to an empty list vs not being supplied.
@@ -331,6 +362,48 @@ default Optional<List<String>> valuesAsOptional(final String name)
                 .filter(list -> !list.isEmpty());
     }
 
+    /**
+     * Retrieve the values supplied for a parameter as an {@link OptionalInt}.
+     * <p>
+     * Returns an {@link OptionalInt#empty() empty Optional} if the parameter is optional and a value has not been supplied.
+     *
+     * @param name the name of the parameter.
+     * @return the value of the parameter, or empty
+     * @throws IllegalArgumentException if {@code name} does not match the name of a supported parameter.
+     */
+    default OptionalInt valuesAsOptionalInt(final String name)
+    {
+        return hasValue(name) ? OptionalInt.of(valueAsInt(name)) : OptionalInt.empty();
+    }
+
+    /**
+     * Retrieve the values supplied for a parameter as an {@link OptionalLong}.
+     * <p>
+     * Returns an {@link OptionalLong#empty() empty Optional} if the parameter is optional and a value has not been supplied.
+     *
+     * @param name the name of the parameter.
+     * @return the value of the parameter, or empty
+     * @throws IllegalArgumentException if {@code name} does not match the name of a supported parameter.
+     */
+    default OptionalLong valuesAsOptionalLong(final String name)
+    {
+        return hasValue(name) ? OptionalLong.of(valueAsLong(name)) : OptionalLong.empty();
+    }
+
+    /**
+     * Retrieve the values supplied for a parameter as an {@link OptionalDouble}.
+     * <p>
+     * Returns an {@link OptionalDouble#empty() empty Optional} if the parameter is optional and a value has not been supplied.
+     *
+     * @param name the name of the parameter.
+     * @return the value of the parameter, or empty
+     * @throws IllegalArgumentException if {@code name} does not match the name of a supported parameter.
+     */
+    default OptionalDouble valuesAsOptionalDouble(final String name)
+    {
+        return hasValue(name) ? OptionalDouble.of(valueAsInt(name)) : OptionalDouble.empty();
+    }
+
     /**
      * Retrieve the values supplied for a parameter as an {@code int} array.
      * <p>
diff --git a/src/main/java/com/lmax/simpledsl/api/SimpleDslArg.java b/src/main/java/com/lmax/simpledsl/api/SimpleDslArg.java
index d953cea..feb19fc 100644
--- a/src/main/java/com/lmax/simpledsl/api/SimpleDslArg.java
+++ b/src/main/java/com/lmax/simpledsl/api/SimpleDslArg.java
@@ -16,6 +16,8 @@
 
 package com.lmax.simpledsl.api;
 
+import static java.util.Arrays.stream;
+
 /**
  * The root type for all simple args.
  */
@@ -96,7 +98,8 @@ public SimpleDslArg setDefault(final String defaultValue)
 
     /**
      * Restrict the allowed values for this argument to the specified set.
-     * Specifying a value outside of this set will result in an exception being thrown when parsing the arguments.
+     * <p>
+     * Specifying a value outside this set will result in an exception being thrown when parsing the arguments.
      *
      * @param allowedValues the allowable values for this argument.
      * @return this argument
@@ -107,6 +110,35 @@ public SimpleDslArg setAllowedValues(final String... allowedValues)
         return this;
     }
 
+    /**
+     * Restrict the allowed values for this argument to the specified set.
+     * <p>
+     * Specifying a value outside this set will result in an exception being thrown when parsing the arguments.
+     *
+     * @param <T> the type
+     * @param clazz the {@link Class} that provides the allowed values.
+     * @return this argument
+     * @throws IllegalArgumentException if allowed values cannot be determined from the provided class
+     */
+    public <T> SimpleDslArg setAllowedValues(final Class<T> clazz)
+    {
+        if (Boolean.class.isAssignableFrom(clazz))
+        {
+            return setAllowedValues("true", "false");
+        }
+        else if (Enum.class.isAssignableFrom(clazz))
+        {
+            return setAllowedValues(
+                    stream(clazz.getEnumConstants())
+                            .map(constant -> (Enum<?>) constant)
+                            .map(Enum::name)
+                            .toArray(String[]::new)
+            );
+        }
+
+        throw new IllegalArgumentException("Cannot assign allowed values from class " + clazz.getName());
+    }
+
     /**
      * Allow multiple values to be specified for this argument, either as separate arguments or using comma (,) as a delimiter.
      * <p>
diff --git a/src/test/java/com/lmax/simpledsl/internal/DslParamsImplTest.java b/src/test/java/com/lmax/simpledsl/internal/DslParamsImplTest.java
index 3722ac4..02dbe74 100644
--- a/src/test/java/com/lmax/simpledsl/internal/DslParamsImplTest.java
+++ b/src/test/java/com/lmax/simpledsl/internal/DslParamsImplTest.java
@@ -24,6 +24,9 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptyList;
@@ -74,7 +77,7 @@ public void shouldReturnMultipleValues()
 
         final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
 
-        assertArrayEquals(new String[] {"Hello World", "Goodbye, Cruel World"}, params.values("a"));
+        assertArrayEquals(new String[]{"Hello World", "Goodbye, Cruel World"}, params.values("a"));
     }
 
     @Test
@@ -85,7 +88,7 @@ public void shouldReturnMultipleValuesWhenUsingAMappingFunctionToGenericArray()
         final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
 
         assertArrayEquals(
-                new Object[] {TestValues.VALUE_1, TestValues.VALUE_2},
+                new Object[]{TestValues.VALUE_1, TestValues.VALUE_2},
                 params.valuesAs("a", TestValues::valueOf)
         );
     }
@@ -98,7 +101,7 @@ public void shouldReturnMultipleValuesWhenUsingAMappingFunctionToArrayOfSpecific
         final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
 
         assertArrayEquals(
-                new TestValues[] {TestValues.VALUE_1, TestValues.VALUE_2},
+                new TestValues[]{TestValues.VALUE_1, TestValues.VALUE_2},
                 params.valuesAs("a", TestValues.class, TestValues::valueOf)
         );
     }
@@ -111,7 +114,7 @@ public void shouldReturnMultipleValuesAsAnEnum()
         final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
 
         assertArrayEquals(
-                new TestValues[] {TestValues.VALUE_1, TestValues.VALUE_2},
+                new TestValues[]{TestValues.VALUE_1, TestValues.VALUE_2},
                 params.valuesAs("a", TestValues.class)
         );
     }
@@ -244,6 +247,26 @@ public void shouldReturnNullValueAsParamWhenSimpleDslParamNotSpecified()
         assertNull(params.valueAsParam("a"));
     }
 
+    @Test
+    public void shouldReturnValueAsNamedParamForOptionalValueThatWasSpecified()
+    {
+        final SimpleDslParam aParam = new SimpleDslParam("a", singletonList("value"));
+
+        final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
+
+        assertEquals("b: value", params.valueAsParamNamed("a", "b"));
+    }
+
+    @Test
+    public void shouldReturnNullValueAsNamedParamWhenSimpleDslParamNotSpecified()
+    {
+        final SimpleDslParam aParam = new SimpleDslParam("a", emptyList());
+
+        final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
+
+        assertNull(params.valueAsParamNamed("a", "b"));
+    }
+
     @Test
     public void shouldReturnValuesAsIntArray()
     {
@@ -447,6 +470,36 @@ public void shouldReturnEmptyOptionalListWhenNoValuesAreSupplied()
         assertEquals(Optional.empty(), params.valuesAsOptional("a"));
     }
 
+    @Test
+    public void shouldReturnEmptyOptionalIntWhenNoValuesAreSupplied()
+    {
+        final SimpleDslParam aParam = new SimpleDslParam("a", emptyList());
+
+        final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
+
+        assertEquals(OptionalInt.empty(), params.valuesAsOptionalInt("a"));
+    }
+
+    @Test
+    public void shouldReturnEmptyOptionalLongWhenNoValuesAreSupplied()
+    {
+        final SimpleDslParam aParam = new SimpleDslParam("a", emptyList());
+
+        final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
+
+        assertEquals(OptionalLong.empty(), params.valuesAsOptionalLong("a"));
+    }
+
+    @Test
+    public void shouldReturnEmptyOptionalDoubleWhenNoValuesAreSupplied()
+    {
+        final SimpleDslParam aParam = new SimpleDslParam("a", emptyList());
+
+        final DslParams params = new DslParamsImpl(new DslArg[0], Collections.singletonMap("a", aParam));
+
+        assertEquals(OptionalDouble.empty(), params.valuesAsOptionalDouble("a"));
+    }
+
     @Test
     public void shouldReturnOptionalListWhenMultipleParameterValueIsSupplied()
     {
diff --git a/src/test/java/com/lmax/simpledsl/internal/DslParamsParserTest.java b/src/test/java/com/lmax/simpledsl/internal/DslParamsParserTest.java
index 72fbac7..4353656 100644
--- a/src/test/java/com/lmax/simpledsl/internal/DslParamsParserTest.java
+++ b/src/test/java/com/lmax/simpledsl/internal/DslParamsParserTest.java
@@ -626,7 +626,79 @@ public void shouldMatchAllowedValuesCaseInsensitivelyAndReturnValuesUsingTheCase
     }
 
     @Test
-    public void shouldThrowAnExceptionIfRequiredArgeterMissingFromGroup()
+    public void shouldMatchAllowedValuesSpecifiedViaABoolean()
+    {
+        final String[] args = {
+                "thisWorks: true",
+        };
+        final DslArg[] parameters = {
+                new RequiredArg("thisWorks").setAllowedValues(Boolean.class),
+        };
+
+        final DslParamsParser parser = new DslParamsParser();
+
+        final DslParams params = parser.parse(args, parameters);
+
+        assertTrue(params.valueAsBoolean("thisWorks"));
+    }
+
+    @Test
+    public void shouldThrowAnExceptionIfValuesDoesNotMatchAllowedValuesSpecifiedViaABoolean()
+    {
+        final String[] args = {
+                "thisWorks: NO",
+        };
+        final DslArg[] parameters = {
+                new RequiredArg("thisWorks").setAllowedValues(Boolean.class),
+        };
+
+        final DslParamsParser parser = new DslParamsParser();
+
+        final IllegalArgumentException exception = assertThrows(
+                IllegalArgumentException.class,
+                () -> parser.parse(args, parameters));
+
+        assertEquals("thisWorks parameter value 'NO' must be one of: [true, false]", exception.getMessage());
+    }
+
+    @Test
+    public void shouldMatchAllowedValuesSpecifiedViaAnEnum()
+    {
+        final String[] args = {
+                "pet: DRAGON",
+        };
+        final DslArg[] parameters = {
+                new RequiredArg("pet").setAllowedValues(PossiblePets.class),
+        };
+
+        final DslParamsParser parser = new DslParamsParser();
+
+        final DslParams params = parser.parse(args, parameters);
+
+        assertEquals("DRAGON", params.value("pet"));
+    }
+
+    @Test
+    public void shouldThrowAnExceptionIfValuesDoesNotMatchAllowedValuesSpecifiedViaAnEnum()
+    {
+        final String[] args = {
+                "pet: UNICORN",
+        };
+        final DslArg[] parameters = {
+                new RequiredArg("pet").setAllowedValues(PossiblePets.class),
+        };
+
+        final DslParamsParser parser = new DslParamsParser();
+
+        final IllegalArgumentException exception = assertThrows(
+                IllegalArgumentException.class,
+                () -> parser.parse(args, parameters));
+
+        assertEquals("pet parameter value 'UNICORN' must be one of: [COW, SHEEP, GOAT, DRAGON]", exception.getMessage());
+    }
+
+    @Test
+    public void shouldThrowAnExceptionIfRequiredParameterMissingFromGroup()
     {
         final String[] args = {"a: value", "myGroup: Joe", "myGroup: Jenny", "myValue: 2"};
         final DslArg[] params = {
@@ -805,4 +877,12 @@ public void maybeShouldThrowExceptionIfRequiredParametersArePassedOutOfOrder()
 
         assertEquals("Unexpected ambiguous argument 1", exception.getMessage());
     }
+
+    private enum PossiblePets
+    {
+        COW,
+        SHEEP,
+        GOAT,
+        DRAGON
+    }
 }
\ No newline at end of file