diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index 25f683f..10a1441 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -34,16 +34,16 @@ class Command(NoArgsCommand):
 
     def __init__(self, *args, **kwargs):
         super(NoArgsCommand, self).__init__(*args, **kwargs)
-        self.copied_files = set()
-        self.symlinked_files = set()
-        self.unmodified_files = set()
-        self.destination_storage = get_storage_class(settings.STATICFILES_STORAGE)()
+        self.copied_files = []
+        self.symlinked_files = []
+        self.unmodified_files = []
+        self.storage = get_storage_class(settings.STATICFILES_STORAGE)()
         try:
-            self.destination_storage.path('')
+            self.storage.path('')
         except NotImplementedError:
-            self.destination_local = False
+            self.local = False
         else:
-            self.destination_local = True
+            self.local = True
         # Use ints for file times (ticket #14665)
         os.stat_float_times(False)
 
@@ -59,25 +59,33 @@ class Command(NoArgsCommand):
             if sys.platform == 'win32':
                 raise CommandError("Symlinking is not supported by this "
                                    "platform (%s)." % sys.platform)
-            if not self.destination_local:
+            if not self.local:
                 raise CommandError("Can't symlink to a remote destination.")
 
         # Warn before doing anything more.
         if options.get('interactive'):
             confirm = raw_input("""
-You have requested to collate static files and collect them at the destination
-location as specified in your settings file.
+You have requested to collect static files at the destination
+location as specified in your settings file ('%s').
 
 This will overwrite existing files.
 Are you sure you want to do this?
 
-Type 'yes' to continue, or 'no' to cancel: """)
+Type 'yes' to continue, or 'no' to cancel: """ % settings.STATIC_ROOT)
             if confirm != 'yes':
                 raise CommandError("Collecting static files cancelled.")
 
         for finder in finders.get_finders():
-            for source, storage in finder.list(ignore_patterns):
-                self.copy_file(source, storage, **options)
+            for path, storage in finder.list(ignore_patterns):
+                # Prefix the relative path if the source storage contains it
+                if getattr(storage, 'prefix', None):
+                    prefixed_path = os.path.join(storage.prefix, path)
+                else:
+                    prefixed_path = path
+                if symlink:
+                    self.link_file(path, prefixed_path, storage, **options)
+                else:
+                    self.copy_file(path, prefixed_path, storage, **options)
 
         actual_count = len(self.copied_files) + len(self.symlinked_files)
         unmodified_count = len(self.unmodified_files)
@@ -98,84 +106,94 @@ Type 'yes' to continue, or 'no' to cancel: """)
         if self.verbosity >= level:
             self.stdout.write(msg)
 
-    def copy_file(self, source, source_storage, **options):
-        """
-        Attempt to copy (or symlink) ``source`` to ``destination``,
-        returning True if successful.
-        """
-        source_path = source_storage.path(source)
-        try:
-            source_last_modified = source_storage.modified_time(source)
-        except (OSError, NotImplementedError):
-            source_last_modified = None
-        if getattr(source_storage, 'prefix', None):
-            destination = os.path.join(source_storage.prefix, source)
-        else:
-            destination = source
+    def delete_file(self, path, prefixed_path, source_storage, **options):
+        # Whether we are in symlink mode
         symlink = options['link']
-        dry_run = options['dry_run']
-
-        if destination in self.copied_files:
-            self.log("Skipping '%s' (already copied earlier)" % destination)
-            return False
-
-        if destination in self.symlinked_files:
-            self.log("Skipping '%s' (already linked earlier)" % destination)
-            return False
-
-        if self.destination_storage.exists(destination):
+        # Checks if the target file should be deleted if it already exists
+        if self.storage.exists(prefixed_path):
             try:
-                destination_last_modified = \
-                    self.destination_storage.modified_time(destination)
+                # When was the target file modified last time?
+                target_last_modified = self.storage.modified_time(prefixed_path)
             except (OSError, NotImplementedError):
-                # storage doesn't support ``modified_time`` or failed.
+                # The storage doesn't support ``modified_time`` or failed
                 pass
             else:
-                destination_is_link = (self.destination_local and
-                    os.path.islink(self.destination_storage.path(destination)))
-                if destination_last_modified >= source_last_modified:
-                    if (not symlink and not destination_is_link):
-                        self.log("Skipping '%s' (not modified)" % destination)
-                        self.unmodified_files.add(destination)
-                        return False
-            if dry_run:
-                self.log("Pretending to delete '%s'" % destination)
+                try:
+                    # When was the source file modified last time?
+                    source_last_modified = source_storage.modified_time(path)
+                except (OSError, NotImplementedError):
+                    pass
+                else:
+                    # The full path of the target file
+                    full_path = self.storage.path(prefixed_path)
+                    # Skip the file if the source file is younger
+                    if target_last_modified >= source_last_modified:
+                        if not ((symlink and not os.path.islink(full_path)) or
+                                (not symlink and os.path.islink(full_path))):
+                            if prefixed_path not in self.unmodified_files:
+                                self.unmodified_files.append(prefixed_path)
+                            self.log("Skipping '%s' (not modified)" % path)
+                            return False
+            # Then delete the existing file if really needed
+            if options['dry_run']:
+                self.log("Pretending to delete '%s'" % path)
             else:
-                self.log("Deleting '%s'" % destination)
-                self.destination_storage.delete(destination)
+                self.log("Deleting '%s'" % path)
+                self.storage.delete(prefixed_path)
+        return True
 
-        if symlink:
-            destination_path = self.destination_storage.path(destination)
-            if dry_run:
-                self.log("Pretending to link '%s' to '%s'" %
-                         (source_path, destination_path), level=1)
-            else:
-                self.log("Linking '%s' to '%s'" %
-                         (source_path, destination_path), level=1)
+    def link_file(self, path, prefixed_path, source_storage, **options):
+        """
+        Attempt to link ``path``
+        """
+        # Skip this file if it was already copied earlier
+        if prefixed_path in self.symlinked_files:
+            return self.log("Skipping '%s' (already linked earlier)" % path)
+        # Delete the target file if needed or break
+        if not self.delete_file(path, prefixed_path, source_storage, **options):
+            return
+        # The full path of the source file
+        source_path = source_storage.path(path)
+        # Finally link the file
+        if options['dry_run']:
+            self.log("Pretending to link '%s'" % source_path, level=1)
+        else:
+            self.log("Linking '%s'" % source_path, level=1)
+            full_path = self.storage.path(prefixed_path)
+            try:
+                os.makedirs(os.path.dirname(full_path))
+            except OSError:
+                pass
+            os.symlink(source_path, full_path)
+        if prefixed_path not in self.symlinked_files:
+            self.symlinked_files.append(prefixed_path)
+
+    def copy_file(self, path, prefixed_path, source_storage, **options):
+        """
+        Attempt to copy ``path`` with storage
+        """
+        # Skip this file if it was already copied earlier
+        if prefixed_path in self.copied_files:
+            return self.log("Skipping '%s' (already copied earlier)" % path)
+        # Delete the target file if needed or break
+        if not self.delete_file(path, prefixed_path, source_storage, **options):
+            return
+        # The full path of the source file
+        source_path = source_storage.path(path)
+        # Finally start copying
+        if options['dry_run']:
+            self.log("Pretending to copy '%s'" % source_path, level=1)
+        else:
+            self.log("Copying '%s'" % source_path, level=1)
+            if self.local:
+                full_path = self.storage.path(prefixed_path)
                 try:
-                    os.makedirs(os.path.dirname(destination_path))
+                    os.makedirs(os.path.dirname(full_path))
                 except OSError:
                     pass
-                os.symlink(source_path, destination_path)
-            self.symlinked_files.add(destination)
-        else:
-            if dry_run:
-                self.log("Pretending to copy '%s' to '%s'" %
-                         (source_path, destination), level=1)
+                shutil.copy2(source_path, full_path)
             else:
-                if self.destination_local:
-                    destination_path = self.destination_storage.path(destination)
-                    try:
-                        os.makedirs(os.path.dirname(destination_path))
-                    except OSError:
-                        pass
-                    shutil.copy2(source_path, destination_path)
-                    self.log("Copying '%s' to '%s'" %
-                             (source_path, destination_path), level=1)
-                else:
-                    source_file = source_storage.open(source)
-                    self.destination_storage.save(destination, source_file)
-                    self.log("Copying %s to %s" %
-                             (source_path, destination), level=1)
-            self.copied_files.add(destination)
-        return True
+                source_file = source_storage.open(path)
+                self.storage.save(prefixed_path, source_file)
+        if not prefixed_path in self.copied_files:
+            self.copied_files.append(prefixed_path)
