diff --git a/django/forms/fields.py b/django/forms/fields.py
index ccb54d8..5da3a01 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -439,8 +439,10 @@ except ImportError:
     # It's OK if Django settings aren't configured.
     URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
 
-
-class FileField(Field):
+class FieldWithInitial(object):
+    pass
+ 
+class FileField(Field, FieldWithInitial):
     widget = FileInput
     default_error_messages = {
         'invalid': _(u"No file was submitted. Check the encoding type on the form."),
@@ -454,7 +456,7 @@ class FileField(Field):
     def clean(self, data, initial=None):
         super(FileField, self).clean(initial or data)
         if not self.required and data in EMPTY_VALUES:
-            return None
+            return initial or None
         elif not data and initial:
             return initial
 
@@ -714,7 +716,7 @@ class MultipleChoiceField(ChoiceField):
                 raise ValidationError(self.error_messages['invalid_choice'] % {'value': val})
         return new_value
 
-class ComboField(Field):
+class ComboField(Field, FieldWithInitial):
     """
     A Field whose clean() method calls multiple Field clean() methods.
     """
@@ -727,17 +729,20 @@ class ComboField(Field):
             f.required = False
         self.fields = fields
 
-    def clean(self, value):
+    def clean(self, value, initial=None):
         """
         Validates the given value against all of self.fields, which is a
         list of Field instances.
         """
-        super(ComboField, self).clean(value)
+        super(ComboField, self).clean(initial or value)
         for field in self.fields:
-            value = field.clean(value)
+            if isinstance(field, FieldWithInitial):
+                value = field.clean(value, initial)
+            else:
+                value = field.clean(value)
         return value
 
-class MultiValueField(Field):
+class MultiValueField(Field, FieldWithInitial):
     """
     A Field that aggregates the logic of multiple Fields.
 
@@ -767,7 +772,7 @@ class MultiValueField(Field):
             f.required = False
         self.fields = fields
 
-    def clean(self, value):
+    def clean(self, value, initial=None):
         """
         Validates every value in the given list. A value is validated against
         the corresponding Field in self.fields.
@@ -776,10 +781,27 @@ class MultiValueField(Field):
         fields=(DateField(), TimeField()), clean() would call
         DateField.clean(value[0]) and TimeField.clean(value[1]).
         """
-        clean_data = []
+        clean_data, value_list, initial_list, takes_initial_list = [], [], [], []
+        value, initial = value or [], initial or []
         errors = ErrorList()
         if not value or isinstance(value, (list, tuple)):
-            if not value or not [v for v in value if v not in EMPTY_VALUES]:
+            for i, field in enumerate(self.fields):
+                try:
+                    field_value = value[i]
+                except IndexError:
+                    field_value = None
+                value_list.append(field_value)
+                try:
+                    field_initial = initial[i]
+                except IndexError:
+                    field_initial = None
+                initial_list.append(field_initial)
+                takes_initial_list.append(isinstance(field, FieldWithInitial)) 
+
+            if not value or not [(v, i, t) for v, i, t in \
+                zip(value_list, initial_list, takes_initial_list) \
+                if v not in EMPTY_VALUES or t and i not in EMPTY_VALUES]:
+
                 if self.required:
                     raise ValidationError(self.error_messages['required'])
                 else:
@@ -787,14 +809,17 @@ class MultiValueField(Field):
         else:
             raise ValidationError(self.error_messages['invalid'])
         for i, field in enumerate(self.fields):
+            field_value = value_list[i]
+            field_initial = initial_list[i]
+            takes_initial = takes_initial_list[i]
+            if self.required and not ( (takes_initial and field_initial not in EMPTY_VALUES) or 
+                (field_value not in EMPTY_VALUES) ):
+                 raise ValidationError(self.error_messages['required'])
             try:
-                field_value = value[i]
-            except IndexError:
-                field_value = None
-            if self.required and field_value in EMPTY_VALUES:
-                raise ValidationError(self.error_messages['required'])
-            try:
-                clean_data.append(field.clean(field_value))
+                if takes_initial:
+                    clean_data.append(field.clean(field_value, field_initial))
+                else:
+                    clean_data.append(field.clean(field_value))
             except ValidationError, e:
                 # Collect all validation errors in a single list, which we'll
                 # raise at the end of clean(), rather than raising a single
@@ -802,9 +827,9 @@ class MultiValueField(Field):
                 errors.extend(e.messages)
         if errors:
             raise ValidationError(errors)
-        return self.compress(clean_data)
+        return self.compress(clean_data, initial_list)
 
-    def compress(self, data_list):
+    def compress(self, data_list, initial_list=[]):
         """
         Returns a single value for the given list of values. The values can be
         assumed to be valid.
@@ -860,7 +885,7 @@ class SplitDateTimeField(MultiValueField):
         )
         super(SplitDateTimeField, self).__init__(fields, *args, **kwargs)
 
-    def compress(self, data_list):
+    def compress(self, data_list, initial_list=[]):
         if data_list:
             # Raise a validation error if time or date is empty
             # (possible if SplitDateTimeField has required=False).
diff --git a/django/forms/forms.py b/django/forms/forms.py
index f5bea10..45c1de7 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -9,7 +9,7 @@ from django.utils.html import conditional_escape
 from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
 from django.utils.safestring import mark_safe
 
-from fields import Field, FileField
+from fields import Field, FieldWithInitial
 from widgets import Media, media_property, TextInput, Textarea
 from util import flatatt, ErrorDict, ErrorList, ValidationError
 
@@ -224,7 +224,7 @@ class BaseForm(StrAndUnicode):
             # widgets split data over several HTML fields.
             value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
             try:
-                if isinstance(field, FileField):
+                if isinstance(field, FieldWithInitial):
                     initial = self.initial.get(name, field.initial)
                     value = field.clean(value, initial)
                 else:
diff --git a/tests/regressiontests/forms/extra.py b/tests/regressiontests/forms/extra.py
index 80f7ef6..5ba45b2 100644
--- a/tests/regressiontests/forms/extra.py
+++ b/tests/regressiontests/forms/extra.py
@@ -276,7 +276,7 @@ True
 ...         )
 ...         super(ComplexField, self).__init__(fields, required, widget, label, initial)
 ...
-...     def compress(self, data_list):
+...     def compress(self, data_list, initial_list=[]):
 ...         if data_list:
 ...             return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2])
 ...         return None
diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py
index fa5a62a..eabded7 100644
--- a/tests/regressiontests/forms/fields.py
+++ b/tests/regressiontests/forms/fields.py
@@ -1290,6 +1290,43 @@ ValidationError: [u'Enter a valid e-mail address.']
 u''
 >>> f.clean(None)
 u''
+>>> f = ComboField(fields=[FileField(), CharField(max_length=20)])
+>>> f.clean('data', 'some_file.txt')
+Traceback (most recent call last):
+...    
+ValidationError: [u'No file was submitted. Check the encoding type on the form.']
+>>> f.clean('', 'some_file.txt')
+u'some_file.txt'
+>>> f.clean('', None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean({'filename': 'filename.txt', 'content':'something'})
+u'filename.txt'
+>>> f.clean({'filename': 'too_long_filename_for_this_combofield_here.txt', 'content':'something'})
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 20 characters (it has 46).']
+  
+# MultiValueField ##########################################################
+
+>>> f = MultiValueField(fields=[FileField(), CharField(max_length=20)])
+>>> f.clean([{'filename': 'some_file.txt', 'content':'something'}, 'Some text'])
+Traceback (most recent call last):
+...
+NotImplementedError: Subclasses must implement this method.
+>>> f.clean([{'filename': 'some_file.txt', 'content':'something'}, 'alotoftext_more_than_20_chars'])
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 20 characters (it has 29).']
+>>> f.clean([None, None])
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean([None, 'Some text'], ['some_file.txt', None])
+Traceback (most recent call last):
+...
+NotImplementedError: Subclasses must implement this method.
 
 # FilePathField ###############################################################
 
