diff --git a/metatype/changelog.txt b/metatype/changelog.txt
index af4d409..f6c26b9 100644
--- a/metatype/changelog.txt
+++ b/metatype/changelog.txt
@@ -1,3 +1,11 @@
+Changes from 1.0.6 to 1.0.8
+---------------------------
+
+** Bug
+    * [FELIX-3756] - Optional attributes validated invalid data as correct;
+    * [FELIX-3757] - If an AttributeDefinition did not specify a minimum, maximum or option values, it did not detect missing values;
+    * [FELIX-3758] - AttributeDefinition.validate() did not take non-zero cardinality into consideration.
+
 Changes from 1.0.4 to 1.0.6
 ---------------------------
 
diff --git a/metatype/src/main/java/org/apache/felix/metatype/AD.java b/metatype/src/main/java/org/apache/felix/metatype/AD.java
index a083f68..f2456f2 100644
--- a/metatype/src/main/java/org/apache/felix/metatype/AD.java
+++ b/metatype/src/main/java/org/apache/felix/metatype/AD.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.metatype;
 
-
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -28,7 +27,6 @@
 import org.osgi.service.log.LogService;
 import org.osgi.service.metatype.AttributeDefinition;
 
-
 /**
  * The <code>AD</code> class represents the <code>AD</code> element of the
  * meta type descriptor.
@@ -84,255 +82,221 @@
     private String max;
     private boolean isRequired = true;
 
-
     public String getID()
     {
         return id;
     }
 
-
     public String getName()
     {
         return name;
     }
 
-
     public String getDescription()
     {
         return description;
     }
 
-
     public int getType()
     {
         return type;
     }
 
-
     public int getCardinality()
     {
         return cardinality;
     }
 
-
     public String[] getOptionLabels()
     {
         return optionLabels;
     }
 
-
     public String[] getOptionValues()
     {
         return optionValues;
     }
 
-
     public String[] getDefaultValue()
     {
         return defaultValue;
     }
 
-
     public String getMin()
     {
         return min;
     }
 
-
     public String getMax()
     {
         return max;
     }
 
-
     public boolean isRequired()
     {
         return isRequired;
     }
 
-
     /**
      * Implements validation of the <code>valueString</code> and returns an
-     * indication of the success:
-     * <dl>
-     * <dt><code>null</code>
-     * <dd>If neither a {@link #getMin() minimal value} nor a
-     *      {@link #getMax() maximal value} nor any
-     *      {@link #getOptionValues() optional values} are defined in this
-     *      instance, validation cannot be performed.
-     * <dt>Empty String
-     * <dd>If validation succeeds. This value is also returned if the
-     *      <code>valueString</code> is empty or <code>null</code> or cannot be
-     *      converted into a numeric type.
-     * <dt><b>%</b>message
-     * <dd>If the value falls below the minimum, higher than the maximum or is
-     *      not any of the option values, an explanatory message, which may be
-     *      localized is returned. If any of the minimum, maximum or option
-     *      values is <code>null</code>, the respective value is not checked.
-     * </dl>
+     * indication of the validation result.
      *
-     * @param valueString The string representation of the value to validate.
+     * @param valueString The string representation of the value to validate,
+     *        can be <code>null</code>.
      *
-     * @return As explained above.
+     * @return <code>null</code> if no validation is performed, <tt>""</tt> if
+     *         the value is accepted as valid, or a non-empty string 
+     *         indicating a validation problem was found.
      *
+     * @see ADValidator#validate(AD, String)
      * @see #VALIDATE_GREATER_THAN_MAXIMUM
-     * @see #VALIDATE_LESS_THAN_MINIMUM
      * @see #VALIDATE_NOT_A_VALID_OPTION
+     * @see #VALIDATE_LESS_THAN_MINIMUM
+     * @see #VALIDATE_INVALID_VALUE
+     * @see #VALIDATE_MISSING
      */
-    public String validate( String valueString )
+    public String validate(String valueString)
     {
-    	return ADValidator.validate(this, valueString);
+        return ADValidator.validate(this, valueString);
     }
 
-
     //--------- Setters for setting up this instance --------------------------
 
     /**
      * @param id the id to set
      */
-    public void setID( String id )
+    public void setID(String id)
     {
         this.id = id;
     }
 
-
     /**
      * @param name the name to set
      */
-    public void setName( String name )
+    public void setName(String name)
     {
         this.name = name;
     }
 
-
     /**
      * @param description the description to set
      */
-    public void setDescription( String description )
+    public void setDescription(String description)
     {
         this.description = description;
     }
 
-
     /**
      * @param typeString the type to set
      */
-    public void setType( String typeString )
+    public void setType(String typeString)
     {
-        this.type = toType( typeString );
+        this.type = toType(typeString);
     }
 
-
     /**
      * @param cardinality the cardinality to set
      */
-    public void setCardinality( int cardinality )
+    public void setCardinality(int cardinality)
     {
         this.cardinality = cardinality;
     }
 
-
     /**
      * @param options the options to set
      */
-    public void setOptions( Map options )
+    public void setOptions(Map options)
     {
         optionLabels = new String[options.size()];
         optionValues = new String[options.size()];
         int i = 0;
-        for ( Iterator oi = options.entrySet().iterator(); oi.hasNext(); i++ )
+        for (Iterator oi = options.entrySet().iterator(); oi.hasNext(); i++)
         {
-            Map.Entry entry = ( Map.Entry ) oi.next();
-            optionValues[i] = String.valueOf( entry.getKey() );
-            optionLabels[i] = String.valueOf( entry.getValue() );
+            Map.Entry entry = (Map.Entry) oi.next();
+            optionValues[i] = String.valueOf(entry.getKey());
+            optionLabels[i] = String.valueOf(entry.getValue());
         }
     }
 
-
     /**
      * @param defaultValue the defaultValue to set
      */
-    public void setDefaultValue( String defaultValue )
+    public void setDefaultValue(String defaultValue)
     {
-        this.defaultValue = splitList( defaultValue );
+        this.defaultValue = splitList(defaultValue);
     }
 
-
     /**
      * @param min the min to set
      */
-    public void setMin( String min )
+    public void setMin(String min)
     {
         this.min = min;
     }
 
-
     /**
      * @param max the max to set
      */
-    public void setMax( String max )
+    public void setMax(String max)
     {
         this.max = max;
     }
 
-
     /**
      * @param defaultValue the defaultValue to set
      */
-    public void setDefaultValue( String[] defaultValue )
+    public void setDefaultValue(String[] defaultValue)
     {
-        this.defaultValue = ( String[] ) defaultValue.clone();
+        this.defaultValue = (String[]) defaultValue.clone();
     }
 
-
     /**
      * @param isRequired the isRequired to set
      */
-    public void setRequired( boolean isRequired )
+    public void setRequired(boolean isRequired)
     {
         this.isRequired = isRequired;
     }
 
-
-    public static int toType( String typeString )
+    public static int toType(String typeString)
     {
-        if ( "String".equals( typeString ) )
+        if ("String".equals(typeString))
         {
             return AttributeDefinition.STRING;
         }
-        else if ( "Long".equals( typeString ) )
+        else if ("Long".equals(typeString))
         {
             return AttributeDefinition.LONG;
         }
-        else if ( "Double".equals( typeString ) )
+        else if ("Double".equals(typeString))
         {
             return AttributeDefinition.DOUBLE;
         }
-        else if ( "Float".equals( typeString ) )
+        else if ("Float".equals(typeString))
         {
             return AttributeDefinition.FLOAT;
         }
-        else if ( "Integer".equals( typeString ) )
+        else if ("Integer".equals(typeString))
         {
             return AttributeDefinition.INTEGER;
         }
-        else if ( "Byte".equals( typeString ) )
+        else if ("Byte".equals(typeString))
         {
             return AttributeDefinition.BYTE;
         }
-        else if ( "Char".equals( typeString ) )
+        else if ("Char".equals(typeString))
         {
             return AttributeDefinition.CHARACTER;
         }
-        else if ( "Boolean".equals( typeString ) )
+        else if ("Boolean".equals(typeString))
         {
             return AttributeDefinition.BOOLEAN;
         }
-        else if ( "Short".equals( typeString ) )
+        else if ("Short".equals(typeString))
         {
             return AttributeDefinition.SHORT;
         }
-        else if ( "Password".equals( typeString ) )
+        else if ("Password".equals(typeString))
         {
             return AttributeDefinition.PASSWORD;
         }
@@ -341,90 +305,102 @@
         return AttributeDefinition.STRING;
     }
 
-
-    public static String[] splitList( String listString )
+    public static String[] splitList(String listString)
     {
-		if (listString == null) {
-			return null;
-		} else if (listString.length() == 0) {
-			return new String[] { "" };
-		}
+        if (listString == null)
+        {
+            return null;
+        }
+        else if (listString.length() == 0)
+        {
+            return new String[] { "" };
+        }
 
-		List strings = new ArrayList();
-		StringBuffer sb = new StringBuffer();
+        List strings = new ArrayList();
+        StringBuffer sb = new StringBuffer();
 
-		int length = listString.length();
-		boolean escaped = false;
-		
-		for (int i = 0; i < length; i++) {
-			char ch = listString.charAt(i);
-			if (ch == '\\') {
-				if (!escaped) {
-					escaped = true;
-					continue;
-				}
-			} else if (ch == ',') {
-				if (!escaped) {
-					// unescaped comma, this is a string delimiter...
-					strings.add(sb.toString());
-					sb.setLength(0);
-					continue;
-				}
-			} else if (ch == ' ') {
-				// we should ignore spaces normally, unless they are escaped...
-				if (!escaped) {
-					continue;
-				}
-			} else if (Character.isWhitespace(ch)) {
-				// Other whitespaces are ignored...
-				continue;
-			}
+        int length = listString.length();
+        boolean escaped = false;
 
-			sb.append(ch);
-			escaped = false;
-		}
+        for (int i = 0; i < length; i++)
+        {
+            char ch = listString.charAt(i);
+            if (ch == '\\')
+            {
+                if (!escaped)
+                {
+                    escaped = true;
+                    continue;
+                }
+            }
+            else if (ch == ',')
+            {
+                if (!escaped)
+                {
+                    // unescaped comma, this is a string delimiter...
+                    strings.add(sb.toString());
+                    sb.setLength(0);
+                    continue;
+                }
+            }
+            else if (ch == ' ')
+            {
+                // we should ignore spaces normally, unless they are escaped...
+                if (!escaped)
+                {
+                    continue;
+                }
+            }
+            else if (Character.isWhitespace(ch))
+            {
+                // Other whitespaces are ignored...
+                continue;
+            }
 
-		// Always add the last string, as it contains everything after the last comma...
-		strings.add(sb.toString());
+            sb.append(ch);
+            escaped = false;
+        }
 
-		return (String[]) strings.toArray(new String[strings.size()]);
+        // Always add the last string, as it contains everything after the last comma...
+        strings.add(sb.toString());
+
+        return (String[]) strings.toArray(new String[strings.size()]);
     }
 
-
-    protected Comparable convertToType( final String value )
+    protected Comparable convertToType(final String value)
     {
-        if ( value != null && value.length() > 0 )
+        if (value != null && value.length() > 0)
         {
             try
             {
-                switch ( getType() )
+                switch (getType())
                 {
                     case AttributeDefinition.BOOLEAN:
                         // Boolean is only Comparable starting with Java 5
-                        return new ComparableBoolean( value );
+                        return new ComparableBoolean(value);
                     case AttributeDefinition.CHARACTER:
-                        return new Character( value.charAt( 0 ) );
+                        return new Character(value.charAt(0));
                     case AttributeDefinition.BYTE:
-                        return Byte.valueOf( value );
+                        return Byte.valueOf(value);
                     case AttributeDefinition.SHORT:
-                        return Short.valueOf( value );
+                        return Short.valueOf(value);
                     case AttributeDefinition.INTEGER:
-                        return Integer.valueOf( value );
+                        return Integer.valueOf(value);
                     case AttributeDefinition.LONG:
-                        return Long.valueOf( value );
+                        return Long.valueOf(value);
                     case AttributeDefinition.FLOAT:
-                        return Float.valueOf( value );
+                        return Float.valueOf(value);
                     case AttributeDefinition.DOUBLE:
-                        return Double.valueOf( value );
+                        return Double.valueOf(value);
                     case AttributeDefinition.STRING:
                     case AttributeDefinition.PASSWORD:
                     default:
                         return value;
                 }
             }
-            catch ( NumberFormatException nfe )
+            catch (NumberFormatException nfe)
             {
-                Activator.log( LogService.LOG_INFO, "Cannot convert value '" + value + "'", nfe );
+                Activator.log(LogService.LOG_INFO, "Cannot convert value '" + value + "'", nfe);
             }
         }
 
@@ -435,17 +411,15 @@
     {
         private boolean value;
 
-
-        ComparableBoolean( String boolValue )
+        ComparableBoolean(String boolValue)
         {
-            value = Boolean.valueOf( boolValue ).booleanValue();
+            value = Boolean.valueOf(boolValue).booleanValue();
         }
 
-
-        public int compareTo( Object obj )
+        public int compareTo(Object obj)
         {
-            ComparableBoolean cb = ( ComparableBoolean ) obj;
-            return ( cb.value == value ? 0 : ( value ? 1 : -1 ) );
+            ComparableBoolean cb = (ComparableBoolean) obj;
+            return (cb.value == value ? 0 : (value ? 1 : -1));
         }
     }
 }
diff --git a/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java b/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java
index d82b136..60b35a0 100644
--- a/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java
+++ b/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java
@@ -30,319 +30,407 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-final class ADValidator {
+final class ADValidator
+{
+    /**
+     * Validates a given input string according to the type specified by the given attribute 
+     * definition.
+     * <p>
+     * The validation is done in the following way:
+     * </p>
+     * <ul>
+     * <li>If the input is undefined (ie. <code>null</code>), and the attribute is mandatory, the 
+     * validation fails due to a missing value. If the attribute is optional, the input is 
+     * accepted;</li>
+     * <li>If the input represents a <em>boolean</em> value, it is tested whether it is defined (in
+     * case of non-zero cardinality) and represents either <tt>"true"</tt> or <tt>"false"</tt>. The
+     * minimum and maximum parameters are <b>not</b> used in this validation;</li>
+     * <li>If the input represents a <em>character</em> value, it is tested whether it is defined 
+     * (in case of non-zero cardinality). The character value must be defined within the character 
+     * range specified by the minimum and maximum parameters (if defined);</li>
+     * <li>If the input represents a <em>numeric</em> value, it is tested whether it is defined (in
+     * case of non-zero cardinality). The numeric value must be defined within the numeric range 
+     * specified by the minimum and maximum parameters (if defined);</li>
+     * <li>If the input represents a <em>string</em> or <em>password</em>, it is tested whether it
+     * is defined (in case of non-zero cardinality). The length of the string value must be in the
+     * range specified by the minimum and maximum parameters (if defined).</li>
+     * </ul>
+     * <p>
+     * For all types of attributes, if it defines option values, the input should be present as one
+     * of the defined option values. 
+     * </p>
+     * 
+     * @param ad
+     *            the attribute definition to use in the validation;
+     * @param rawInput
+     *            the raw input value to validate.
+     * @return <code>null</code> if no validation is available, <tt>""</tt> if
+     *         validation was successful, or any other non-empty string in case
+     *         validation fails.
+     */
+    public static String validate(AD ad, String rawInput)
+    {
+        // Handle the case in which the given input is not defined...
+        if (rawInput == null)
+        {
+            if (ad.isRequired())
+            {
+                return AD.VALIDATE_MISSING;
+            }
 
-	/**
-	 * Validates a given input string according to the type specified by the
-	 * given attribute definition.
-	 * 
-	 * @param ad
-	 *            the attribute definition to use in the validation;
-	 * @param rawInput
-	 *            the raw input value to validate.
-	 * @return <code>null</code> if no validation is available, <tt>""</tt> if
-	 *         validation was successful, or any other non-empty string in case
-	 *         validation fails.
-	 */
-	public static String validate(AD ad, String rawInput) {
-		// Handle the case in which the given input is not defined...
-		if (rawInput == null) {
-			if (ad.isRequired()) {
-				return AD.VALIDATE_MISSING;
-			}
+            return ""; // accept null value...
+        }
 
-			return ""; // accept null value...
-		}
+        // Raw input is defined, validate it further
+        String[] input;
+        if (ad.getCardinality() == 0)
+        {
+            input = new String[] { rawInput.trim() };
+        }
+        else
+        {
+            input = AD.splitList(rawInput);
+        }
 
-		// Raw input is defined, validate it further
-		String[] input;
+        int type = ad.getType();
+        switch (type)
+        {
+            case AttributeDefinition.BOOLEAN:
+                return validateBooleanValue(ad, input);
 
-		if (ad.getCardinality() == 0) {
-			input = new String[] { rawInput.trim() };
-		} else {
-			input = AD.splitList(rawInput);
-		}
+            case AttributeDefinition.CHARACTER:
+                return validateCharacterValue(ad, input);
 
-		int type = ad.getType();
-		switch (type) {
-		case AttributeDefinition.BOOLEAN:
-			return validateBooleanValue(ad, input);
+            case AttributeDefinition.BIGDECIMAL:
+            case AttributeDefinition.BIGINTEGER:
+            case AttributeDefinition.BYTE:
+            case AttributeDefinition.DOUBLE:
+            case AttributeDefinition.FLOAT:
+            case AttributeDefinition.INTEGER:
+            case AttributeDefinition.LONG:
+            case AttributeDefinition.SHORT:
+                return validateNumericValue(ad, input);
 
-		case AttributeDefinition.CHARACTER:
-			return validateCharacterValue(ad, input);
+            case AttributeDefinition.PASSWORD:
+            case AttributeDefinition.STRING:
+                return validateString(ad, input);
 
-		case AttributeDefinition.BIGDECIMAL:
-		case AttributeDefinition.BIGINTEGER:
-		case AttributeDefinition.BYTE:
-		case AttributeDefinition.DOUBLE:
-		case AttributeDefinition.FLOAT:
-		case AttributeDefinition.INTEGER:
-		case AttributeDefinition.LONG:
-		case AttributeDefinition.SHORT:
-			return validateNumericValue(ad, input);
+            default:
+                return null; // no validation present...
+        }
+    }
 
-		case AttributeDefinition.PASSWORD:
-		case AttributeDefinition.STRING:
-			return validateString(ad, input);
+    /**
+     * Searches for a given search value in a given array of options.
+     * 
+     * @param searchValue
+     *            the value to search for;
+     * @param optionValues
+     *            the values to search in.
+     * @return <code>null</code> if the given search value is not found in the
+     *         given options, the searched value if found, or <tt>""</tt> if no
+     *         search value or options were given.
+     */
+    private static String findOptionValue(String searchValue, String[] optionValues)
+    {
+        if ((searchValue == null) || (optionValues == null) || (optionValues.length == 0))
+        {
+            // indicates that we've not searched...
+            return "";
+        }
 
-		default:
-			return null; // no validation present...
-		}
-	}
+        for (int i = 0; i < optionValues.length; i++)
+        {
+            if (optionValues[i].equals(searchValue))
+            {
+                return optionValues[i];
+            }
+        }
 
-	/**
-	 * Searches for a given search value in a given array of options.
-	 * 
-	 * @param searchValue
-	 *            the value to search for;
-	 * @param optionValues
-	 *            the values to search in.
-	 * @return <code>null</code> if the given search value is not found in the
-	 *         given options, the searched value if found, or <tt>""</tt> if no
-	 *         search value or options were given.
-	 */
-	private static String findOptionValue(String searchValue, String[] optionValues) {
-		if ((searchValue == null) || (optionValues == null) || (optionValues.length == 0)) {
-			// indicates that we've not searched
-			return "";
-		}
+        return null;
+    }
 
-		for (int i = 0; i < optionValues.length; i++) {
-			if (optionValues[i].equals(searchValue)) {
-				return optionValues[i];
-			}
-		}
+    /**
+     * Parses a given string value into a numeric type.
+     * 
+     * @param type
+     *            the type to parse;
+     * @param value
+     *            the value to parse.
+     * @return a {@link Number} representation of the given value, or
+     *         <code>null</code> if the input was <code>null</code>, empty, or
+     *         not a numeric type.
+     * @throws NumberFormatException
+     *             in case the given value cannot be parsed as numeric value.
+     */
+    private static Comparable parseNumber(int type, String value) throws NumberFormatException
+    {
+        if ((value != null) && (value.length() > 0))
+        {
+            switch (type)
+            {
+                case AttributeDefinition.BIGDECIMAL:
+                    return new BigDecimal(value);
+                case AttributeDefinition.BIGINTEGER:
+                    return new BigInteger(value);
+                case AttributeDefinition.BYTE:
+                    return Byte.valueOf(value);
+                case AttributeDefinition.SHORT:
+                    return Short.valueOf(value);
+                case AttributeDefinition.INTEGER:
+                    return Integer.valueOf(value);
+                case AttributeDefinition.LONG:
+                    return Long.valueOf(value);
+                case AttributeDefinition.FLOAT:
+                    return Float.valueOf(value);
+                case AttributeDefinition.DOUBLE:
+                    return Double.valueOf(value);
+                default:
+                    return null;
+            }
+        }
+        return null;
+    }
 
-		return null;
-	}
+    /**
+     * Parses a given string value as character, allowing <code>null</code>
+     * -values and empty values to be given as input.
+     * 
+     * @param value
+     *            the value to parse as character, can be <code>null</code> or
+     *            an empty value.
+     * @return the character value if, and only if, the given input was non-
+     *         <code>null</code> and a non-empty string.
+     */
+    private static Character parseOptionalChar(String value)
+    {
+        if ((value != null) && (value.length() > 0))
+        {
+            return Character.valueOf(value.charAt(0));
+        }
+        return null;
+    }
 
-	/**
-	 * Parses a given string value into a numeric type.
-	 * 
-	 * @param type
-	 *            the type to parse;
-	 * @param value
-	 *            the value to parse.
-	 * @return a {@link Number} representation of the given value, or
-	 *         <code>null</code> if the input was <code>null</code>, empty, or
-	 *         not a numeric type.
-	 * @throws NumberFormatException
-	 *             in case the given value cannot be parsed as numeric value.
-	 */
-	private static Comparable parseNumber(int type, String value) throws NumberFormatException {
-		if ((value != null) && (value.length() > 0)) {
-			switch (type) {
-			case AttributeDefinition.BIGDECIMAL:
-				return new BigDecimal(value);
-			case AttributeDefinition.BIGINTEGER:
-				return new BigInteger(value);
-			case AttributeDefinition.BYTE:
-				return Byte.valueOf(value);
-			case AttributeDefinition.SHORT:
-				return Short.valueOf(value);
-			case AttributeDefinition.INTEGER:
-				return Integer.valueOf(value);
-			case AttributeDefinition.LONG:
-				return Long.valueOf(value);
-			case AttributeDefinition.FLOAT:
-				return Float.valueOf(value);
-			case AttributeDefinition.DOUBLE:
-				return Double.valueOf(value);
-			default:
-				return null;
-			}
-		}
-		return null;
-	}
+    /**
+     * Parses a given string value as numeric value, allowing 
+     * <code>null</code>-values and invalid numeric values to be given as 
+     * input.
+     * 
+     * @param type the type of number, should only be a numeric type;
+     * @param value
+     *            the value to parse as integer, can be <code>null</code> or a
+     *            non-numeric value.
+     * @return the integer value if, and only if, the given input was non-
+     *         <code>null</code> and a valid integer representation.
+     */
+    private static Comparable parseOptionalNumber(int type, String value)
+    {
+        if (value != null)
+        {
+            try
+            {
+                return parseNumber(type, value);
+            }
+            catch (NumberFormatException e)
+            {
+                // Ignore; invalid value...
+            }
+        }
+        return null;
+    }
 
-	/**
-	 * Parses a given string value as character, allowing <code>null</code>
-	 * -values and empty values to be given as input.
-	 * 
-	 * @param value
-	 *            the value to parse as character, can be <code>null</code> or
-	 *            an empty value.
-	 * @return the character value if, and only if, the given input was non-
-	 *         <code>null</code> and a non-empty string.
-	 */
-	private static Character parseOptionalChar(String value) {
-		if ((value != null) && (value.length() > 0)) {
-			return Character.valueOf(value.charAt(0));
-		}
-		return null;
-	}
+    /**
+     * Validates a given input string as boolean value.
+     * 
+     * @param ad
+     *            the attribute definition to use in the validation;
+     * @param input
+     *            the array with input values to validate.
+     * @return <code>null</code> if no validation is available, <tt>""</tt> if
+     *         validation was successful, or any other non-empty string in case
+     *         validation fails.
+     */
+    private static String validateBooleanValue(AD ad, String[] input)
+    {
+        for (int i = 0; i < input.length; i++)
+        {
+            String value = input[i];
+            int length = (value == null) ? 0 : value.length();
 
-	/**
-	 * Parses a given string value as integer, allowing <code>null</code>-values
-	 * and invalid numeric values to be given as input.
-	 * 
-	 * @param value
-	 *            the value to parse as integer, can be <code>null</code> or a
-	 *            non-numeric value.
-	 * @return the integer value if, and only if, the given input was non-
-	 *         <code>null</code> and a valid integer representation.
-	 */
-	private static Integer parseOptionalInt(String value) {
-		if (value != null) {
-			try {
-				return Integer.valueOf(value);
-			} catch (NumberFormatException e) {
-				// Ignore; invalid value...
-			}
-		}
-		return null;
-	}
+            if ((length == 0) && ad.isRequired())
+            {
+                return AD.VALIDATE_MISSING;
+            }
+            else if (length > 0 && !"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value))
+            {
+                return AD.VALIDATE_INVALID_VALUE;
+            }
+        }
 
-	/**
-	 * Validates a given input string as boolean value.
-	 * 
-	 * @param ad
-	 *            the attribute definition to use in the validation;
-	 * @param input
-	 *            the array with input values to validate.
-	 * @return <code>null</code> if no validation is available, <tt>""</tt> if
-	 *         validation was successful, or any other non-empty string in case
-	 *         validation fails.
-	 */
-	private static String validateBooleanValue(AD ad, String[] input) {
-		for (int i = 0; i < input.length; i++) {
-			int length = input[i].length();
-			if ((length == 0) && ad.isRequired()) {
-				return AD.VALIDATE_MISSING;
-			} else if (length > 0 && !"true".equalsIgnoreCase(input[i]) && !"false".equalsIgnoreCase(input[i])) {
-				return AD.VALIDATE_INVALID_VALUE;
-			}
-		}
+        String[] optionValues = ad.getOptionValues();
+        if ((optionValues != null) && (optionValues.length > 0))
+        {
+            return null; // no validation possible for this type...
+        }
 
-		String[] optionValues = ad.getOptionValues();
-		if (optionValues != null && optionValues.length > 0) {
-			return null; // no validation possible for this type...
-		}
+        return ""; // accept given value...
+    }
 
-		return ""; // accept given value...
-	}
+    /**
+     * Validates a given input string as character value.
+     * 
+     * @param ad
+     *            the attribute definition to use in the validation;
+     * @param input
+     *            the array with input values to validate.
+     * @return <code>null</code> if no validation is available, <tt>""</tt> if
+     *         validation was successful, or any other non-empty string in case
+     *         validation fails.
+     */
+    private static String validateCharacterValue(AD ad, String[] input)
+    {
+        Character min = parseOptionalChar(ad.getMin());
+        Character max = parseOptionalChar(ad.getMax());
+        String[] optionValues = ad.getOptionValues();
 
-	/**
-	 * Validates a given input string as character value.
-	 * 
-	 * @param ad
-	 *            the attribute definition to use in the validation;
-	 * @param input
-	 *            the array with input values to validate.
-	 * @return <code>null</code> if no validation is available, <tt>""</tt> if
-	 *         validation was successful, or any other non-empty string in case
-	 *         validation fails.
-	 */
-	private static String validateCharacterValue(AD ad, String[] input) {
-		Character min = parseOptionalChar(ad.getMin());
-		Character max = parseOptionalChar(ad.getMax());
-		String[] optionValues = ad.getOptionValues();
+        for (int i = 0; i < input.length; i++)
+        {
+            Character ch = null;
 
-		for (int i = 0; i < input.length; i++) {
-			Character ch = null;
-			int length = input[i].length();
-			if (length > 1) {
-				return AD.VALIDATE_GREATER_THAN_MAXIMUM;
-			} else if ((length == 0) && ad.isRequired()) {
-				return AD.VALIDATE_MISSING;
-			} else if (length == 1) {
-				ch = Character.valueOf(input[i].charAt(0));
-				// Check whether the minimum value is adhered for all values...
-				if ((min != null) && (ch.compareTo(min) < 0)) {
-					return AD.VALIDATE_LESS_THAN_MINIMUM;
-				}
-				// Check whether the maximum value is adhered for all values...
-				if ((max != null) && (ch.compareTo(max) > 0)) {
-					return AD.VALIDATE_GREATER_THAN_MAXIMUM;
-				}
-			}
+            int length = (input[i] == null) ? 0 : input[i].length();
+            if (length > 1)
+            {
+                return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+            }
+            else if ((length == 0) && ad.isRequired())
+            {
+                return AD.VALIDATE_MISSING;
+            }
+            else if (length == 1)
+            {
+                ch = Character.valueOf(input[i].charAt(0));
+                // Check whether the minimum value is adhered for all values...
+                if ((min != null) && (ch.compareTo(min) < 0))
+                {
+                    return AD.VALIDATE_LESS_THAN_MINIMUM;
+                }
+                // Check whether the maximum value is adhered for all values...
+                if ((max != null) && (ch.compareTo(max) > 0))
+                {
+                    return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+                }
+            }
 
-			if (findOptionValue(input[i], optionValues) == null) {
-				return AD.VALIDATE_NOT_A_VALID_OPTION;
-			}
-		}
+            if (findOptionValue(input[i], optionValues) == null)
+            {
+                return AD.VALIDATE_NOT_A_VALID_OPTION;
+            }
+        }
 
-		return ""; // accept given value...
-	}
+        return ""; // accept given value...
+    }
 
-	/**
-	 * Validates a given input string as numeric value.
-	 * 
-	 * @param ad
-	 *            the attribute definition to use in the validation;
-	 * @param input
-	 *            the array with input values to validate.
-	 * @return <code>null</code> if no validation is available, <tt>""</tt> if
-	 *         validation was successful, or any other non-empty string in case
-	 *         validation fails.
-	 */
-	private static String validateNumericValue(AD ad, String[] input) {
-		Integer min = parseOptionalInt(ad.getMin());
-		Integer max = parseOptionalInt(ad.getMax());
-		String[] optionValues = ad.getOptionValues();
+    /**
+     * Validates a given input string as numeric value.
+     * 
+     * @param ad
+     *            the attribute definition to use in the validation;
+     * @param input
+     *            the array with input values to validate.
+     * @return <code>null</code> if no validation is available, <tt>""</tt> if
+     *         validation was successful, or any other non-empty string in case
+     *         validation fails.
+     */
+    private static String validateNumericValue(AD ad, String[] input)
+    {
+        Comparable min = parseOptionalNumber(ad.getType(), ad.getMin());
+        Comparable max = parseOptionalNumber(ad.getType(), ad.getMax());
+        String[] optionValues = ad.getOptionValues();
 
-		for (int i = 0; i < input.length; i++) {
-			Comparable value = null;
-			try {
-				value = parseNumber(ad.getType(), input[i]);
-			} catch (NumberFormatException e) {
-				return AD.VALIDATE_INVALID_VALUE;
-			}
+        for (int i = 0; i < input.length; i++)
+        {
+            Comparable value = null;
+            try
+            {
+                value = parseNumber(ad.getType(), input[i]);
+            }
+            catch (NumberFormatException e)
+            {
+                return AD.VALIDATE_INVALID_VALUE;
+            }
 
-			if ((value == null) && ad.isRequired()) {
-				// Possible if the cardinality != 0 and input was something like
-				// "0,,1"...
-				return AD.VALIDATE_MISSING;
-			}
-			// Check whether the minimum value is adhered for all values...
-			if ((min != null) && (value != null) && (value.compareTo(min) < 0)) {
-				return AD.VALIDATE_LESS_THAN_MINIMUM;
-			}
-			// Check whether the maximum value is adhered for all values...
-			if ((max != null) && (value != null) && (value.compareTo(max) > 0)) {
-				return AD.VALIDATE_GREATER_THAN_MAXIMUM;
-			}
+            if ((value == null) && ad.isRequired())
+            {
+                // Possible if the cardinality != 0 and input was something like
+                // "0,,1"...
+                return AD.VALIDATE_MISSING;
+            }
+            // Check whether the minimum value is adhered for all values...
+            if ((min != null) && (value != null) && (value.compareTo(min) < 0))
+            {
+                return AD.VALIDATE_LESS_THAN_MINIMUM;
+            }
+            // Check whether the maximum value is adhered for all values...
+            if ((max != null) && (value != null) && (value.compareTo(max) > 0))
+            {
+                return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+            }
 
-			if (findOptionValue(input[i], optionValues) == null) {
-				return AD.VALIDATE_NOT_A_VALID_OPTION;
-			}
-		}
+            if (findOptionValue(input[i], optionValues) == null)
+            {
+                return AD.VALIDATE_NOT_A_VALID_OPTION;
+            }
+        }
 
-		return ""; // accept given value...
-	}
+        return ""; // accept given value...
+    }
 
-	/**
-	 * Validates a given input string as string (or password).
-	 * 
-	 * @param ad
-	 *            the attribute definition to use in the validation;
-	 * @param input
-	 *            the array with input values to validate.
-	 * @return <code>null</code> if no validation is available, <tt>""</tt> if
-	 *         validation was successful, or any other non-empty string in case
-	 *         validation fails.
-	 */
-	private static String validateString(AD ad, String[] input) {
-		Integer min = parseOptionalInt(ad.getMin());
-		Integer max = parseOptionalInt(ad.getMax());
-		String[] optionValues = ad.getOptionValues();
+    /**
+     * Validates a given input string as string (or password).
+     * 
+     * @param ad
+     *            the attribute definition to use in the validation;
+     * @param input
+     *            the array with input values to validate.
+     * @return <code>null</code> if no validation is available, <tt>""</tt> if
+     *         validation was successful, or any other non-empty string in case
+     *         validation fails.
+     */
+    private static String validateString(AD ad, String[] input)
+    {
+        // The length() method of a string yields an Integer, so the maximum string length is 2^31-1...
+        Integer min = (Integer) parseOptionalNumber(AttributeDefinition.INTEGER, ad.getMin());
+        Integer max = (Integer) parseOptionalNumber(AttributeDefinition.INTEGER, ad.getMax());
+        String[] optionValues = ad.getOptionValues();
 
-		for (int i = 0; i < input.length; i++) {
-			int length = input[i].length();
-			// Check whether the minimum length is adhered for all values...
-			if ((min != null) && (length < min.intValue())) {
-				return AD.VALIDATE_LESS_THAN_MINIMUM;
-			}
-			// Check whether the maximum length is adhered for all values...
-			if ((max != null) && (length > max.intValue())) {
-				return AD.VALIDATE_GREATER_THAN_MAXIMUM;
-			}
+        for (int i = 0; i < input.length; i++)
+        {
+            String value = input[i];
+            int length = (value == null) ? 0 : value.length();
 
-			if (findOptionValue(input[i], optionValues) == null) {
-				return AD.VALIDATE_NOT_A_VALID_OPTION;
-			}
-		}
+            if (ad.isRequired() && ((value == null) || (length == 0)))
+            {
+                // Possible if the cardinality != 0 and input was something like
+                // "0,,1"...
+                return AD.VALIDATE_MISSING;
+            }
+            // Check whether the minimum length is adhered for all values...
+            if ((min != null) && (length < min.intValue()))
+            {
+                return AD.VALIDATE_LESS_THAN_MINIMUM;
+            }
+            // Check whether the maximum length is adhered for all values...
+            if ((max != null) && (length > max.intValue()))
+            {
+                return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+            }
 
-		return ""; // accept given value...
-	}
+            if (findOptionValue(value, optionValues) == null)
+            {
+                return AD.VALIDATE_NOT_A_VALID_OPTION;
+            }
+        }
+
+        return ""; // accept given value...
+    }
 }
diff --git a/metatype/src/test/java/org/apache/felix/metatype/ADTest.java b/metatype/src/test/java/org/apache/felix/metatype/ADTest.java
index 065f0c9..00cbc27 100644
--- a/metatype/src/test/java/org/apache/felix/metatype/ADTest.java
+++ b/metatype/src/test/java/org/apache/felix/metatype/ADTest.java
@@ -18,12 +18,10 @@
  */
 package org.apache.felix.metatype;
 
-
 import junit.framework.TestCase;
 
 import org.osgi.service.metatype.AttributeDefinition;
 
-
 /**
  * The <code>ADTest</code> class tests the static helper methods of the
  * {@link AD} class.
@@ -35,59 +33,54 @@
 
     private static final String BLANK = "     \r\n   \t";
 
-
     public void testNull()
     {
         String listString = null;
-        String[] list = AD.splitList( listString );
-        assertNull( list );
+        String[] list = AD.splitList(listString);
+        assertNull(list);
     }
 
-
     public void testEmpty()
     {
         String listString = "";
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 1, list.length );
-        assertEquals( listString, list[0] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(1, list.length);
+        assertEquals(listString, list[0]);
     }
 
-
     public void testSingle()
     {
         String value0 = "value";
         String listString = value0;
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 1, list.length );
-        assertEquals( value0, list[0] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(1, list.length);
+        assertEquals(value0, list[0]);
     }
 
-
     public void testTwo()
     {
         String value0 = "value0";
         String value1 = "value1";
         String listString = value0 + "," + value1;
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 2, list.length );
-        assertEquals( value0, list[0] );
-        assertEquals( value1, list[1] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(2, list.length);
+        assertEquals(value0, list[0]);
+        assertEquals(value1, list[1]);
     }
 
-
     public void testEmptySecond()
     {
         String value0 = "value0";
         String value1 = "";
         String listString = value0 + ",";
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 2, list.length );
-        assertEquals( value0, list[0] );
-        assertEquals( value1, list[1] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(2, list.length);
+        assertEquals(value0, list[0]);
+        assertEquals(value1, list[1]);
     }
 
     public void testSpacedSecond()
@@ -95,38 +88,35 @@
         String value0 = "value0";
         String value1 = "";
         String listString = value0 + ", ";
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 2, list.length );
-        assertEquals( value0, list[0] );
-        assertEquals( value1, list[1] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(2, list.length);
+        assertEquals(value0, list[0]);
+        assertEquals(value1, list[1]);
     }
 
-
     public void testSingleBlanks()
     {
         String value0 = "value";
         String listString = BLANK + value0 + BLANK;
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 1, list.length );
-        assertEquals( value0, list[0] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(1, list.length);
+        assertEquals(value0, list[0]);
     }
 
-
     public void testTwoBlanks()
     {
         String value0 = "value0";
         String value1 = "value1";
         String listString = BLANK + value0 + BLANK + "," + BLANK + value1 + BLANK;
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 2, list.length );
-        assertEquals( value0, list[0] );
-        assertEquals( value1, list[1] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(2, list.length);
+        assertEquals(value0, list[0]);
+        assertEquals(value1, list[1]);
     }
 
-
     public void testStandardSample()
     {
         String value0 = "a,b";
@@ -134,66 +124,68 @@
         String value2 = " c\\";
         String value3 = "d";
         String listString = "a\\,b,b\\,c,\\ c\\\\,d";
-        String[] list = AD.splitList( listString );
-        assertNotNull( list );
-        assertEquals( 4, list.length );
-        assertEquals( value0, list[0] );
-        assertEquals( value1, list[1] );
-        assertEquals( value2, list[2] );
-        assertEquals( value3, list[3] );
+        String[] list = AD.splitList(listString);
+        assertNotNull(list);
+        assertEquals(4, list.length);
+        assertEquals(value0, list[0]);
+        assertEquals(value1, list[1]);
+        assertEquals(value2, list[2]);
+        assertEquals(value3, list[3]);
     }
 
-
     public void testToTypeString()
     {
-        assertEquals( AttributeDefinition.STRING, AD.toType( "String" ) );
-        assertEquals( AttributeDefinition.LONG, AD.toType( "Long" ) );
-        assertEquals( AttributeDefinition.DOUBLE, AD.toType( "Double" ) );
-        assertEquals( AttributeDefinition.FLOAT, AD.toType( "Float" ) );
-        assertEquals( AttributeDefinition.INTEGER, AD.toType( "Integer" ) );
-        assertEquals( AttributeDefinition.BYTE, AD.toType( "Byte" ) );
-        assertEquals( AttributeDefinition.CHARACTER, AD.toType( "Char" ) );
-        assertEquals( AttributeDefinition.BOOLEAN, AD.toType( "Boolean" ) );
-        assertEquals( AttributeDefinition.SHORT, AD.toType( "Short" ) );
-        assertEquals( AttributeDefinition.PASSWORD, AD.toType( "Password" ) );
-        assertEquals( AttributeDefinition.STRING, AD.toType( "JohnDoe" ) );
+        assertEquals(AttributeDefinition.STRING, AD.toType("String"));
+        assertEquals(AttributeDefinition.LONG, AD.toType("Long"));
+        assertEquals(AttributeDefinition.DOUBLE, AD.toType("Double"));
+        assertEquals(AttributeDefinition.FLOAT, AD.toType("Float"));
+        assertEquals(AttributeDefinition.INTEGER, AD.toType("Integer"));
+        assertEquals(AttributeDefinition.BYTE, AD.toType("Byte"));
+        assertEquals(AttributeDefinition.CHARACTER, AD.toType("Char"));
+        assertEquals(AttributeDefinition.BOOLEAN, AD.toType("Boolean"));
+        assertEquals(AttributeDefinition.SHORT, AD.toType("Short"));
+        assertEquals(AttributeDefinition.PASSWORD, AD.toType("Password"));
+        assertEquals(AttributeDefinition.STRING, AD.toType("JohnDoe"));
     }
-    
+
     /**
      * FELIX-3757: if an AD has only its 'required' property set, but no 
      * min/max or option values defined, the validation still should detect 
      * empty values. 
      */
-    public void testValidateRequiredValueWithMinimalOptions() {
-    	AD ad = new AD();
-    	ad.setType("Integer");
-    	ad.setRequired(true);
+    public void testValidateRequiredValueWithMinimalOptions()
+    {
+        AD ad = new AD();
+        ad.setType("Integer");
+        ad.setRequired(true);
 
-    	assertEquals(AD.VALIDATE_MISSING, ad.validate(null));
+        assertEquals(AD.VALIDATE_MISSING, ad.validate(null));
     }
-    
+
     /**
      * FELIX-3756: if an AD is optional, but its validate method is called
      * with invalid data, the value is regarded missing.
      */
-    public void testValidateOptionalValueWithInvalidData() {
-    	AD ad = new AD();
-    	ad.setType("Integer");
-    	ad.setRequired(false);
-    	
-    	assertEquals(AD.VALIDATE_INVALID_VALUE, ad.validate("abc"));
+    public void testValidateOptionalValueWithInvalidData()
+    {
+        AD ad = new AD();
+        ad.setType("Integer");
+        ad.setRequired(false);
+
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ad.validate("abc"));
     }
-    
+
     /**
      * FELIX-3758: if an AD has a cardinality != 0, the validation method
      * cannot handle a comma-separated input.
      */
-    public void testValidateValueWithMultiValueCardinality() {
-    	AD ad = new AD();
-    	ad.setType("Integer");
-    	ad.setCardinality(2);
-    	ad.setRequired(true);
-    	
-    	assertEquals("", ad.validate("1,2"));
+    public void testValidateValueWithMultiValueCardinality()
+    {
+        AD ad = new AD();
+        ad.setType("Integer");
+        ad.setCardinality(2);
+        ad.setRequired(true);
+
+        assertEquals("", ad.validate("1,2"));
     }
 }
diff --git a/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java b/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java
index 8640629..33c02c3 100644
--- a/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java
+++ b/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java
@@ -30,240 +30,348 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ADValidatorTest extends TestCase {
+public class ADValidatorTest extends TestCase
+{
+    /**
+     * Tests the validation of boolean is only done minimally.
+     */
+    public void testValidateBoolean()
+    {
+        AD ad = new AD();
+        ad.setType("Boolean");
+        ad.setRequired(false);
 
-	/**
-	 * Tests the validation of boolean is only done minimally.
-	 */
-	public void testValidateBoolean() {
-		AD ad = new AD();
-		ad.setType("Boolean");
-		ad.setRequired(false);
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        // adhere minimal value
+        assertEquals("", ADValidator.validate(ad, "true"));
+        // adhere maximal value
+        assertEquals("", ADValidator.validate(ad, "false"));
+        // not a valid value
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "foobar"));
 
-		// optional value
-		assertEquals("", ADValidator.validate(ad, null));
-		// adhere minimal value
-		assertEquals("", ADValidator.validate(ad, "true"));
-		// adhere maximal value
-		assertEquals("", ADValidator.validate(ad, "false"));
-		// not a valid value
-		assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "foobar"));
+        ad.setCardinality(3); // up to three values are allowed...
 
-		ad.setCardinality(3); // up to three values are allowed...
-		
-		// mandatory value
-		assertEquals("", ADValidator.validate(ad, null));
-		// 2nd value is missing
-		assertEquals("", ADValidator.validate(ad, "true,,false"));
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        // 2nd value is missing, but that's ok...
+        assertEquals("", ADValidator.validate(ad, "true,,false"));
 
-		ad.setRequired(true);
+        ad.setRequired(true);
 
-		// mandatory value
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
-		// 2nd value is missing
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "false,,true"));
-		assertEquals("", ADValidator.validate(ad, "false, true, false"));
+        // mandatory value
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+        // 2nd value is missing
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "false,,true"));
+        // correct values
+        assertEquals("", ADValidator.validate(ad, "false, true, false"));
+        // correct values
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "false, yessir, false"));
 
-		ad.setOptions(Collections.singletonMap("true", "Yes!"));
+        ad.setOptions(Collections.singletonMap("true", "Yes!"));
 
-		assertEquals(null, ADValidator.validate(ad, "false, true, false"));
-	}
+        assertEquals(null, ADValidator.validate(ad, "false, true, false"));
+    }
 
-	/**
-	 * Tests the validation of characters with only limited set of options.
-	 */
-	public void testValidateCharacterOptionValues() {
-		AD ad = new AD();
-		ad.setType("Char");
-		ad.setRequired(false);
+    /**
+     * Tests the validation of bytes works and uses the correct minimum and maximum values.
+     */
+    public void testValidateByte()
+    {
+        AD ad = new AD();
+        ad.setType("Byte");
+        ad.setRequired(false);
 
-		// optional value
-		assertEquals("", ADValidator.validate(ad, null));
-		// option too long
-		assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "ab"));
-		// adhere first option value
-		assertEquals("", ADValidator.validate(ad, "b"));
-		// adhere last option value
-		assertEquals("", ADValidator.validate(ad, "e"));
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        assertEquals("", ADValidator.validate(ad, ""));
 
-		ad.setCardinality(3); // up to three values are allowed...
+        ad.setRequired(true);
 
-		// mandatory value
-		assertEquals("", ADValidator.validate(ad, ""));
-		// 2nd value is missing
-		assertEquals("", ADValidator.validate(ad, "b,,c"));
+        // mandatory value
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, ""));
+        // value too small
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "-129"));
+        // value too small
+        assertEquals("", ADValidator.validate(ad, "-128"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "0"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "127"));
+        // value is invalid
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "128"));
 
-		ad.setRequired(true);
+        ad.setMin("0");
+        ad.setMax("128"); // !!! this is an invalid value for maximum, this means that we cannot do this validation...
 
-		// mandatory value
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
-		// 2nd value is missing
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "b,,c"));
-		// adhere minimal values
-		assertEquals("", ADValidator.validate(ad, "b, c, d"));
-		// adhere maximal values
-		assertEquals("", ADValidator.validate(ad, "c, d, e"));
+        // value too small
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "-1"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "0"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "127"));
+        // value is invalid
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "128"));
+    }
 
-		Map options = new HashMap();
-		options.put("b", "B");
-		options.put("c", "C");
-		options.put("d", "D");
-		options.put("e", "E");
+    /**
+     * Tests the validation of characters with only limited set of options.
+     */
+    public void testValidateCharacter()
+    {
+        AD ad = new AD();
+        ad.setType("Char");
+        ad.setRequired(false);
 
-		ad.setOptions(options);
-		// no option given
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, ""));
-		// invalid option
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "a"));
-		// too great
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "f"));
-		// 2nd value is too less
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "b,a,c"));
-		// 3rd value is too great
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "d, e, f"));
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        // option too long
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "ab"));
+        // adhere first option value
+        assertEquals("", ADValidator.validate(ad, "b"));
+        // adhere last option value
+        assertEquals("", ADValidator.validate(ad, "e"));
 
-		ad.setMin("b");
-		ad.setMax("c");
-		ad.setOptions(Collections.emptyMap());
+        ad.setCardinality(3); // up to three values are allowed...
 
-		// adhere minimal values
-		assertEquals("", ADValidator.validate(ad, "b, c, b"));
-		// d is too great
-		assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "b, c, d"));
-		// a is too less
-		assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "a, b, c"));
-	}
+        // mandatory value
+        assertEquals("", ADValidator.validate(ad, ""));
+        // 2nd value is missing
+        assertEquals("", ADValidator.validate(ad, "b,,c"));
 
-	/**
-	 * Tests the validation of characters with only limited set of options.
-	 */
-	public void testValidateDoubleOptionValues() {
-		Map options = new HashMap();
-		options.put("1.1", "B");
-		options.put("2.2", "C");
-		options.put("3.3", "D");
-		options.put("4.4", "E");
+        ad.setRequired(true);
 
-		AD ad = new AD();
-		ad.setType("Double");
-		ad.setOptions(options);
-		ad.setRequired(false);
+        // mandatory value
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+        // 2nd value is missing
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "b,,c"));
+        // adhere minimal values
+        assertEquals("", ADValidator.validate(ad, "b, c, d"));
+        // adhere maximal values
+        assertEquals("", ADValidator.validate(ad, "c, d, e"));
 
-		// optional value
-		assertEquals("", ADValidator.validate(ad, null));
-		// invalid option
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.0"));
-		// adhere first option value
-		assertEquals("", ADValidator.validate(ad, "1.1"));
-		// adhere last option value
-		assertEquals("", ADValidator.validate(ad, "4.4"));
-		// too great
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "4.5"));
+        Map options = new HashMap();
+        options.put("b", "B");
+        options.put("c", "C");
+        options.put("d", "D");
+        options.put("e", "E");
 
-		ad.setCardinality(3); // up to three values are allowed...
-		ad.setRequired(true);
+        ad.setOptions(options);
+        // no option given
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, ""));
+        // invalid option
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "a"));
+        // too great
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "f"));
+        // 2nd value is too less
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "b,a,c"));
+        // 3rd value is too great
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "d, e, f"));
 
-		// mandatory value
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
-		// 2nd value is too less
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.1,1.0,2.2"));
-		// adhere minimal values
-		assertEquals("", ADValidator.validate(ad, "1.1, 2.2, 3.3"));
-		// adhere maximal values
-		assertEquals("", ADValidator.validate(ad, "2.2, 3.3, 4.4"));
-		// 3rd value is too great
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "3.3, 4.4, 5.5"));
-	}
+        ad.setMin("b");
+        ad.setMax("c");
+        ad.setOptions(Collections.emptyMap());
 
-	/**
-	 * Tests the validation of integers is based on the minimum and maximum values.
-	 */
-	public void testValidateInteger() {
-		AD ad = new AD();
-		ad.setType("Integer");
-		ad.setMin("3"); // only values greater than 2
-		ad.setMax("6"); // only values less than 7
-		ad.setRequired(false);
+        // adhere minimal values
+        assertEquals("", ADValidator.validate(ad, "b, c, b"));
+        // d is too great
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "b, c, d"));
+        // a is too small
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "a, b, c"));
+    }
 
-		// optional value
-		assertEquals("", ADValidator.validate(ad, null));
-		// too less
-		assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "2"));
-		// adhere minimal value
-		assertEquals("", ADValidator.validate(ad, "3"));
-		// adhere maximal value
-		assertEquals("", ADValidator.validate(ad, "6"));
-		// too great
-		assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "7"));
+    /**
+     * Tests the validation of double value works as expected.
+     */
+    public void testValidateDouble()
+    {
+        AD ad = new AD();
+        ad.setType("Double");
+        ad.setRequired(false);
 
-		ad.setCardinality(3); // up to three values are allowed...
-		
-		// mandatory value
-		assertEquals("", ADValidator.validate(ad, null));
-		// 2nd value is missing
-		assertEquals("", ADValidator.validate(ad, "3,,3"));
+        ad.setMin("-123.45");
+        ad.setMax("+123.45");
 
-		ad.setRequired(true);
+        // Value is too small...
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "-123.4501"));
+        // Value is within range...
+        assertEquals("", ADValidator.validate(ad, "-123.45000"));
+        // Value is within range...
+        assertEquals("", ADValidator.validate(ad, "123.45000"));
+        // Value is too great...
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "123.4501"));
 
-		// mandatory value
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
-		// 2nd value is missing
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "3,,3"));
-		// 2nd value is invalid
-		assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "3,a,3"));
-		// 2nd value is too less
-		assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "3,2,3"));
-		// adhere minimal values
-		assertEquals("", ADValidator.validate(ad, "3, 4, 5"));
-		// adhere maximal values
-		assertEquals("", ADValidator.validate(ad, "6, 5, 4"));
-		// 3rd value is too great
-		assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "5, 6, 7"));
-	}
+        Map options = new HashMap();
+        options.put("1.1", "B");
+        options.put("2.2", "C");
+        options.put("3.3", "D");
+        options.put("4.4", "E");
 
-	/**
-	 * Tests the validation of strings is based on the minimum and maximum lengths.
-	 */
-	public void testValidateString() {
-		AD ad = new AD();
-		ad.setType("String");
-		ad.setRequired(false);
+        ad.setOptions(options);
 
-		// optional value
-		assertEquals("", ADValidator.validate(ad, null));
-		// any length of input is accepted
-		assertEquals("", ADValidator.validate(ad, "1234567890"));
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        // invalid option
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.0"));
+        // adhere first option value
+        assertEquals("", ADValidator.validate(ad, "1.1"));
+        // adhere last option value
+        assertEquals("", ADValidator.validate(ad, "4.4"));
+        // too great
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "4.5"));
 
-		ad.setMin("3"); // minimal length == 3
-		ad.setMax("6"); // maximum length == 6
+        ad.setCardinality(3); // up to three values are allowed...
+        ad.setRequired(true);
 
-		// too short
-		assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "12"));
-		// adhere minimum length
-		assertEquals("", ADValidator.validate(ad, "123"));
-		// adhere maximum length
-		assertEquals("", ADValidator.validate(ad, "12356"));
-		// too long
-		assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "1234567"));
+        // mandatory value
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+        // 2nd value is too less
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.1,1.0,2.2"));
+        // adhere minimal values
+        assertEquals("", ADValidator.validate(ad, "1.1, 2.2, 3.3"));
+        // adhere maximal values
+        assertEquals("", ADValidator.validate(ad, "2.2, 3.3, 4.4"));
+        // 3rd value is too great
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "3.3, 4.4, 5.5"));
+    }
 
-		ad.setCardinality(3); // up to three values are allowed...
-		ad.setRequired(true);
+    /**
+     * Tests the validation of integers is based on the minimum and maximum values.
+     */
+    public void testValidateInteger()
+    {
+        AD ad = new AD();
+        ad.setType("Integer");
+        ad.setMin("3"); // only values greater than 2
+        ad.setMax("6"); // only values less than 7
+        ad.setRequired(false);
 
-		// mandatory value
-		assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
-		// 2nd value is too short
-		assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "321,12,123"));
-		// adhere minimum lengths
-		assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
-		// adhere maximum lengths
-		assertEquals("", ADValidator.validate(ad, "12356, 654321, 123456"));
-		// 3rd value is too long
-		assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "123, 123, 1234567"));
-		
-		ad.setOptions(Collections.singletonMap("123", "foo"));
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        assertEquals("", ADValidator.validate(ad, ""));
+        // too less
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "2"));
+        // adhere minimal value
+        assertEquals("", ADValidator.validate(ad, "3"));
+        // adhere maximal value
+        assertEquals("", ADValidator.validate(ad, "6"));
+        // too great
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "7"));
 
-		// adhere minimum lengths
-		assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
-		assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "2134"));
-	}
+        ad.setCardinality(3); // up to three values are allowed...
+
+        // mandatory value
+        assertEquals("", ADValidator.validate(ad, null));
+        // 2nd value is missing
+        assertEquals("", ADValidator.validate(ad, "3,,3"));
+
+        ad.setRequired(true);
+
+        // mandatory value
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+        // 2nd value is missing
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "3,,3"));
+        // 2nd value is invalid
+        assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "3,a,3"));
+        // 2nd value is too less
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "3,2,3"));
+        // adhere minimal values
+        assertEquals("", ADValidator.validate(ad, "3, 4, 5"));
+        // adhere maximal values
+        assertEquals("", ADValidator.validate(ad, "6, 5, 4"));
+        // 3rd value is too great
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "5, 6, 7"));
+    }
+
+    /**
+     * Tests the validation of long values works as expected.
+     */
+    public void testValidateLong()
+    {
+        AD ad = new AD();
+        ad.setType("Long");
+        ad.setRequired(true);
+
+        ad.setMin("-20");
+        ad.setMax("-15");
+
+        // value too small
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "-21"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "-15"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "-20"));
+        // value too great
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "-14"));
+
+        // Set minimum and maximum beyond the range of plain integers...
+        ad.setMin("2147483650");
+        ad.setMax("2147483655");
+
+        // value too small
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "2147483649"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "2147483650"));
+        // value within bounds
+        assertEquals("", ADValidator.validate(ad, "2147483655"));
+        // value too great
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "2147483656"));
+    }
+
+    /**
+     * Tests the validation of strings is based on the minimum and maximum lengths.
+     */
+    public void testValidateString()
+    {
+        AD ad = new AD();
+        ad.setType("String");
+        ad.setRequired(false);
+
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        // any length of input is accepted
+        assertEquals("", ADValidator.validate(ad, "1234567890"));
+
+        ad.setMin("3"); // minimal length == 3
+        ad.setMax("6"); // maximum length == 6
+
+        // too short
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "12"));
+        // adhere minimum length
+        assertEquals("", ADValidator.validate(ad, "123"));
+        // adhere maximum length
+        assertEquals("", ADValidator.validate(ad, "12356"));
+        // too long
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "1234567"));
+
+        ad.setCardinality(3); // up to three values are allowed...
+        ad.setMin("");
+
+        // optional value
+        assertEquals("", ADValidator.validate(ad, null));
+        // 2nd value is missing; but that's ok
+        assertEquals("", ADValidator.validate(ad, "321, , 123"));
+
+        ad.setRequired(true);
+        ad.setMin("3");
+
+        // mandatory value
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+        // 2nd value is missing
+        assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "321, , 123"));
+        // 2nd value is too short
+        assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "321,12,123"));
+        // adhere minimum lengths
+        assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
+        // adhere maximum lengths
+        assertEquals("", ADValidator.validate(ad, "12356, 654321, 123456"));
+        // 3rd value is too long
+        assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "123, 123, 1234567"));
+
+        ad.setOptions(Collections.singletonMap("123", "foo"));
+
+        // adhere minimum lengths
+        assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
+        assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "2134"));
+    }
 }
