diff --git a/scrapy/core/scheduler.py b/scrapy/core/scheduler.py
index a54b4daf0..eb790a67e 100644
--- a/scrapy/core/scheduler.py
+++ b/scrapy/core/scheduler.py
@@ -4,7 +4,7 @@ import logging
 from os.path import join, exists
 
 from scrapy.utils.reqser import request_to_dict, request_from_dict
-from scrapy.utils.misc import load_object
+from scrapy.utils.misc import load_object, create_instance
 from scrapy.utils.job import job_dir
 
 logger = logging.getLogger(__name__)
@@ -26,7 +26,7 @@ class Scheduler(object):
     def from_crawler(cls, crawler):
         settings = crawler.settings
         dupefilter_cls = load_object(settings['DUPEFILTER_CLASS'])
-        dupefilter = dupefilter_cls.from_settings(settings)
+        dupefilter = create_instance(dupefilter_cls, settings, crawler)
         pqclass = load_object(settings['SCHEDULER_PRIORITY_QUEUE'])
         dqclass = load_object(settings['SCHEDULER_DISK_QUEUE'])
         mqclass = load_object(settings['SCHEDULER_MEMORY_QUEUE'])
diff --git a/scrapy/http/request/form.py b/scrapy/http/request/form.py
index 95b38e990..c2413b431 100644
--- a/scrapy/http/request/form.py
+++ b/scrapy/http/request/form.py
@@ -114,10 +114,12 @@ def _get_form(response, formname, formid, formnumber, formxpath):
 
 def _get_inputs(form, formdata, dont_click, clickdata, response):
     try:
-        formdata = dict(formdata or ())
+        formdata_keys = dict(formdata or ()).keys()
     except (ValueError, TypeError):
         raise ValueError('formdata should be a dict or iterable of tuples')
 
+    if not formdata:
+        formdata = ()
     inputs = form.xpath('descendant::textarea'
                         '|descendant::select'
                         '|descendant::input[not(@type) or @type['
@@ -128,14 +130,17 @@ def _get_inputs(form, formdata, dont_click, clickdata, response):
                             "re": "http://exslt.org/regular-expressions"})
     values = [(k, u'' if v is None else v)
               for k, v in (_value(e) for e in inputs)
-              if k and k not in formdata]
+              if k and k not in formdata_keys]
 
     if not dont_click:
         clickable = _get_clickable(clickdata, form)
         if clickable and clickable[0] not in formdata and not clickable[0] is None:
             values.append(clickable)
 
-    values.extend((k, v) for k, v in formdata.items() if v is not None)
+    if isinstance(formdata, dict):
+        formdata = formdata.items()
+
+    values.extend((k, v) for k, v in formdata if v is not None)
     return values
 
 

diff --git a/tests/test_dupefilters.py b/tests/test_dupefilters.py
index 2d1a4bfff..db69597a2 100644
--- a/tests/test_dupefilters.py
+++ b/tests/test_dupefilters.py
@@ -5,11 +5,60 @@ import shutil
 
 from scrapy.dupefilters import RFPDupeFilter
 from scrapy.http import Request
+from scrapy.core.scheduler import Scheduler
 from scrapy.utils.python import to_bytes
+from scrapy.utils.job import job_dir
+from scrapy.utils.test import get_crawler
+
+
+class FromCrawlerRFPDupeFilter(RFPDupeFilter):
+
+    @classmethod
+    def from_crawler(cls, crawler):
+        debug = crawler.settings.getbool('DUPEFILTER_DEBUG')
+        df = cls(job_dir(crawler.settings), debug)
+        df.method = 'from_crawler'
+        return df
+
+
+class FromSettingsRFPDupeFilter(RFPDupeFilter):
+
+    @classmethod
+    def from_settings(cls, settings):
+        debug = settings.getbool('DUPEFILTER_DEBUG')
+        df = cls(job_dir(settings), debug)
+        df.method = 'from_settings'
+        return df
+
+
+class DirectDupeFilter(object):
+    method = 'n/a'
 
 
 class RFPDupeFilterTest(unittest.TestCase):
 
+    def test_df_from_crawler_scheduler(self):
+        settings = {'DUPEFILTER_DEBUG': True,
+                    'DUPEFILTER_CLASS': __name__  + '.FromCrawlerRFPDupeFilter'}
+        crawler = get_crawler(settings_dict=settings)
+        scheduler = Scheduler.from_crawler(crawler)
+        self.assertTrue(scheduler.df.debug)
+        self.assertEqual(scheduler.df.method, 'from_crawler')
+
+    def test_df_from_settings_scheduler(self):
+        settings = {'DUPEFILTER_DEBUG': True,
+                    'DUPEFILTER_CLASS': __name__  + '.FromSettingsRFPDupeFilter'}
+        crawler = get_crawler(settings_dict=settings)
+        scheduler = Scheduler.from_crawler(crawler)
+        self.assertTrue(scheduler.df.debug)
+        self.assertEqual(scheduler.df.method, 'from_settings')
+
+    def test_df_direct_scheduler(self):
+        settings = {'DUPEFILTER_CLASS': __name__  + '.DirectDupeFilter'}
+        crawler = get_crawler(settings_dict=settings)
+        scheduler = Scheduler.from_crawler(crawler)
+        self.assertEqual(scheduler.df.method, 'n/a')
+
     def test_filter(self):
         dupefilter = RFPDupeFilter()
         dupefilter.open()
diff --git a/tests/test_http_request.py b/tests/test_http_request.py
index fc89229c6..58326a384 100644
--- a/tests/test_http_request.py
+++ b/tests/test_http_request.py
@@ -406,6 +406,29 @@ class FormRequestTest(RequestTest):
         self.assertEqual(fs[u'test2'], [u'xxx µ'])
         self.assertEqual(fs[u'six'], [u'seven'])
 
+    def test_from_response_duplicate_form_key(self):
+        response = _buildresponse(
+                '<form></form>',
+                url='http://www.example.com')
+        req = self.request_class.from_response(response,
+                method='GET',
+                formdata=(('foo', 'bar'), ('foo', 'baz')))
+        self.assertEqual(urlparse(req.url).hostname, 'www.example.com')
+        self.assertEqual(urlparse(req.url).query, 'foo=bar&foo=baz')
+    
+    def test_from_response_override_duplicate_form_key(self):
+        response = _buildresponse(
+            """<form action="get.php" method="POST">
+            <input type="hidden" name="one" value="1">
+            <input type="hidden" name="two" value="3">
+            </form>""")
+        req = self.request_class.from_response(
+            response,
+            formdata=(('two', '2'), ('two', '4')))
+        fs = _qs(req)
+        self.assertEqual(fs[b'one'], [b'1'])
+        self.assertEqual(fs[b'two'], [b'2', b'4'])
+
     def test_from_response_extra_headers(self):
         response = _buildresponse(
             """<form action="post.php" method="POST">

`scrapy.FormRequest.from_response` observed to eliminate duplicate keys in `formdata`
This looks good:
```
In [2]: scrapy.FormRequest('http://example.com', method='GET', formdata=(('foo', 'bar'), ('foo', 'baz')))
Out[2]: <GET http://example.com?foo=bar&foo=baz>
```

While here is the issue:
```
In [3]: response = scrapy.http.TextResponse(url='http://example.com', body='<form></form>', encoding='utf8')

In [4]: scrapy.FormRequest.from_response(response, method='GET', formdata=(('foo', 'bar'), ('foo', 'baz')))
Out[4]: <GET http://example.com?foo=baz>
```

(Tested with `Scrapy 1.5.0` and `Python 3.6.5`)
tests/test_dupefilters.py::RFPDupeFilterTest::test_df_direct_scheduler tests/test_dupefilters.py::RFPDupeFilterTest::test_df_from_crawler_scheduler tests/test_http_request.py::FormRequestTest::test_from_response_duplicate_form_key tests/test_http_request.py::FormRequestTest::test_from_response_override_duplicate_form_key
tests/test_dupefilters.py::RFPDupeFilterTest::test_df_from_settings_scheduler tests/test_dupefilters.py::RFPDupeFilterTest::test_dupefilter_path tests/test_dupefilters.py::RFPDupeFilterTest::test_filter tests/test_dupefilters.py::RFPDupeFilterTest::test_request_fingerprint tests/test_http_request.py::RequestTest::test_ajax_url tests/test_http_request.py::RequestTest::test_body tests/test_http_request.py::RequestTest::test_callback_is_callable tests/test_http_request.py::RequestTest::test_copy tests/test_http_request.py::RequestTest::test_copy_inherited_classes tests/test_http_request.py::RequestTest::test_eq tests/test_http_request.py::RequestTest::test_errback_is_callable tests/test_http_request.py::RequestTest::test_headers tests/test_http_request.py::RequestTest::test_immutable_attributes tests/test_http_request.py::RequestTest::test_init tests/test_http_request.py::RequestTest::test_method_always_str tests/test_http_request.py::RequestTest::test_replace tests/test_http_request.py::RequestTest::test_url tests/test_http_request.py::RequestTest::test_url_encoding tests/test_http_request.py::RequestTest::test_url_encoding_nonutf8_untouched tests/test_http_request.py::RequestTest::test_url_encoding_other tests/test_http_request.py::RequestTest::test_url_encoding_query tests/test_http_request.py::RequestTest::test_url_encoding_query_latin1 tests/test_http_request.py::RequestTest::test_url_no_scheme tests/test_http_request.py::RequestTest::test_url_quoting tests/test_http_request.py::FormRequestTest::test_ajax_url tests/test_http_request.py::FormRequestTest::test_body tests/test_http_request.py::FormRequestTest::test_callback_is_callable tests/test_http_request.py::FormRequestTest::test_copy tests/test_http_request.py::FormRequestTest::test_copy_inherited_classes tests/test_http_request.py::FormRequestTest::test_custom_encoding_bytes tests/test_http_request.py::FormRequestTest::test_custom_encoding_textual_data tests/test_http_request.py::FormRequestTest::test_default_encoding_bytes tests/test_http_request.py::FormRequestTest::test_default_encoding_mixed_data tests/test_http_request.py::FormRequestTest::test_default_encoding_textual_data tests/test_http_request.py::FormRequestTest::test_empty_formdata tests/test_http_request.py::FormRequestTest::test_eq tests/test_http_request.py::FormRequestTest::test_errback_is_callable tests/test_http_request.py::FormRequestTest::test_from_response_ambiguous_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_button_notype tests/test_http_request.py::FormRequestTest::test_from_response_button_novalue tests/test_http_request.py::FormRequestTest::test_from_response_button_submit tests/test_http_request.py::FormRequestTest::test_from_response_case_insensitive tests/test_http_request.py::FormRequestTest::test_from_response_checkbox tests/test_http_request.py::FormRequestTest::test_from_response_clickdata_does_not_ignore_image tests/test_http_request.py::FormRequestTest::test_from_response_css tests/test_http_request.py::FormRequestTest::test_from_response_descendants tests/test_http_request.py::FormRequestTest::test_from_response_dont_click tests/test_http_request.py::FormRequestTest::test_from_response_dont_submit_image_as_input tests/test_http_request.py::FormRequestTest::test_from_response_dont_submit_reset_as_input tests/test_http_request.py::FormRequestTest::test_from_response_drop_params tests/test_http_request.py::FormRequestTest::test_from_response_errors_formnumber tests/test_http_request.py::FormRequestTest::test_from_response_errors_noform tests/test_http_request.py::FormRequestTest::test_from_response_extra_headers tests/test_http_request.py::FormRequestTest::test_from_response_formid_errors_formnumber tests/test_http_request.py::FormRequestTest::test_from_response_formid_exists tests/test_http_request.py::FormRequestTest::test_from_response_formid_notexist tests/test_http_request.py::FormRequestTest::test_from_response_formname_errors_formnumber tests/test_http_request.py::FormRequestTest::test_from_response_formname_exists tests/test_http_request.py::FormRequestTest::test_from_response_formname_notexist tests/test_http_request.py::FormRequestTest::test_from_response_formname_notexists_fallback_formid tests/test_http_request.py::FormRequestTest::test_from_response_get tests/test_http_request.py::FormRequestTest::test_from_response_input_hidden tests/test_http_request.py::FormRequestTest::test_from_response_input_text tests/test_http_request.py::FormRequestTest::test_from_response_input_textarea tests/test_http_request.py::FormRequestTest::test_from_response_invalid_html5 tests/test_http_request.py::FormRequestTest::test_from_response_invalid_nr_index_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_multiple_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_multiple_forms_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_noformname tests/test_http_request.py::FormRequestTest::test_from_response_non_matching_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_nr_index_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_override_clickable tests/test_http_request.py::FormRequestTest::test_from_response_override_method tests/test_http_request.py::FormRequestTest::test_from_response_override_params tests/test_http_request.py::FormRequestTest::test_from_response_override_url tests/test_http_request.py::FormRequestTest::test_from_response_post tests/test_http_request.py::FormRequestTest::test_from_response_post_nonascii_bytes_latin1 tests/test_http_request.py::FormRequestTest::test_from_response_post_nonascii_bytes_utf8 tests/test_http_request.py::FormRequestTest::test_from_response_post_nonascii_unicode tests/test_http_request.py::FormRequestTest::test_from_response_radio tests/test_http_request.py::FormRequestTest::test_from_response_select tests/test_http_request.py::FormRequestTest::test_from_response_submit_first_clickable tests/test_http_request.py::FormRequestTest::test_from_response_submit_not_first_clickable tests/test_http_request.py::FormRequestTest::test_from_response_submit_novalue tests/test_http_request.py::FormRequestTest::test_from_response_unicode_clickdata tests/test_http_request.py::FormRequestTest::test_from_response_unicode_clickdata_latin1 tests/test_http_request.py::FormRequestTest::test_from_response_unicode_xpath tests/test_http_request.py::FormRequestTest::test_from_response_xpath tests/test_http_request.py::FormRequestTest::test_headers tests/test_http_request.py::FormRequestTest::test_html_base_form_action tests/test_http_request.py::FormRequestTest::test_immutable_attributes tests/test_http_request.py::FormRequestTest::test_init tests/test_http_request.py::FormRequestTest::test_method_always_str tests/test_http_request.py::FormRequestTest::test_multi_key_values tests/test_http_request.py::FormRequestTest::test_replace tests/test_http_request.py::FormRequestTest::test_spaces_in_action tests/test_http_request.py::FormRequestTest::test_url tests/test_http_request.py::FormRequestTest::test_url_encoding tests/test_http_request.py::FormRequestTest::test_url_encoding_nonutf8_untouched tests/test_http_request.py::FormRequestTest::test_url_encoding_other tests/test_http_request.py::FormRequestTest::test_url_encoding_query tests/test_http_request.py::FormRequestTest::test_url_encoding_query_latin1 tests/test_http_request.py::FormRequestTest::test_url_no_scheme tests/test_http_request.py::FormRequestTest::test_url_quoting tests/test_http_request.py::XmlRpcRequestTest::test_ajax_url tests/test_http_request.py::XmlRpcRequestTest::test_body tests/test_http_request.py::XmlRpcRequestTest::test_callback_is_callable tests/test_http_request.py::XmlRpcRequestTest::test_copy tests/test_http_request.py::XmlRpcRequestTest::test_copy_inherited_classes tests/test_http_request.py::XmlRpcRequestTest::test_eq tests/test_http_request.py::XmlRpcRequestTest::test_errback_is_callable tests/test_http_request.py::XmlRpcRequestTest::test_headers tests/test_http_request.py::XmlRpcRequestTest::test_immutable_attributes tests/test_http_request.py::XmlRpcRequestTest::test_init tests/test_http_request.py::XmlRpcRequestTest::test_latin1 tests/test_http_request.py::XmlRpcRequestTest::test_method_always_str tests/test_http_request.py::XmlRpcRequestTest::test_replace tests/test_http_request.py::XmlRpcRequestTest::test_url tests/test_http_request.py::XmlRpcRequestTest::test_url_encoding tests/test_http_request.py::XmlRpcRequestTest::test_url_encoding_nonutf8_untouched tests/test_http_request.py::XmlRpcRequestTest::test_url_encoding_other tests/test_http_request.py::XmlRpcRequestTest::test_url_encoding_query tests/test_http_request.py::XmlRpcRequestTest::test_url_encoding_query_latin1 tests/test_http_request.py::XmlRpcRequestTest::test_url_no_scheme tests/test_http_request.py::XmlRpcRequestTest::test_url_quoting tests/test_http_request.py::XmlRpcRequestTest::test_xmlrpc_dumps