diff --git a/config/schema/facets.processor.schema.yml b/config/schema/facets.processor.schema.yml
index 445ac77..dab9282 100644
--- a/config/schema/facets.processor.schema.yml
+++ b/config/schema/facets.processor.schema.yml
@@ -14,6 +14,17 @@ plugin.plugin_configuration.facets_processor.display_value_widget_order:
       type: string
       label: sort order
 
+plugin.plugin_configuration.facets_processor.exclude_specified_items:
+  type: mapping
+  label: 'Exclude specified items'
+  mapping:
+    exclude:
+      type: string
+      label: Exclude
+    regex:
+      type: boolean
+      label: Regex
+
 plugin.plugin_configuration.facets_processor.raw_value_widget_order:
   type: mapping
   label: 'Raw value widget order'
@@ -30,6 +41,14 @@ plugin.plugin_configuration.facets_processor.active_widget_order:
       type: string
       label: sort order
 
+plugin.plugin_configuration.facets_processor.count_widget_order:
+  type: mapping
+  label: 'Active widget order'
+  mapping:
+    sort:
+      type: string
+      label: sort order
+
 plugin.plugin_configuration.facets_processor.count_limit:
   type: mapping
   label: 'Count limit widget'
diff --git a/src/Tests/ExampleContentTrait.php b/src/Tests/ExampleContentTrait.php
index 5bb93f4..2d2dac7 100644
--- a/src/Tests/ExampleContentTrait.php
+++ b/src/Tests/ExampleContentTrait.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\facets\Tests;
 
+use Drupal\Component\Render\FormattableMarkup;
 use Drupal\search_api\Entity\Index;
 
 /**
@@ -94,4 +95,50 @@ trait ExampleContentTrait {
     return $index->indexItems();
   }
 
+  /**
+   * Add a facet trough the UI.
+   *
+   * @param string $name
+   *   The facet name.
+   * @param string $id
+   *   The facet id.
+   * @param string $field
+   *   The facet field.
+   */
+  protected function createFacet($name, $id, $field = 'type') {
+    $facet_add_page = 'admin/config/search/facets/add-facet';
+
+    $this->drupalGet($facet_add_page);
+
+    $form_values = [
+      'id' => $id,
+      'status' => 1,
+      'url_alias' => $id,
+      'name' => $name,
+      'facet_source_id' => 'search_api_views:search_api_test_view:page_1',
+      'facet_source_configs[search_api_views:search_api_test_view:page_1][field_identifier]' => $field,
+    ];
+    $this->drupalPostForm(NULL, ['facet_source_id' => 'search_api_views:search_api_test_view:page_1'], $this->t('Configure facet source'));
+    $this->drupalPostForm(NULL, $form_values, $this->t('Save'));
+  }
+
+  /**
+   * Asserts that a string is before another string.
+   *
+   * @param string $x
+   *   A string.
+   * @param string $y
+   *   Another string.
+   */
+  protected function assertXBeforeY($x, $y) {
+    $this->assertText($x);
+    $this->assertText($y);
+
+    $x_position = strpos($this->getRawContent(), $x);
+    $y_position = strpos($this->getRawContent(), $y);
+
+    $message = new FormattableMarkup('Assert that %x is before %y in the HTML', ['%x' => $x, '%y' => $y]);
+    $this->assertTrue($x_position < $y_position, $message);
+  }
+
 }
diff --git a/src/Tests/IntegrationTest.php b/src/Tests/IntegrationTest.php
index 3738c1b..3a8a610 100644
--- a/src/Tests/IntegrationTest.php
+++ b/src/Tests/IntegrationTest.php
@@ -386,62 +386,6 @@ class IntegrationTest extends FacetWebTestBase {
   }
 
   /**
-   * Tests for processor integration.
-   */
-  public function testProcessorIntegration() {
-    $facet_name = "Snowy owl~";
-    $facet_id = "snowy_owl_";
-    $this->addFacet($facet_name);
-
-    // Go to the processors form and check that the count limit processor is not
-    // checked.
-    $this->drupalGet('admin/config/search/facets/' . $facet_id . '/display');
-    $this->assertNoFieldChecked('edit-facet-settings-count-limit-status');
-
-    $form = ['facet_settings[count_limit][status]' => TRUE];
-    $this->drupalPostForm(NULL, $form, $this->t('Save'));
-    $this->assertResponse(200);
-    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
-
-    // Enable the sort processor and change sort direction.
-    // Test that the sort settings change persisted.
-    $form = [
-      'facet_sorting[active_widget_order][status]' => TRUE,
-      'facet_sorting[active_widget_order][settings][sort]' => 'DESC',
-    ];
-    $this->drupalPostForm(NULL, $form, $this->t('Save'));
-    $this->assertResponse(200);
-    $this->assertFieldChecked('edit-facet-sorting-active-widget-order-status');
-    $this->assertFieldChecked('edit-facet-sorting-active-widget-order-settings-sort-desc');
-
-    // Add an extra processor so we can test the weights as well.
-    $form = [
-      'facet_settings[hide_non_narrowing_result_processor][status]' => TRUE,
-      'facet_settings[count_limit][status]' => TRUE,
-    ];
-    $this->drupalPostForm(NULL, $form, $this->t('Save'));
-
-    $this->assertResponse(200);
-    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
-    $this->assertFieldChecked('edit-facet-settings-hide-non-narrowing-result-processor-status');
-    $this->assertOptionSelected('edit-processors-count-limit-weights-build', -10);
-    $this->assertOptionSelected('edit-processors-hide-non-narrowing-result-processor-weights-build', -10);
-
-    // Change the weight of one of the processors and test that the weight
-    // change persisted.
-    $form = [
-      'facet_settings[hide_non_narrowing_result_processor][status]' => TRUE,
-      'facet_settings[count_limit][status]' => TRUE,
-      'processors[hide_non_narrowing_result_processor][weights][build]' => 5,
-    ];
-    $this->drupalPostForm(NULL, $form, $this->t('Save'));
-    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
-    $this->assertFieldChecked('edit-facet-settings-hide-non-narrowing-result-processor-status');
-    $this->assertOptionSelected('edit-processors-count-limit-weights-build', -10);
-    $this->assertOptionSelected('edit-processors-hide-non-narrowing-result-processor-weights-build', 5);
-  }
-
-  /**
    * Tests the facet's exclude functionality.
    */
   public function testExcludeFacet() {
diff --git a/src/Tests/ProcessorIntegrationTest.php b/src/Tests/ProcessorIntegrationTest.php
new file mode 100644
index 0000000..67b34b8
--- /dev/null
+++ b/src/Tests/ProcessorIntegrationTest.php
@@ -0,0 +1,378 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\facets\Tests\ProcessorIntegrationTest.
+ */
+
+namespace Drupal\facets\Tests;
+
+use Drupal\Core\Url;
+use Drupal\facets\Tests\WebTestBase as FacetWebTestBase;
+
+/**
+ * Tests the processor functionality.
+ *
+ * @group facets
+ */
+class ProcessorIntegrationTest extends FacetWebTestBase {
+
+  /**
+   * The block entities used by this test.
+   *
+   * @var \Drupal\block\BlockInterface[]
+   */
+  protected $blocks;
+
+  /**
+   * The url of the edit form.
+   *
+   * @var string
+   */
+  protected $editForm;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->drupalLogin($this->adminUser);
+
+    $this->setUpExampleStructure();
+    $this->insertExampleContent();
+    $this->assertEqual($this->indexItems($this->indexId), 5, '5 items were indexed.');
+    $this->insertExampleContent();
+    $this->assertEqual($this->indexItems($this->indexId), 5, '5 items were indexed.');
+
+    // Make absolutely sure the ::$blocks variable doesn't pass information
+    // along between tests.
+    $this->blocks = NULL;
+  }
+
+  /**
+   * Tests for admin processors..
+   */
+  public function testProcessorAdmin() {
+    $facet_name = "Guanaco";
+    $facet_id = "guanaco";
+
+    $this->createFacet($facet_name, $facet_id);
+
+    // Go to the processors form and check that the count limit processor is not
+    // checked.
+    $this->drupalGet('admin/config/search/facets/' . $facet_id . '/display');
+    $this->assertNoFieldChecked('edit-facet-settings-count-limit-status');
+
+    $form = ['facet_settings[count_limit][status]' => TRUE];
+    $this->drupalPostForm(NULL, $form, $this->t('Save'));
+    $this->assertResponse(200);
+    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
+
+    // Enable the sort processor and change sort direction.
+    // Test that the sort settings change persisted.
+    $form = [
+      'facet_sorting[active_widget_order][status]' => TRUE,
+      'facet_sorting[active_widget_order][settings][sort]' => 'DESC',
+    ];
+    $this->drupalPostForm(NULL, $form, $this->t('Save'));
+    $this->assertResponse(200);
+    $this->assertFieldChecked('edit-facet-sorting-active-widget-order-status');
+    $this->assertFieldChecked('edit-facet-sorting-active-widget-order-settings-sort-desc');
+
+    // Add an extra processor so we can test the weights as well.
+    $form = [
+      'facet_settings[hide_non_narrowing_result_processor][status]' => TRUE,
+      'facet_settings[count_limit][status]' => TRUE,
+    ];
+    $this->drupalPostForm(NULL, $form, $this->t('Save'));
+
+    $this->assertResponse(200);
+    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
+    $this->assertFieldChecked('edit-facet-settings-hide-non-narrowing-result-processor-status');
+    $this->assertOptionSelected('edit-processors-count-limit-weights-build', -10);
+    $this->assertOptionSelected('edit-processors-hide-non-narrowing-result-processor-weights-build', -10);
+
+    // Change the weight of one of the processors and test that the weight
+    // change persisted.
+    $form = [
+      'facet_settings[hide_non_narrowing_result_processor][status]' => TRUE,
+      'facet_settings[count_limit][status]' => TRUE,
+      'processors[hide_non_narrowing_result_processor][weights][build]' => 5,
+    ];
+    $this->drupalPostForm(NULL, $form, $this->t('Save'));
+    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
+    $this->assertFieldChecked('edit-facet-settings-hide-non-narrowing-result-processor-status');
+    $this->assertOptionSelected('edit-processors-count-limit-weights-build', -10);
+    $this->assertOptionSelected('edit-processors-hide-non-narrowing-result-processor-weights-build', 5);
+  }
+
+  /**
+   * Tests for processor integration.
+   */
+  public function testProcessorIntegration() {
+    $facet_name = "Vicuña";
+    $facet_id = "vicuna";
+    $this->editForm = 'admin/config/search/facets/' . $facet_id . '/display';
+
+    $this->createFacet($facet_name, $facet_id, 'keywords');
+    $this->createFacetBlock($facet_id);
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertText('grape');
+    $this->assertText('orange');
+    $this->assertText('apple');
+    $this->assertText('strawberry');
+    $this->assertText('banana');
+
+    $this->checkCountLimitProcessor();
+    $this->checkExcludeItems();
+    $this->checkHideNonNarrowingProcessor();
+  }
+
+  /**
+   * Tests for processor integration.
+   */
+  public function testSortingWidgets() {
+    $facet_name = "Huacaya alpaca";
+    $facet_id = "huacaya_alpaca";
+    $this->editForm = 'admin/config/search/facets/' . $facet_id . '/display';
+
+    $this->createFacet($facet_name, $facet_id, 'keywords');
+    $this->createFacetBlock($facet_id);
+
+    $this->checkSortByActive();
+    $this->checkSortByCount();
+    $this->checkSortByDisplay();
+  }
+
+  /**
+   * Tests the count limit processor.
+   */
+  private function checkCountLimitProcessor() {
+    $this->drupalGet($this->editForm);
+
+    $form = [
+      'widget_configs[show_numbers]' => TRUE,
+      'facet_settings[count_limit][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+    $this->assertResponse(200);
+    $this->assertFieldChecked('edit-facet-settings-count-limit-status');
+    $form = [
+      'widget_configs[show_numbers]' => TRUE,
+      'facet_settings[count_limit][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $form = [
+      'widget_configs[show_numbers]' => TRUE,
+      'facet_settings[count_limit][status]' => TRUE,
+      'facet_settings[count_limit][settings][minimum_items]' => 5,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertText('grape (6)');
+    $this->assertNoText('apple (4)');
+
+    $form = [
+      'widget_configs[show_numbers]' => TRUE,
+      'facet_settings[count_limit][status]' => TRUE,
+      'facet_settings[count_limit][settings][minimum_items]' => 1,
+      'facet_settings[count_limit][settings][maximum_items]' => 5,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertNoText('grape (6)');
+    $this->assertText('apple (4)');
+
+    $form = [
+      'widget_configs[show_numbers]' => FALSE,
+      'facet_settings[count_limit][status]' => FALSE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+  }
+
+  /**
+   * Tests the exclude items.
+   */
+  private function checkExcludeItems() {
+    $form = [
+      'facet_settings[exclude_specified_items][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $form = [
+      'facet_settings[exclude_specified_items][status]' => TRUE,
+      'facet_settings[exclude_specified_items][settings][exclude]' => 'banana',
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertText('grape');
+    $this->assertNoText('banana');
+
+    $form = [
+      'facet_settings[exclude_specified_items][status]' => TRUE,
+      'facet_settings[exclude_specified_items][settings][exclude]' => '(.*)berry',
+      'facet_settings[exclude_specified_items][settings][regex]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertNoText('strawberry');
+    $this->assertText('grape');
+
+    $form = [
+      'facet_settings[exclude_specified_items][status]' => FALSE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+  }
+
+  /**
+   * Tests hiding non-narrowing results.
+   */
+  private function checkHideNonNarrowingProcessor() {
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertLink('grape');
+
+    $this->clickLink('grape');
+    $this->assertText('Displaying 6 search results');
+    $this->assertLink('orange');
+
+    $form = [
+      'facet_settings[hide_non_narrowing_result_processor][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertText('Displaying 10 search results');
+    $this->assertLink('grape');
+
+    $this->clickLink('grape');
+    $this->assertText('Displaying 6 search results');
+    $this->assertNoLink('orange');
+
+    $form = [
+      'facet_settings[hide_non_narrowing_result_processor][status]' => FALSE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+  }
+
+  /**
+   * Tests the active widget order.
+   */
+  protected function checkSortByActive() {
+    $form = [
+      'facet_sorting[active_widget_order][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertXBeforeY('grape', 'strawberry');
+    $this->clickLink('strawberry');
+    $this->assertXBeforeY('(-) strawberry', 'grape');
+
+    $form = [
+      'facet_sorting[active_widget_order][status]' => TRUE,
+      'facet_sorting[active_widget_order][settings][sort]' => 'DESC',
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertXBeforeY('grape', 'strawberry');
+    $this->clickLink('strawberry');
+    $this->assertXBeforeY('grape', '(-) strawberry');
+
+    $form = [
+      'facet_sorting[active_widget_order][status]' => FALSE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+  }
+
+  /**
+   * Tests the active widget order.
+   */
+  protected function checkSortByCount() {
+    $form = [
+      'widget_configs[show_numbers]' => TRUE,
+      'facet_sorting[count_widget_order][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertXBeforeY('banana', 'apple');
+    $this->assertXBeforeY('banana', 'strawberry');
+    $this->assertXBeforeY('apple', 'orange');
+
+    $form = [
+      'facet_sorting[count_widget_order][status]' => TRUE,
+      'facet_sorting[count_widget_order][settings][sort]' => 'DESC',
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertXBeforeY('apple', 'banana');
+    $this->assertXBeforeY('strawberry', 'banana');
+    $this->assertXBeforeY('orange', 'apple');
+
+    $form = [
+      'widget_configs[show_numbers]' => FALSE,
+      'facet_sorting[count_widget_order][status]' => FALSE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+  }
+
+  /**
+   * Tests the display order.
+   */
+  public function checkSortByDisplay() {
+    $form = [
+      'facet_sorting[display_value_widget_order][status]' => TRUE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertXBeforeY('grape', 'strawberry');
+    $this->assertXBeforeY('apple', 'banana');
+
+    $form = [
+      'facet_sorting[display_value_widget_order][status]' => TRUE,
+      'facet_sorting[display_value_widget_order][settings][sort]' => 'DESC',
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+
+    $this->drupalGet('search-api-test-fulltext');
+    $this->assertXBeforeY('strawberry', 'grape');
+    $this->assertXBeforeY('banana', 'apple');
+
+    $form = [
+      'facet_sorting[display_value_widget_order][status]' => FALSE,
+    ];
+    $this->drupalPostForm($this->editForm, $form, $this->t('Save'));
+  }
+
+  /**
+   * Creates a facet block by id.
+   *
+   * @param string $id
+   *   The id of the block.
+   */
+  protected function createFacetBlock($id) {
+    $plugin_id = 'facet_block:' . $id;
+    $settings = [
+      'region' => 'footer',
+      'id' => str_replace('_', '-', $id),
+    ];
+    $this->blocks[$id] = $this->drupalPlaceBlock($plugin_id, $settings);
+  }
+
+}
