diff --git a/quora.module b/quora.module
index 7c1976a..5378157 100644
--- a/quora.module
+++ b/quora.module
@@ -2,9 +2,11 @@
 
 /**
  * @file
+ * Functions for Quora search support.
  */
 
 use Drupal\Core\Routing\RouteMatchInterface;
+
 /**
  * Implements hook_help().
  */
@@ -30,369 +32,3 @@ function quora_theme($existing, $type, $theme, $path) {
     ),
   );
 }
-
-/**
- * Builds Settings Form.
- */
-function _quora_settings_form($callby, &$form, $form_state = NULL, $conf = NULL) {
-  $form['quora_display_options'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Display Options'),
-  );
-  $form['quora_display_options']['quora_no_questions'] = array(
-    '#type' => 'select',
-    '#title' => t('Number of related questions to be shown'),
-    '#options' => array(
-      1 => '1',
-      2 => '2',
-      3 => '3',
-      4 => '4',
-      5 => '5',
-      6 => '6',
-      7 => '7',
-      8 => '8',
-    ),
-    '#default_value' => _quora_default($callby, 'no_questions', $conf),
-  );
-  $form['quora_display_options']['quora_description'] = array(
-    '#type' => 'select',
-    '#title' => t('Description with questions'),
-    '#options' => array(
-      'enable' => t('Enable'),
-      'disable' => t('Disable'),
-    ),
-    '#default_value' => _quora_default($callby, 'description', $conf),
-  );
-  $form['quora_display_options']['quora_description_size'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Limit Description text'),
-    '#description' => t('Enter size, 0 for no limit'),
-    '#element_validate' => array('element_validate_integer'),
-    '#default_value' => _quora_default($callby, 'description_size', $conf),
-    '#states' => array(
-      'visible' => array(
-        ':input[name="quora_description"]' => array('value' => 'enable'),
-      ),
-    ),
-  );
-  $form['quora_search_options'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Advanced Search Settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['quora_search_options']['quora_search_sensitivity'] = array(
-    '#type' => 'select',
-    '#title' => t('Search Sensitivity'),
-    '#options' => array(
-      0 => t('Auto'),
-      1 => t('3 Words'),
-      2 => t('5 Words'),
-      3 => t('7 Words'),
-      4 => t('Maximum'),
-    ),
-    '#default_value' => _quora_default($callby, 'search_sensitivity', $conf),
-  );
-  $form['quora_search_options']['quora_include'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Always include certain words'),
-    '#description' => t('Use comma to separate multiple words. (Case Insensitive)'),
-    '#default_value' => _quora_default($callby, 'include', $conf),
-  );
-  $form['quora_search_options']['quora_exclude'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Always exclude certain words'),
-    '#description' => t('Use comma to separate multiple words. (Case Insensitive)'),
-    '#default_value' => _quora_default($callby, 'exclude', $conf),
-  );
-}
-
-/**
- * Builds Quora Content form.
- */
-function _quora_build_content($callby, $node, $conf = NULL) {
-  $quora_tag_field = _quora_fetch_field($node);
-  $quora_tag_string = _quora_preprocess_tag_terms($callby, $node, $quora_tag_field, $conf);
-  _quora_filter_tag_terms($callby, $quora_tag_string, $conf);
-  $results = _quora_search_web($quora_tag_string);
-  if (!$results) {
-    drupal_set_message(t('No results were found'), 'error', FALSE);
-    return NULL;
-  }
-  return _quora_process_results($callby, $results, $conf);
-}
-
-/**
- * Returns field which will be used as tag field by quora.
- */
-function _quora_fetch_field($node) {
-  $mapped_field = \Drupal::config('quora.admin')->get('quora_' . $node->getType() . '_field');
-  $mapped_field_val = $node->{$mapped_field}->getValue();
-  $field_tags_val = $node->field_tags->getValue();
-  if (isset($mapped_field_val) && !empty($mapped_field_val)) {
-    return $mapped_field;
-  }
-  elseif (isset($field_tags_val) && !empty($field_tags_val)) {
-    return 'field_tags';
-  }
-  else {
-    return 'title';
-  }
-}
-
-/**
- * Returns array of preprocessed tags according to sensitivity.
- */
-function _quora_preprocess_tag_terms($callby, $node, $quora_tag_field, $conf = NULL) {
-  $data = $node->{$quora_tag_field}->getValue();
-  // Formation of Data string.
-  switch (gettype($data)) {
-    case 'string':
-      // Do nothing.
-      break;
-
-    case 'array':
-      $str = '';
-      if (isset($data[0]['value'])) {
-        $str = $data[0]['value'];
-      }
-      else {
-        foreach ($data as $term) {
-          if (isset($term->tid)) {
-            $str .= $term->name . ' ';
-          }
-        }
-      }
-      if ($str) {
-        $data = NULL;
-        $data = $str;
-      }
-      else {
-        \Drupal::logger('quora')->notice('Unsupported fieldtype selected as quora_tag_field',
-          array());
-        // Selecting title as quora_tag_field.
-        $data = $node->title->getValue();
-      }
-      break;
-
-    case 'object':
-      $str = '';
-      if (isset($data->type)) {
-        $str = _quora_preprocess_tag_terms($callby, $data, _quora_fetch_field($data));
-      }
-
-      if ($str) {
-        $data = NULL;
-        $data = $str;
-      }
-      else {
-        \Drupal::logger('quora')->notice('Unsupported fieldtype selected as quora_tag_field',
-          array());
-        // Selecting title as quora_tag_field.
-        $data = $node->title->getValue();
-      }
-      break;
-
-    default:
-      \Drupal::logger('quora')->notice('Unsupported fieldtype selected as quora_tag_field',
-        array());
-      // Selecting title as quora_tag_field.
-      $data = $node->title->getValue();
-      break;
-  }
-  return $data;
-}
-
-/**
- * Filters tag terms based on user defined options.
- */
-function _quora_filter_tag_terms($callby, &$data, $conf) {
-  // We have string in variable data.
-  $data = preg_replace('/[^\p{L}\p{N}\ ]/', '', $data);
-  $data = str_replace(_quora_preprocess_prepare_exclude_arr($callby, $conf), '', $data);
-  $data = _quora_preprocess_sensitivity($callby, $data, $conf);
-  $data .= ' ' . _quora_preprocess_prepare_include_arr($callby, $conf);
-  $data = preg_replace('/\s+/', ' ', $data);
-}
-
-/**
- * Helper function for preprocessor to build exclude list.
- */
-function _quora_preprocess_sensitivity($callby, $data, $conf = NULL) {
-  $terms = explode(' ', $data);
-  $count = count($terms);
-  switch (_quora_default($callby, 'search_sensitivity', $conf)) {
-
-    case 1:
-      // 3 Words.
-      if ($count > 3) {
-        $terms = array_slice($terms, 0, 3);
-      }
-      break;
-
-    case 2:
-      // 5 Words.
-      if ($count > 5) {
-        $terms = array_slice($terms, 0, 5);
-      }
-      break;
-
-    case 3:
-      // 7 Words.
-      if ($count > 7) {
-        $terms = array_slice($terms, 0, 7);
-      }
-      break;
-
-    default:
-      // Maximum words.
-      while ($count >= 10) {
-        $count = $count / 2;
-      }
-      $terms = array_slice($terms, 0, $count);
-      break;
-  }
-  return implode(' ', $terms);
-}
-
-/**
- * Helper function for preprocessor to build exclude list.
- */
-function _quora_preprocess_prepare_exclude_arr($callby, $conf = NULL) {
-  $ex = _quora_default($callby, 'exclude', $conf);
-  if ($ex) {
-    $ex = preg_replace('/[^\p{L}\p{N}\ \,]/', '', $ex);
-    $ex = explode(',', $ex);
-  }
-  return $ex;
-}
-
-/**
- * Helper function for preprocessor to build include string.
- */
-function _quora_preprocess_prepare_include_arr($callby, $conf = NULL) {
-  $in = _quora_default($callby, 'include', $conf);
-  if ($in) {
-    $in = preg_replace('/[^\p{L}\p{N}\ ]/', '', $in);
-  }
-  return $in;
-}
-
-/**
- * Search web using google and returns results.
- */
-function _quora_search_web($query) {
-  $query .= " site:quora.com";
-  $query = trim($query);
-
-  $config = \Drupal::config('quora.admin');
-
-  $api = $config->get('quora_google_cse_api');
-  $cx = $config->get('quora_google_cse_cx');
-  if ($api && $cx) {
-    // Use api to get results.
-    $gs_results = json_decode(@file_get_contents('https://www.googleapis.com/customsearch/v1?key=' . $api . '&cx=' . $cx . '&q=' . urlencode($query)));
-    if ($gs_results) {
-      foreach ($gs_results->items as $result) {
-        $q_results[] = array(
-          'title' => $result->title,
-          'snippet' => $result->snippet,
-          'url' => $result->link,
-        );
-      }
-      return $q_results;
-    }
-  }
-  // Else Use default ajax way to fetch results.
-  $gs_results = json_decode(@file_get_contents('http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=large&q=' . urlencode($query)));
-  if ($gs_results) {
-    foreach ($gs_results->responseData->results as $result) {
-      $q_results[] = array(
-        'title' => $result->titleNoFormatting,
-        'snippet' => strip_tags($result->content),
-        'url' => $result->url,
-      );
-    }
-  }
-  else {
-    \Drupal::logger('quora')->error('Unable to fetch results with query @query',
-      array(
-        '@query' => urlencode($query),
-      ));
-    return FALSE;
-  }
-  return $q_results;
-}
-
-/**
- * Process results array.
- */
-function _quora_process_results($callby, $results, $conf = NULL) {
-  $results = array_slice($results, 0, _quora_default($callby, 'no_questions', $conf));
-  // Preprocess description snippet to be displayed.
-  if (_quora_default($callby, 'description', $conf) == 'disable') {
-    foreach ($results as $key => $result) {
-      unset($results[$key]['snippet']);
-    }
-  }
-  else {
-    $size = _quora_default($callby, 'description_size', $conf);
-    if ($size) {
-      foreach ($results as $key => $result) {
-        $results[$key]['snippet'] = text_summary($result['snippet'], NULL, $size) . '..';
-      }
-    }
-  }
-
-  return $results;
-}
-
-/**
- * Returns a string for a variable name.
- *
- * Used by settings forms to retrieve strings.
- */
-function _quora_default($callby, $key, $conf = NULL) {
-  switch ($callby) {
-    case 'ctools':
-      $admin_setting = !empty($conf['quora_' . $key]) ? $conf['quora_' . $key] : FALSE;
-      break;
-
-    case 'block':
-      $admin_setting = \Drupal::config('quora.admin')->get('quora_' . $key);
-      break;
-  }
-  if ($admin_setting) {
-    // An admin setting overrides the default string.
-    $default = $admin_setting;
-  }
-  else {
-    // No override, return default string.
-    switch ($key) {
-      case 'no_questions':
-        $default = 3;
-        break;
-
-      case 'description':
-        $default = 'enable';
-        break;
-
-      case 'description_size':
-        $default = 0;
-        break;
-
-      case 'search_sensitivity':
-        $default = 0;
-        break;
-
-      case 'exclude':
-        $default = '';
-        break;
-
-      case 'include':
-        $default = '';
-        break;
-    }
-  }
-  return $default;
-}
diff --git a/quora.services.yml b/quora.services.yml
new file mode 100644
index 0000000..37a0d86
--- /dev/null
+++ b/quora.services.yml
@@ -0,0 +1,4 @@
+services:
+  quora.services:
+    class: Drupal\quora\QuoraDataProcess
+    arguments: ['@config.factory', '@logger.factory']
diff --git a/src/QuoraDataProcess.php b/src/QuoraDataProcess.php
new file mode 100644
index 0000000..d5b7b11
--- /dev/null
+++ b/src/QuoraDataProcess.php
@@ -0,0 +1,312 @@
+<?php
+
+namespace Drupal\quora;
+
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\node\Entity\Node;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Logger\LoggerChannelFactory;
+
+/**
+ * Quora data processing functions.
+ */
+class QuoraDataProcess implements ContainerFactoryPluginInterface {
+
+  /**
+   * The config object for 'quora.admin'.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  private $config;
+
+  /**
+   * Logger object.
+   *
+   * @var \Drupal\Core\Logger\LoggerChannelFactory
+   */
+  private $loggerChannelFactory;
+
+  /**
+   * QuoraDataProcess constructor.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
+   *   Config object.
+   * @param \Drupal\Core\Logger\LoggerChannelFactory $loggerChannelFactory
+   *   Logger Object.
+   */
+  public function __construct(ConfigFactoryInterface $configFactory, LoggerChannelFactory $loggerChannelFactory) {
+    $this->config = $configFactory->getEditable('quora.admin');
+    $this->loggerChannelFactory = $loggerChannelFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('logger.factory')
+    );
+  }
+
+  /**
+   * Builds result content for block.
+   *
+   * @param \Drupal\node\Entity\Node $node
+   *   Node object.
+   * @param array $conf
+   *   Display configuration values.
+   *
+   * @return array|null
+   *   Array of results.
+   */
+  public function buildContent(Node $node, array $conf) {
+    $quoraTagField = $this->fetchField($node);
+    $quoraTagString = $this->preprocessTagTerms($node, $quoraTagField);
+    $this->filterTagTerms($quoraTagString, $conf);
+    $results = $this->getResults($quoraTagString);
+    if (!$results) {
+      drupal_set_message(t('No results were found on Quora for the given set of keywords/tags.'), 'error', FALSE);
+      return NULL;
+    }
+    return $this->processResults($results, $conf);
+
+  }
+
+  /**
+   * Get results using Google CSE.
+   *
+   * @param string $query
+   *   String to search.
+   *
+   * @return array|bool
+   *   Results or FALSE.
+   */
+  public function getResults($query) {
+    // We want to make sure about search on quora.com domain.
+    $query .= " site:quora.com";
+    $query = trim($query);
+
+    $api = $this->config->get('google_cse_api');
+    $cx = $this->config->get('google_cse_cx');
+    if ($api && $cx) {
+      // Use api to get results.
+      $web_results = json_decode(@file_get_contents('https://www.googleapis.com/customsearch/v1?key=' . $api . '&cx=' . $cx . '&q=' . urlencode($query)));
+      if (property_exists($web_results, 'items')) {
+        foreach ($web_results->items as $result) {
+          $quora_results[] = array(
+            'title' => $result->title,
+            'snippet' => $result->snippet,
+            'url' => $result->link,
+          );
+        }
+        return $quora_results;
+      }
+    }
+    else {
+      $this->loggerChannelFactory->get('quora')->error('Unable to fetch results with query @query',
+        array(
+          '@query' => urlencode($query),
+        ));
+      return FALSE;
+    }
+
+  }
+
+  /**
+   * Returns field which will be used as tag field by quora.
+   *
+   * @param \Drupal\node\Entity\Node $node
+   *   Node object.
+   *
+   * @return string
+   *   Tag field.
+   */
+  public function fetchField(Node $node) {
+    $mappedField = $this->config->get($node->getType() . '_fields');
+    if ($mappedField == 'auto') {
+      return 'title';
+    }
+    elseif ($mappedField == 'field_tags') {
+      return 'field_tags';
+    }
+    $mappedFieldValue = $node->{$mappedField}->getValue();
+    if (isset($mappedFieldValue) && !empty($mappedFieldValue)) {
+      return $mappedField;
+    }
+  }
+
+  /**
+   * Returns array of preprocessed tags according to sensitivity.
+   *
+   * @param \Drupal\node\Entity\Node $node
+   *   Node object.
+   * @param string $quoraTagField
+   *   Tag field.
+   *
+   * @return null|string
+   *   Tag terms.
+   */
+  public function preprocessTagTerms(Node $node, $quoraTagField) {
+    if ($quoraTagField != 'field_tags') {
+      $data = $node->{$quoraTagField}->getValue();
+    }
+    else {
+      $data = $node->field_tags->referencedEntities();
+    }
+    // Formation of Data string.
+    switch (gettype($data)) {
+      case 'string':
+        // Do nothing.
+        break;
+
+      case 'array':
+        $str = '';
+        if (!is_object($data[0])) {
+          $str = $data[0]['value'];
+        }
+        else {
+          foreach ($data as $term) {
+            $str .= $term->getName() . ' ';
+          }
+        }
+        if ($str) {
+          $data = NULL;
+          $data = $str;
+        }
+        else {
+          $this->loggerChannelFactory->get('quora')->notice('Unsupported fieldtype selected as quoraTagField');
+          // Selecting title as quoraTagField.
+          $data = $node->title->getValue();
+        }
+        break;
+
+      case 'object':
+        $str = '';
+        if (isset($data->type)) {
+          $str = $this->preprocessTagTerms($data, $this->fetchField($data));
+        }
+
+        if ($str) {
+          $data = NULL;
+          $data = $str;
+        }
+        else {
+          $this->loggerChannelFactory->get('quora')->notice('Unsupported fieldtype selected as quoraTagField');
+          // Selecting title as quoraTagField.
+          $data = $node->title->getValue();
+        }
+        break;
+
+      default:
+        $this->loggerChannelFactory->get('quora')->notice('Unsupported fieldtype selected as quoraTagField');
+        // Selecting title as quoraTagField.
+        $data = $node->title->getValue();
+        break;
+    }
+    return $data;
+
+  }
+
+  /**
+   * Filter the tag terms based on user defined options.
+   *
+   * @param string $data
+   *   Tag terms.
+   * @param array $conf
+   *   Search configurations.
+   *
+   * @return string
+   *   Filtered tag terms.
+   */
+  public function filterTagTerms($data, array $conf) {
+    // We have string in variable data.
+    $data = preg_replace('/[^\p{L}\p{N}\ ]/', '', $data);
+    // Process exclude list.
+    $ex = $conf['exclude'];
+    if ($ex) {
+      $ex = preg_replace('/[^\p{L}\p{N}\ \,]/', '', $ex);
+      $ex = explode(',', $ex);
+    }
+    $data = str_replace($ex, '', $data);
+    $terms = explode(' ', $data);
+    $count = count($terms);
+    switch ($conf['search_sensitivity']) {
+
+      case 1:
+        // 3 Words.
+        if ($count > 3) {
+          $terms = array_slice($terms, 0, 3);
+        }
+        break;
+
+      case 2:
+        // 5 Words.
+        if ($count > 5) {
+          $terms = array_slice($terms, 0, 5);
+        }
+        break;
+
+      case 3:
+        // 7 Words.
+        if ($count > 7) {
+          $terms = array_slice($terms, 0, 7);
+        }
+        break;
+
+      default:
+        // Maximum words.
+        while ($count >= 10) {
+          $count = $count / 2;
+        }
+        $terms = array_slice($terms, 0, $count);
+        break;
+    }
+    $data = implode(' ', $terms);
+    // Process include string.
+    $in = $conf['include'];
+    if ($in) {
+      $in = preg_replace('/[^\p{L}\p{N}\ ]/', '', $in);
+    }
+    $data .= ' ' . $in;
+    $data = preg_replace('/\s+/', ' ', $data);
+    return $data;
+
+  }
+
+  /**
+   * Process results array.
+   *
+   * @param array $results
+   *   Search results.
+   * @param array $conf
+   *   Search configurations.
+   *
+   * @return array
+   *   Processed Results.
+   */
+  public function processResults(array $results, array $conf) {
+    $results = array_slice($results, 0, $conf['no_questions']);
+    // Preprocess description snippet to be displayed.
+    if ($conf['description'] == 'disable') {
+      foreach ($results as $key => $result) {
+        unset($results[$key]['snippet']);
+      }
+    }
+    else {
+      $size = $conf['description_size'];
+      if ($size) {
+        foreach ($results as $key => $result) {
+          $results[$key]['snippet'] = text_summary($result['snippet'], NULL, $size) . '..';
+        }
+      }
+    }
+
+    return $results;
+  }
+
+}
