diff --git a/config/install/workflow_notifications.settings.yml b/config/install/workflow_notifications.settings.yml
index c26e5c1..898d6fd 100644
--- a/config/install/workflow_notifications.settings.yml
+++ b/config/install/workflow_notifications.settings.yml
@@ -1 +1 @@
-last_run_date: 1511772856
\ No newline at end of file
+last_run_date: 1511772856
diff --git a/config/schema/workflow_notifications.schema.yml b/config/schema/workflow_notifications.schema.yml
index 4a3b130..cf8b6f9 100644
--- a/config/schema/workflow_notifications.schema.yml
+++ b/config/schema/workflow_notifications.schema.yml
@@ -11,15 +11,15 @@ workflow_notifications.workflow_notify.*:
     label:
       type: string
       label: 'Label'
-    workflow_type:
+    wid:
       type: string
       label: 'Workflow Type'
-    from_state:
+    from_sid:
       type: string
-      label: 'From State'
-    to_state:
+      label: 'From State ID'
+    to_sid:
       type: string
-      label: 'To State'
+      label: 'To State ID'
     when_to_trigger:
       type: string
       label: 'When To Trigger'
@@ -28,17 +28,16 @@ workflow_notifications.workflow_notify.*:
       label: 'Days'
     roles:
       type: sequence
-      label: 'Roles'
+      label: 'User roles'
       sequence:
         type: 'string'
-        label: 'role'
+        label: 'Role'
     mail_ids:
       type: string
-      label: 'Mail Ids'
+      label: 'Email IDs'
     subject:
       type: string
       label: 'Subject'
     message:
       type: text_format
       label: 'Message'
-          
\ No newline at end of file
diff --git a/js/workflow_notifications.js b/js/workflow_notifications.js
deleted file mode 100644
index a844f07..0000000
--- a/js/workflow_notifications.js
+++ /dev/null
@@ -1,17 +0,0 @@
-(function ($) {
-    $(document).ready(function(){
-        if($("input[type=radio][name='when_to_trigger']:checked").val() == 'on_state_change') {
-            $('.time').parent().hide();
-        }
-        $('.whn-to-trggr').click(function(){
-            if($(this).is(':checked')) {
-                if($(this).val() == 'on_state_change') {
-                    $('.time').parent().hide();
-                }
-                else {
-                    $('.time').parent().show();
-                }
-            }
-        });
-    });
-})(jQuery);
diff --git a/src/Controller/WorkflowNotificationListBuilder.php b/src/Controller/WorkflowNotificationListBuilder.php
new file mode 100644
index 0000000..47b38de
--- /dev/null
+++ b/src/Controller/WorkflowNotificationListBuilder.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\workflow_notifications\Controller;
+
+use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\workflow_notifications\Entity\WorkflowNotification;
+
+/**
+ * Class WorkflowNotificationListBuilder
+ */
+class WorkflowNotificationListBuilder extends ConfigEntityListBuilder {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildHeader() {
+    $header['label'] = $this->t('Label');
+    $header['from_sid'] = $this->t('From State');
+    $header['to_sid'] = $this->t('To State');
+    $header['when_to_trigger'] = $this->t('When To Trigger');
+    $header += parent::buildHeader();
+    return $header;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildRow(EntityInterface $entity) {
+    $row = [];
+
+    /** @var $entity WorkflowNotification */
+    $wid = workflow_url_get_workflow()->id();
+    if ($wid <> $entity->getWorkflowId()) {
+      return $row;
+    }
+
+    $row['label'] = $entity->label();
+    $row['from_sid'] = $entity->from_sid;
+    $row['to_sid'] = $entity->to_sid;
+    $row['when_to_trigger'] = $entity->when_to_trigger;
+    $row += parent::buildRow($entity);
+    return $row;
+  }
+
+}
diff --git a/src/Controller/WorkflowNotificationsListBuilder.php b/src/Controller/WorkflowNotificationsListBuilder.php
deleted file mode 100644
index d396067..0000000
--- a/src/Controller/WorkflowNotificationsListBuilder.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-namespace Drupal\workflow_notifications\Controller;
-
-use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
-use Drupal\Core\Entity\EntityInterface;
-
-class WorkflowNotificationsListBuilder extends ConfigEntityListBuilder {
-  
-  public function buildHeader() {
-    $header['label'] = $this->t('Example');
-    $header['from_state'] = $this->t('From State');
-    $header['to_state'] = $this->t('To State');
-    $header['when_to_trigger'] = $this->t('When To Trigger');
-    return $header + parent::buildHeader();
-  }
-
-  public function buildRow(EntityInterface $entity) {
-    if(\Drupal::request()->get('workflow_type') == $entity->workflow_type) {
-      $row['label'] = $this->getLabel($entity);
-      $row['from_state'] = $entity->from_state;
-      $row['to_state'] = $entity->to_state;
-      $row['when_to_trigger'] = $entity->when_to_trigger;
-      return $row + parent::buildRow($entity);
-    }
-  }
-  
-}
\ No newline at end of file
diff --git a/src/Entity/WorkflowNotification.php b/src/Entity/WorkflowNotification.php
new file mode 100644
index 0000000..5d62361
--- /dev/null
+++ b/src/Entity/WorkflowNotification.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace Drupal\workflow_notifications\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\workflow\WorkflowTypeAttributeTrait;
+
+/**
+ *  Defines a Workflow Notification entity
+ *
+ * @ConfigEntityType(
+ *   id = "workflow_notify",
+ *   label = @Translation("Workflow Notification"),
+ *   handlers = {
+ *     "access" = "Drupal\workflow_notifications\WorkflowNotificationControlHandler",
+ *     "list_builder" = "Drupal\workflow_notifications\Controller\WorkflowNotificationListBuilder",
+ *     "form" = {
+ *       "add" = "Drupal\workflow_notifications\Form\WorkflowNotificationForm",
+ *       "edit" = "Drupal\workflow_notifications\Form\WorkflowNotificationForm",
+ *       "delete" = "Drupal\Core\Entity\EntityDeleteForm",
+ *     },
+ *   },
+ *   config_prefix = "workflow_notify",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "wid" = "wid",
+ *     "from_sid" = "from_sid",
+ *     "to_sid" = "to_sid",
+ *     "when_to_trigger" = "when_to_trigger",
+ *     "time" = "time",
+ *     "mail_to" = "mail_to",
+ *   },
+ *   config_export = {
+ *     "id",
+ *     "label",
+ *     "wid",
+ *     "from_sid",
+ *     "to_sid",
+ *     "when_to_trigger",
+ *     "days",
+ *     "roles",
+ *     "mail_ids",
+ *     "subject",
+ *     "message",
+ *   },
+ *   links = {
+ *     "edit-form" = "/admin/config/workflow/workflow/{workflow_type}/notifications/{workflow_notify}/edit",
+ *     "delete-form" = "/admin/config/workflow/workflow/{workflow_type}/notifications/{workflow_notify}/delete",
+ *     "collection" = "/admin/config/workflow/workflow/{workflow_type}/notifications",
+ *   },
+ * )
+ */
+class WorkflowNotification extends ConfigEntityBase implements WorkflowNotificationInterface {
+
+  /*
+   * Add variables and get/set methods for Workflow property.
+   */
+  use WorkflowTypeAttributeTrait;
+
+  public $id;
+  public $label;
+
+  public $from_sid;
+  public $to_sid;
+  public $when_to_trigger = 'on_state_change';
+  public $days;
+  public $roles = [];
+  public $mail_ids = [];
+  public $subject;
+  public $message = ['value' => '', 'format' => 'basic_html',];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function loadMultipleByProperties($from_sid, $to_sid, $wid, $trigger, $days) {
+    $result = \Drupal::entityQuery("workflow_notify");
+    $from_state = $result->orConditionGroup()
+      ->condition('from_sid', $from_sid, '=')
+      ->condition('from_sid', 'any', '=');
+    $to_state = $result->orConditionGroup()
+      ->condition('to_sid', $to_sid, '=')
+      ->condition('to_sid', 'any', '=');
+    $result->condition($from_state)
+      ->condition($to_state)
+      ->condition('wid', $wid, '=')
+      ->condition('when_to_trigger', $trigger, '=');
+    if (!empty($days)) {
+      $result->condition('days', $days, '=');
+    }
+
+    $ids = $result->execute();
+    $workflow_notifications = self::loadMultiple($ids);
+    return $workflow_notifications;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function urlInfo($rel = 'canonical', array $options = []) {
+    // This function is deprecated, so add modification in other function.
+    return $this::toUrl($rel, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function toUrl($rel = 'canonical', array $options = []) {
+    // Perhaps this can be done in routing.yml file.
+    $url = parent::toUrl($rel, $options);
+    $url->setRouteParameter('workflow_type', $this->getWorkflowId());
+    return $url;
+  }
+
+}
diff --git a/src/Entity/WorkflowNotificationInterface.php b/src/Entity/WorkflowNotificationInterface.php
new file mode 100644
index 0000000..c1c19e0
--- /dev/null
+++ b/src/Entity/WorkflowNotificationInterface.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\workflow_notifications\Entity;
+
+use Drupal\workflow\Entity\Workflow;
+
+/**
+ *  Defines a Workflow Notification entity
+ *
+ * @package Drupal\workflow_notifications\Entity
+ */
+interface WorkflowNotificationInterface {
+
+  /**
+   * Returns the Workflow ID of this object.
+   *
+   * @return string
+   *   Workflow Id.
+   */
+  public function getWorkflowId();
+
+  /**
+   * Returns the Workflow object of this object.
+   *
+   * @return Workflow
+   *   Workflow object.
+   */
+  public function getWorkflow();
+
+  /**
+   * @param Workflow $workflow
+   */
+  public function setWorkflow(Workflow $workflow);
+
+  /**
+   * Load WorkflowNotification Id's.
+   *
+   * @param string $from_sid
+   * @param string $to_sid
+   * @param string $wid
+   * @param string $trigger
+   * @param integer $days
+   *
+   * @return WorkflowNotification[]
+   *   An array of Notifications.
+   */
+  public static function loadMultipleByProperties($from_sid, $to_sid, $wid, $trigger, $days);
+
+}
diff --git a/src/Entity/WorkflowNotifications.php b/src/Entity/WorkflowNotifications.php
deleted file mode 100644
index 50eb7f4..0000000
--- a/src/Entity/WorkflowNotifications.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-namespace Drupal\workflow_notifications\Entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\workflow_notifications\WorkflowNotificationsInterface;
-
-/**
- *  Defines workflow notify entity
- * @ConfigEntityType(
- *  id = "workflow_notify",
- *  label = @Translation("Workflow Notify"),
- *  handlers = {
- *      "access" = "Drupal\workflow_notifications\WorkflowNotificationControlHandler",
- *      "list_builder" = "Drupal\workflow_notifications\Controller\WorkflowNotificationsListBuilder",
- *      "form" = {
- *          "add" = "Drupal\workflow_notifications\Form\WorkflowNotificationForm",
- *          "edit" = "Drupal\workflow_notifications\Form\WorkflowNotificationForm",
- *          "delete" = "Drupal\workflow_notifications\Form\WorkflowNotificationDeleteForm",
- *      },
- *  },
- *  config_prefix = "workflow_notify",
- *  entity_keys = {
- *      "id" = "id",
- *      "label" = "label",
- *      "workflow_type" = "workflow_type",
- *      "from_state" = "from_state",
- *      "to_state" = "to_state",
- *      "when_to_trigger" = "when_to_trigger",
- *      "time" = "time",
- *      "mail_to" = "mail_to",
- *  },
- *  config_export = {
- *      "id",
- *      "label",
- *      "workflow_type",
- *      "from_state",
- *      "to_state",
- *      "when_to_trigger",
- *      "days",
- *      "roles",
- *      "mail_ids",
- *      "subject",
- *      "message",
- *  },
- *  links = {
- *      "edit-form" = "/mail/{workflow_notify}/edit",
- *      "delete-form" = "/mail/{workflow_notify}/delete",
- *      "collection" = "/admin/config/workflow/workflow/{workflow_type}/mail",
- *  },
- *)
- **/
-
-
-class WorkflowNotifications extends ConfigEntityBase implements WorkflowNotificationsInterface {
-    public $label;
-    public $id;
-    public $from_state;
-    public $to_state;
-    public $when_to_trigger;
-    public $days;
-    public $roles;
-    public $mail_ids;
-    public $subject;
-    public $message;
-}
diff --git a/src/Form/WorkflowNotificationDeleteForm.php b/src/Form/WorkflowNotificationDeleteForm.php
deleted file mode 100644
index 3851c13..0000000
--- a/src/Form/WorkflowNotificationDeleteForm.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-namespace Drupal\workflow_notifications\Form;
-
-use Drupal\Core\Entity\EntityConfirmFormBase;
-use Drupal\Core\Url;
-use Drupal\Core\Form\FormStateInterface;
-
-class WorkflowNotificationDeleteForm extends EntityConfirmFormBase {
-  public function getQuestion() {
-    return $this->t('Are you sure you want to delete %name?', array('%name' => $this->entity->label()));
-  }
-  
-  public function getCancelUrl() {
-    return Url::fromRoute('entity.workflow_notify.collection', array('workflow_type' => $this->entity->workflow_type));
-    return new Url('entity.workflow_notify.collection');
-  }
-
-  public function getConfirmText() {
-    return $this->t('Delete');
-  }
-
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $this->entity->delete();
-    drupal_set_message($this->t('Notification %label has been deleted.', array('%label' => $this->entity->label())));
-    $form_state->setRedirectUrl($this->getCancelUrl());
-  }
-}
\ No newline at end of file
diff --git a/src/Form/WorkflowNotificationForm.php b/src/Form/WorkflowNotificationForm.php
index 4f2d3e6..ee4bbcd 100644
--- a/src/Form/WorkflowNotificationForm.php
+++ b/src/Form/WorkflowNotificationForm.php
@@ -4,196 +4,208 @@ namespace Drupal\workflow_notifications\Form;
 
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Entity\Query\QueryFactory;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\workflow\Entity\Workflow;
-use Drupal\user\RoleInterface;
-
+use Drupal\workflow\WorkflowTypeAttributeTrait;
+use Drupal\workflow_notifications\Entity\WorkflowNotification;
 
+/**
+ * Class WorkflowNotificationForm
+ */
 class WorkflowNotificationForm extends EntityForm {
-    protected $workflow_id;
-
-  public function __construct(QueryFactory $entity_query) {
-    $this->entityQuery = $entity_query;
-  }
-
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('entity.query')
-    );
-  }
+  /*
+   * Add variables and get/set methods for Workflow property.
+   */
+  use WorkflowTypeAttributeTrait;
 
+  /**
+   * {@inheritdoc}
+   */
   public function form(array $form, FormStateInterface $form_state) {
     $form = parent::form($form, $form_state);
 
-    $workflow_notify = $this->entity;
-    
-    $roles = array_filter(\Drupal\user\Entity\Role::loadMultiple(), function (RoleInterface $role) {
-        return !in_array($role->id(), [
-            RoleInterface::ANONYMOUS_ID,
-            RoleInterface::AUTHENTICATED_ID,
-        ], TRUE);
-        });
-        $role_options = array_map(function (RoleInterface $role) {
-        return $role->label();
-        }, $roles);
-
-    $this->workflow_id = \Drupal::request()->get('workflow_type');
-    if(isset($this->workflow_id) && !empty($this->workflow_id)) {
-        $workflow_type = $this->workflow_id;
-    }
-    else if(isset($workflow_notify->workflow_type)) {
-        $workflow_type = $workflow_notify->workflow_type;
-    }
-    $workflow = Workflow::load($workflow_type);
+    /** @var WorkflowNotification $workflow_notification */
+    $workflow_notification = $this->entity;
+
+    $workflow = workflow_url_get_workflow();
+    $this->setWorkflow($workflow);
+
+    $role_options = workflow_get_user_role_names('');
+    unset($role_options['anonymous']);
+
     $state_options = ['any' => 'Any State'];
-    foreach($workflow->getStates() as $entity => $entity_value) {
-        $state_options[$entity_value->id()] = $entity_value->label();
-    }
-    $days = array();
-    $days[0] = '-None-';
-    for($i=1;$i<=31;$i++){
-        $days[$i] = $i . ' Days';
+    $state_options += workflow_get_workflow_state_names($workflow->id(), FALSE);
+
+    $days_options = [];
+    $days_options[0] = '-None-';
+    for ($i = 1; $i <= 31; $i++) {
+      $days_options[$i] = $i . ' Days';
     }
-    $form['#attached']['library'][] = 'workflow_notifications/workflow_notifications';
-    $form['label'] = array(
-            '#type' => 'textfield',
-            '#title' => $this->t('Label'),
-            '#default_value' => $workflow_notify->label(),
-            '#required' => TRUE,
-    );
-    $form['id'] = array(
+
+    $form['label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Label'),
+      '#default_value' => $workflow_notification->label(),
+      '#required' => TRUE,
+    ];
+    $form['id'] = [
       '#type' => 'machine_name',
-      '#default_value' => $workflow_notify->id(),
-      '#machine_name' => array(
-        'exists' => array($this, 'exist'),
-      ),
-      '#disabled' => !$workflow_notify->isNew(),
-    );
-    $form['workflow_type'] = array(
-        '#type' => 'hidden',
-        '#default_value' => isset($workflow_type)? $workflow_type: "",
-    );
-    $form['from_state'] = array(
-            '#type' => 'select',
-            '#title' => t('From State'),
-            '#options' => $state_options,
-            '#default_value' => $workflow_notify->from_state,
-            '#required' => TRUE,
-        );
-        $form['to_state'] = array(
-            '#type' => 'select',
-            '#title' => t('To State'),
-            '#options' => $state_options,
-            '#default_value' => $workflow_notify->to_state,
-            '#required' => TRUE,
-        );
-        $form['when_to_trigger'] = array(
-            '#type' => 'radios',
-            '#title' => t('When To Trigger'),
-            '#options' => array('on_state_change' => t('On State Change'), 'before_state_change' => t('Before State Change')),
-            '#default_value' => ($workflow_notify->when_to_trigger)? $workflow_notify->when_to_trigger : 'on_state_change',
-            '#required' => TRUE,
-            '#attributes' => array(
-                'class' => array('whn-to-trggr'),
-            ),
-        );
-        $form['days'] = array(
-            '#type' => 'select',
-            '#title' => t('Days'),
-            '#options' => $days,
-            '#default_value' => $workflow_notify->days,
-            '#attributes' => [
-                'class' => ['time'],
-            ],
-        );
-        $form['mail_to'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Mail To'),
-            '#collapsible' => TRUE,
-        );
-        $form['mail_to']['roles'] = array(
-            '#type' => 'checkboxes',
-            '#options' => $role_options,
-            '#title' => t('Roles'),
-            '#default_value' => $workflow_notify->roles,
-        );
-        $form['mail_to']['mail_ids'] = array(
-            '#type' => 'textarea',
-            '#title' => t('MailID'),
-            '#default_value' => $workflow_notify->mail_ids,
-        );
-        $form['template'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Template'),
-            '#collapsible' => TRUE,
-        );
-        $form['template']['subject'] = array(
-            '#type' => 'textfield',
-            '#title' => t('Subject'),
-            '#default_value' => $workflow_notify->subject,
-            '#required' => TRUE,
-        );
-        $form['template']['message'] = array(
-            '#type' => 'text_format',
-            '#title' => t('Message'),
-            '#default_value' => $workflow_notify->message['value'],
-            '#format' => isset($workflow_notify->message['format'])? $workflow_notify->message['format'] :'basic_html',
-            '#required' => TRUE,
-        );
-        $form['note']  = [
-            '#type' => 'markup',
-            '#markup' => t("<b>Note:</b> Token can be available in the listed fields - MailID, Subject, Message"),
-        ]; 
-        // Token support.
-        if (\Drupal::moduleHandler()->moduleExists('token')) {
-            $form['tokens'] = [
-                '#title' => $this->t('Tokens'),
-                '#type' => 'container',
-                '#states' => [
-                'invisible' => [
-                    'input[name="use_token"]' => ['checked' => FALSE],
-                ],
-                ],
-            ];
-            $form['tokens']['help'] = [
-                '#theme' => 'token_tree_link',
-                '#token_types' => ['node', 'workflow_transition', 'workflow_scheduled_transition', 'term', 'site', 'paragraph', 'comment'],
-                // '#token_types' => 'all'
-                '#global_types' => FALSE,
-                '#dialog' => TRUE,
-            ];
-        }
-        return $form;
+      '#default_value' => $workflow_notification->id(),
+      '#machine_name' => [
+        'exists' => [$this, 'exists'],
+      ],
+      '#disabled' => !$workflow_notification->isNew(),
+    ];
+    $form['wid'] = [
+      '#type' => 'hidden',
+      '#default_value' => $this->getWorkflowId(),
+    ];
+    $form['from_sid'] = [
+      '#type' => 'select',
+      '#title' => t('From State'),
+      '#options' => $state_options,
+      '#default_value' => $workflow_notification->from_sid,
+      '#required' => TRUE,
+    ];
+    $form['to_sid'] = [
+      '#type' => 'select',
+      '#title' => t('To State'),
+      '#options' => $state_options,
+      '#default_value' => $workflow_notification->to_sid,
+      '#required' => TRUE,
+    ];
+    $form['when_to_trigger'] = [
+      '#type' => 'radios',
+      '#title' => t('When to trigger'),
+      '#options' => ['on_state_change' => t('On State change'), 'before_state_change' => t('Before State change')],
+      '#default_value' => $workflow_notification->when_to_trigger,
+      '#description' => t('Determine when the message nust be sent:
+        a) directoy upon a state change, or
+        b) some days before a state change (using scheduled transitions).'),
+      '#required' => TRUE,
+      '#attributes' => [
+        'class' => ['when-to-trigger'],
+      ],
+    ];
+    $form['days'] = [
+      '#type' => 'select',
+      '#title' => t('Days'),
+      '#options' => $days_options,
+      '#default_value' => $workflow_notification->days,
+      '#description' => t('Enter the number of days before a transition is scheduled, a message must be sent.'),
+      '#attributes' => [
+        'class' => ['time'],
+      ],
+      '#states' => [
+        'invisible' => [
+          'input[name="when_to_trigger"]' => ['value' => 'on_state_change'],
+        ],
+      ],
+    ];
+    $form['mail_to'] = [
+      '#type' => 'fieldset',
+      '#title' => t('Mail To'),
+      '#collapsible' => TRUE,
+    ];
+    $form['mail_to']['roles'] = [
+      '#type' => 'checkboxes',
+      '#options' => $role_options,
+      '#title' => t('Roles'),
+      '#default_value' => $workflow_notification->roles,
+      '#description' => t('Check each role that must be informed.'),
+    ];
+    // @todo: add validation for email adresses.
+    $form['mail_to']['mail_ids'] = [
+      '#type' => 'textarea',
+      '#title' => t('Email adresses'),
+      '#default_value' => $workflow_notification->mail_ids,
+      '#description' => t('Enter a valid Email address, one per line.'),
+    ];
+    $form['template'] = [
+      '#type' => 'fieldset',
+      '#title' => t('Template'),
+      '#collapsible' => TRUE,
+    ];
+    $form['template']['subject'] = [
+      '#type' => 'textfield',
+      '#title' => t('Subject'),
+      '#default_value' => $workflow_notification->subject,
+      '#required' => TRUE,
+    ];
+    $form['template']['message'] = [
+      '#type' => 'text_format',
+      '#title' => t('Message'),
+      '#default_value' => $workflow_notification->message['value'],
+      '#format' => $workflow_notification->message['format'],
+      '#required' => TRUE,
+    ];
+    $form['note'] = [
+      '#type' => 'markup',
+      '#markup' => t("<b>Note:</b> Token can be available in the listed fields - MailID, Subject, Message"),
+    ];
+
+    // Token support.
+    if (\Drupal::moduleHandler()->moduleExists('token')) {
+      $form['tokens'] = [
+        '#title' => $this->t('Tokens'),
+        '#type' => 'container',
+        '#states' => [
+          'invisible' => [
+            'input[name="use_token"]' => ['checked' => FALSE],
+          ],
+        ],
+      ];
+      $form['tokens']['help'] = [
+        '#theme' => 'token_tree_link',
+        '#token_types' => ['node', 'workflow_transition', 'workflow_scheduled_transition', 'term', 'site', 'paragraph', 'comment'],
+        // '#token_types' => 'all'
+        '#global_types' => FALSE,
+        '#dialog' => TRUE,
+      ];
+    }
+
+    return $form;
   }
-   function validateForm(array &$form, FormStateInterface $form_state) {
-        $form_values = $form_state->getValues();
-        if($form_values['when_to_trigger'] == 'on_state_change') {
-            $form_state->setValue('days',0);
-        }
+
+  /**
+   * {@inheritdoc}
+   */
+  function validateForm(array &$form, FormStateInterface $form_state) {
+    $form_values = $form_state->getValues();
+    if ($form_values['when_to_trigger'] == 'on_state_change') {
+      $form_state->setValue('days', 0);
+    }
   }
+
+  /**
+   * {@inheritdoc}
+   */
   public function save(array $form, FormStateInterface $form_state) {
-    $workflow_notify = $this->entity;
-    $status = $workflow_notify->save();
+    $workflow_notification = $this->entity;
+    $status = parent::save($form, $form_state);
 
     if ($status) {
-      drupal_set_message($this->t('Saved the %label workflow notify.', array(
-        '%label' => $workflow_notify->label(),
-      )));
+      drupal_set_message($this->t('Saved the %label workflow notify.', [
+        '%label' => $workflow_notification->label(),
+      ]));
     }
     else {
-      drupal_set_message($this->t('The %label workflow notify was not saved.', array(
-        '%label' => $workflow_notify->label(),
-      )));
+      drupal_set_message($this->t('The %label workflow notify was not saved.', [
+        '%label' => $workflow_notification->label(),
+      ]));
     }
 
-    $form_state->setRedirect('entity.workflow_notify.collection', ['workflow_type' => $this->workflow_id]);
+    $form_state->setRedirect('entity.workflow_notify.collection', ['workflow_type' => $this->getWorkflowId()]);
   }
 
-  public function exist($id) {
-    $entity = $this->entityQuery->get('workflow_notify')
-      ->condition('id', $id)
-      ->execute();
-    return (bool) $entity;
+  /**
+   * Helper function for machine_name element.
+   *
+   * @param $id
+   *   The given machine name.
+   * @return bool
+   *   Indicates if the machine name already exists.
+   */
+  public function exists($id) {
+    $type = $this->entity->getEntityTypeId();
+    return (bool) $this->entityTypeManager->getStorage($type)->load($id);
   }
 }
\ No newline at end of file
diff --git a/src/Plugin/QueueWorker/ScheduleMailQueue.php b/src/Plugin/QueueWorker/ScheduleMailQueue.php
index 4a40cde..28836f9 100644
--- a/src/Plugin/QueueWorker/ScheduleMailQueue.php
+++ b/src/Plugin/QueueWorker/ScheduleMailQueue.php
@@ -1,33 +1,29 @@
 <?php
 
-/**
- * @file \Drupal\workflow_notifications\Plugin\QueueWorker\ScheduleMailQueue.
- **/
+namespace Drupal\workflow_notifications\Plugin\QueueWorker;
+
+use Drupal\Core\Queue\QueueWorkerBase;
 
- namespace Drupal\workflow_notifications\Plugin\QueueWorker;
- 
- use Drupal\Core\Queue\QueueWorkerBase;
- 
- /**
-  * process mail to the scheduled entities.
-  *
-  *@QueueWorker(
-  *     id = "workflow_scheduled_entity_mail",
-  *     title = @Translation("Workflow mail trigger for scheduled entities."),
-  *     cron = {"time" = 60}
-  *)
-  **/
+/**
+ * process mail to the scheduled entities.
+ *
+ * @QueueWorker(
+ *   id = "workflow_scheduled_entity_mail",
+ *   title = @Translation("Workflow mail trigger for scheduled entities."),
+ *   cron = {"time" = 60},
+ * )
+ */
+class ScheduleMailQueue extends QueueWorkerBase {
 
-  class ScheduleMailQueue extends QueueWorkerBase {
-      /**
-       * {@inheritdoc}
-       **/
-       public function processItem($entity) {           
-             $day = $entity->days? $entity->days: 0;
-             if(!empty($day)) {
-                 $starttime = strtotime("+" . $day . " days 12:00:00 am");
-                 $endtime = strtotime("+" . $day . " days 11:59:59 pm");
-                 send_mail_to_all($starttime, $endtime, $entity);
-             }
-       }
-  }
\ No newline at end of file
+  /**
+   * {@inheritdoc}
+   */
+  public function processItem($notification) {
+    $day = $notification->days ? $notification->days : 0;
+    if (!empty($day)) {
+      $start_time = strtotime("+" . $day . " days 12:00:00 am");
+      $end_time = strtotime("+" . $day . " days 11:59:59 pm");
+      _workflow_notifications_send_mail_to_all($start_time, $end_time, $notification);
+    }
+  }
+}
diff --git a/src/WorkflowNotificationControlHandler.php b/src/WorkflowNotificationControlHandler.php
index 2343024..45ec0dd 100644
--- a/src/WorkflowNotificationControlHandler.php
+++ b/src/WorkflowNotificationControlHandler.php
@@ -2,35 +2,47 @@
 
 namespace Drupal\workflow_notifications;
 
+use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Entity\EntityAccessControlHandler;
 use Drupal\Core\Entity\EntityHandlerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Access\AccessResult;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
+/**
+ * Provides a control handler for Workflow Notifications.
+ */
 class WorkflowNotificationControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
 
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+  /**
+   * {@inheritdoc}
+   */
+  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
     return new static(
       $entity_type
     );
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
-            switch($operation) {
-                case 'update':
-                    return AccessResult::allowed();
-                break;
-                case 'delete':
-                    return AccessResult::allowed();
-                break;
-            }
+    switch ($operation) {
+      case 'update':
+        return AccessResult::allowed();
+        break;
+      case 'delete':
+        return AccessResult::allowed();
+        break;
+    }
   }
 
+  /**
+   * {@inheritdoc}
+   */
   protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
-    return AccessResult::allowedIfHasPermission($account, 'create workflow notifications');
+    return AccessResult::allowedIfHasPermission($account, 'administer workflow');
   }
 
 }
\ No newline at end of file
diff --git a/src/WorkflowNotificationsInterface.php b/src/WorkflowNotificationsInterface.php
deleted file mode 100644
index 362371d..0000000
--- a/src/WorkflowNotificationsInterface.php
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-
-namespace Drupal\workflow_notifications;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-
-interface WorkflowNotificationsInterface extends ConfigEntityInterface {
-    
-}
\ No newline at end of file
diff --git a/workflow_notifications.libraries.yml b/workflow_notifications.libraries.yml
deleted file mode 100644
index 261ef8f..0000000
--- a/workflow_notifications.libraries.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-workflow_notifications:
-    js:
-        js/workflow_notifications.js: {}
-        
\ No newline at end of file
diff --git a/workflow_notifications.links.action.yml b/workflow_notifications.links.action.yml
index c1387c8..1883539 100644
--- a/workflow_notifications.links.action.yml
+++ b/workflow_notifications.links.action.yml
@@ -1,5 +1,5 @@
 entity.workflow_notify.add:
   route_name: 'entity.workflow_notify.add'
-  title: 'Add Mail'
+  title: 'Add Notification'
   appears_on:
     - entity.workflow_notify.collection
diff --git a/workflow_notifications.module b/workflow_notifications.module
index b8fdfc6..4336b0a 100644
--- a/workflow_notifications.module
+++ b/workflow_notifications.module
@@ -1,240 +1,250 @@
 <?php
 
-use Drupal\workflow\Entity\WorkflowScheduledTransition;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\workflow_notifications\Entity\WorkflowNotifications;
+use Drupal\workflow\Entity\WorkflowScheduledTransition;
+use Drupal\workflow\Entity\WorkflowTransitionInterface;
+use Drupal\workflow_notifications\Entity\WorkflowNotification;
+
+/**
+ * Implements hook_entity_update().
+ * sending on state change mail.
+ */
+function workflow_notifications_entity_update(EntityInterface $entity) {
+  // Avoid this hook on workflow objects.
+  if (\Drupal\workflow\Entity\WorkflowManager::isWorkflowEntityType($entity->getEntityTypeId())) {
+    return;
+  }
+
+  foreach (_workflow_info_fields($entity) as $field_info) {
+    $field_name = $field_info->getName();
+    /** @var $transition WorkflowTransitionInterface */
+    $transition = $entity->$field_name->__get('workflow_transition');
+    if (empty($transition)) {
+      continue;
+    }
+
+    // @todo: hide below code in WorkflowNotification::loadMultiple()?
+    $from_sid = $transition->getFromSid();
+    $to_sid = $transition->getToSid();
+    $wid = $transition->getWorkflowId();
+    $days = 0;
+
+    $state_changed = ($from_sid != $to_sid);
+    if (!$state_changed) {
+      continue;
+    }
+
+    // Default select parameters for non-scheduled transitions.
+    $trigger = 'on_state_change';
+    if ($transition->isScheduled()) {
+      $trigger = 'before_state_change';
+
+      $timestamp = $transition->getTimestamp();
+      if (!empty($timestamp)) {
+        $date = explode('-', date('d-m-y', $timestamp));
+        $current_date = explode('-', date('d-m-y', \Drupal::time()->getRequestTime()));
+        if ($date[1] == $current_date[1] && $date[2] == $current_date[2]) {
+          if ($date[0] > $current_date[0]) {
+            $days = $date[0] - $current_date[0];
+          }
+        }
+      }
+    }
+    // $todo: use $transitions as parameter, and derive $trigger from that.
+    $notifications = WorkflowNotification::loadMultipleByProperties($from_sid, $to_sid, $wid, $trigger, $days);
+    if (!empty($notifications)) {
+      _workflow_notifications_mail_trigger($trigger, $notifications, $entity, $transition);
+    }
+
+  }
+}
 
 /**
  * Implements hook_cron().
+ *
  * sending remainder mail.
  **/
 function workflow_notifications_cron() {
+  workflow_debug('', __FUNCTION__, __LINE__);
+
   $config = \Drupal::service('config.factory')->getEditable('workflow_notifications.settings');
-  if(date('d', $config->get('last_run_date')) != date('d')) {
-    // queue to send mail
-    $result = Drupal::entityQuery("workflow_notify")->condition('when_to_trigger','before_state_change','=')->execute();
-    foreach($result as $row => $value) {         
-         $entity = WorkflowNotifications::load($row);
-         $queue = \Drupal::queue('workflow_scheduled_entity_mail');
-         $queue->createItem($entity);   
+  if (date('d', $config->get('last_run_date')) != date('d')) {
+    // queue to send mail.
+    // @todo: use $notifications[] = WorkflowNotification::LoadByProperties()
+    $result = Drupal::entityQuery("workflow_notify")->condition('when_to_trigger', 'before_state_change', '=')->execute();
+    foreach ($result as $key => $value) {
+      $entity = WorkflowNotification::load($key);
+      $queue = \Drupal::queue('workflow_scheduled_entity_mail');
+      $queue->createItem($entity);
     }
-    $config->set('last_run_date', REQUEST_TIME)->save();
+    $config->set('last_run_date', \Drupal::time()->getRequestTime())->save();
   }
 }
 
 /**
-* send mail to all users.
-**/
-
-    function send_mail_to_all($starttime, $endtime, $value) {          
-        $query_publish = \Drupal::database()->select('workflow_transition_schedule', 'ws')->fields('ws');
-        $query_publish->condition('ws.timestamp', array($starttime, $endtime), 'BETWEEN');
-        $query_publish->condition('ws.from_sid', $value->from_state, '=');
-        if($value->to_state != 'any') {
-          $query_publish->condition('ws.to_sid', $value->to_state, '=');
-        }
-        $result_publish = $query_publish->execute()->fetchAll();
-        foreach($result_publish as $row => $val) {          
-          $entity = entity_load($val->entity_type, $val->entity_id);
-          $field = _workflow_info_fields($entity, $val->entity_type);
-          $fieldName = $field[key($field)]->getName();
-          $transition = WorkflowScheduledTransition::loadByProperties($val->entity_type, $val->entity_id, array(), $fieldName);
-          $arrroles = $value->roles;
-          $tkn_rpl_val = token_replace($value->mail_ids, $value->message['value'], $value->subject, $entity, $transition);
-          $arrmailids = get_value_as_array($tkn_rpl_val['mailids']);
-          $to = collect_mail_ids($entity, $arrroles, $arrmailids);
-          $params['subject'] = $tkn_rpl_val['subject'];                 
-          $params['message'] = $tkn_rpl_val['message'];
-          $key = 'workflow_notification_before_mail_trigger';
-          mail_send($to, $params, $key);
-        }
-    }
-
- /**
-  * returns array from string.
-  **/
+ * Implements hook_mail_alter().
+ */
+function workflow_notifications_mail_alter(&$message) {
+  workflow_debug('', __FUNCTION__, __LINE__);
+}
 
-  function get_value_as_array($value) {
-    $values = "\r\n" . $value;
-    $arrval = array_filter(preg_split('/\r\n|[\r\n]/', $values));
-    return $arrval;
-  }
+/**
+ * Implements hook_mail().
+ */
+function workflow_notifications_mail($key, &$message, $params) {
+  workflow_debug('', __FUNCTION__, __LINE__);
+
+  $options = [
+    'langcode' => $message['langcode'],
+  ];
+  $from = Drupal::config('system.site')->get('mail');
+  $message['from'] = $from;
+  $message['subject'] = $params['subject'];
+  $message['body'][] = $params['message'];
+  $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
+}
 
-  
- /**
-  * Implements token replace.
-  **/
-
-   function token_replace($mailids, $message, $subject, $entity, $scheduled_transition) { 
-        $token_service = \Drupal::token();
-        $tkn_rpl_val = array();
-        $tkn_rpl_val['mailids'] = $token_service->replace($mailids, array('comment' => $entity, 'node' => $entity, 'term' => $entity, 'media' => $entity, 'paragraph' => $entity, 'workflow_transition' => $scheduled_transition,'workflow_scheduled_transition' => $scheduled_transition));
-        $tkn_rpl_val['message'] = $token_service->replace($message, array('comment' => $entity, 'node' => $entity, 'term' => $entity, 'media' => $entity, 'paragraph' => $entity, 'workflow_transition' => $scheduled_transition,'workflow_scheduled_transition' => $scheduled_transition));
-        $tkn_rpl_val['subject'] = $token_service->replace($subject, array('comment' => $entity, 'node' => $entity, 'term' => $entity, 'media' => $entity, 'paragraph' => $entity, 'workflow_transition' => $scheduled_transition,'workflow_scheduled_transition' => $scheduled_transition));
-        return $tkn_rpl_val;
-   }
-  
 /**
- * get all mailids.
- **/
+ * Internal helper function. No hook.
+ */
+function _workflow_notifications_mail_trigger($trigger, $notifications, $entity, $transition) {
+  if (empty($notifications)) {
+    return;
+  }
 
+  // Set key for mail. @todo: use $transition->isScheduled() instead?  Or use a Factory.
+  $key = '';
+  $key = ($trigger == 'on_state_change') ? 'workflow_notification_on_state_change_mail_trigger' : $key;
+  $key = ($trigger == 'before_state_change') ? 'workflow_notification_before_state_change_mail_trigger' : $key;
+
+  foreach ($notifications as $id => $notification) {
+    /** @var WorkflowNotification $notifications */
+    $roles = $notification->roles;
+    $tkn_rpl_val = _workflow_notifications_token_replace($notification->mail_ids, $notification->message['value'], $notification->subject, $entity, $transition);
+    $mail_ids = _workflow_notifications_get_value_as_array($tkn_rpl_val['mail_ids']);
+    $to = _workflow_notifications_collect_mail_ids($roles, $mail_ids);
+    $params['subject'] = $tkn_rpl_val['subject'];
+    $params['message'] = $tkn_rpl_val['message'];
+    _workflow_notifications_mail_send($to, $params, $key);
+  }
+}
 
- function collect_mail_ids($entity, $roles, $mailids) {
-    $result_mailids = array();
-    if($roles) {
-      foreach($roles as $r => $role) {
-        $user_storage = \Drupal::service('entity_type.manager')->getStorage('user');
-        $ids = $user_storage->getQuery()
-                ->condition('status', 1)
-                ->condition('roles', $role, 'IN')
-                ->execute();
-        $users = $user_storage->loadMultiple($ids);
-        foreach($users as $row => $val) {
-            $result_mailids[] = $val->getEmail();
-        }
-      }
-    }
-    if($mailids) {
-      foreach($mailids as $row => $mail) {   
-        $result_mailids[] = $mail;     
-      }
-    }
-    return $result_mailids;
- }
- 
-
- /**
-  * send mail.
-  **/
-
- function mail_send($to, $params, $key) {
-   $mailManager = \Drupal::service('plugin.manager.mail');
-   $langcode = \Drupal::currentUser()->getPreferredLangcode();
-   $send = true;
-   $module = 'workflow_notifications';
-   $to = implode(', ', $to);
-   $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
-   if ($result['result'] !== true) {
-    \Drupal::logger('workflow-mail-log')->error("There was a problem sending your message and it was not sent.");
-    drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
+/**
+ * send mail to all users.
+ * @param $start_time
+ * @param $end_time
+ * @param $notification
+ */
+function _workflow_notifications_send_mail_to_all($start_time, $end_time, $notification) {
+  workflow_debug('', __FUNCTION__, __LINE__);
+
+  // @todo: use WorkflowScheduledTransition::loadBetween();
+  $query_publish = \Drupal::database()->select('workflow_transition_schedule', 'ws')->fields('ws');
+  $query_publish->condition('ws.timestamp', [$start_time, $end_time], 'BETWEEN');
+  $query_publish->condition('ws.from_sid', $notification->from_sid, '=');
+  if ($notification->to_sid != 'any') {
+    $query_publish->condition('ws.to_sid', $notification->to_sid, '=');
   }
-  else {
-    \Drupal::logger('workflow-mail-log')->notice("Mail Sent Successfully to ". $to);
-    drupal_set_message(t('Mail Sent Successfully.'));
+  $result_publish = $query_publish->execute()->fetchAll();
+
+  $key = 'workflow_notification_before_mail_trigger';
+  foreach ($result_publish as $row => $val) {
+    $entity = entity_load($val->entity_type, $val->entity_id);
+    $field = _workflow_info_fields($entity, $val->entity_type);
+    $fieldName = $field[key($field)]->getName();
+    // @todo: next line has no effect.
+    $transition = WorkflowScheduledTransition::loadByProperties($val->entity_type, $val->entity_id, [], $fieldName);
+    $roles = $notification->roles;
+    $tkn_rpl_val = _workflow_notifications_token_replace($notification->mail_ids, $notification->message['value'], $notification->subject, $entity, $transition);
+    $mail_ids = _workflow_notifications_get_value_as_array($tkn_rpl_val['mail_ids']);
+    $to = _workflow_notifications_collect_mail_ids($roles, $mail_ids);
+    $params['subject'] = $tkn_rpl_val['subject'];
+    $params['message'] = $tkn_rpl_val['message'];
+    _workflow_notifications_mail_send($to, $params, $key);
   }
- }
+}
 
- 
 /**
- * Implements hook_entity_update().
- * sending on state change mail.
+ * returns array from string.
+ * @param $value
+ * @return array
  */
-function workflow_notifications_entity_update(EntityInterface $entity) {
-  // Avoid this hook on workflow objects.
-  if (!in_array($entity->getEntityTypeId(), [
-    'workflow_type',
-    'workflow_state',
-    'workflow_config_transition',
-    'workflow_transition',
-    'workflow_scheduled_transition',
-    'workflow_notify',
-  ])) {
-    $days = 0;
-    foreach (_workflow_info_fields($entity) as $field_info) {
-      $field_name = $field_info->getName();
-      /* @var $transition WorkflowTransitionInterface */
-      $transition = $entity->$field_name->__get('workflow_transition');
-      if(!empty($transition)) {
-        $frm_sid = $transition->getFromSid();
-        $to_sid = $transition->getToSid();
-        $workflow_type = $transition->getWorkflowId();
-        if(!$transition->isScheduled()) {
-              $state_changed = ($frm_sid != $to_sid);
-              if($state_changed) {
-                $state = 'on_state_change';
-                $result = get_workflow_notifications($frm_sid, $to_sid, $workflow_type, $state, $days);
-                if(!empty($result)) {
-                  $key = 'workflow_notification_on_state_change_mail_trigger';
-                  workflow_mail_trigger($state, $result, $entity, $key, $transition);
-                }
-            }      
-        }
-        else if($transition->isScheduled()) {
-          $timestamp = $transition->getTimestamp();
-          if(!empty($timestamp)) {
-            $date = explode('-',date('d-m-y',$timestamp));
-            $current_date = explode('-', date('d-m-y', REQUEST_TIME));
-            if($date[1] == $current_date[1] && $date[2] == $current_date[2]) {
-              if($date[0] > $current_date[0]) {
-                $days = $date[0]-$current_date[0];
-                $state = 'before_state_change';
-                $result = get_workflow_notifications($frm_sid, $to_sid, $workflow_type, $state, $days);
-                if(!empty($result)) {
-                  $key = 'workflow_notification_before_state_change_mail_trigger';
-                  workflow_mail_trigger($state, $result, $entity, $key, $transition);
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
+function _workflow_notifications_get_value_as_array($value) {
+  $values = "\r\n" . $value;
+  $result = array_filter(preg_split('/\r\n|[\r\n]/', $values));
+  return $result;
 }
 
- /**
-  * get mail workflow_notifications_cron.
-  **/
-
- function get_workflow_notifications($frm_sid, $to_sid, $workflow_type, $state, $days) {
-    $result = Drupal::entityQuery("workflow_notify");
-    $fromstate = $result->orConditionGroup()
-        ->condition('from_state',$frm_sid,'=')
-        ->condition('from_state','any','=');
-    $tostate = $result->orConditionGroup()
-        ->condition('to_state',$to_sid,'=')
-        ->condition('to_state','any','=');
-    $result->condition($fromstate)
-           ->condition($tostate)
-           ->condition('workflow_type',$workflow_type,'=')
-           ->condition('when_to_trigger',$state,'=');
-   if(!empty($days)) {
-     $result->condition('days', $days, '=');
-   }
-   $value = $result->execute();
-   return $value;
- }
- 
 /**
- * workflow mail trigger.
- **/
+ * Implements token replace.
+ */
+function _workflow_notifications_token_replace($mail_ids, $message, $subject, $entity, $transition) {
+  $token_service = \Drupal::token();
+  $tkn_rpl_val = [];
+  $tkn_rpl_val['mail_ids'] = $token_service->replace($mail_ids, ['comment' => $entity, 'node' => $entity, 'term' => $entity, 'media' => $entity, 'paragraph' => $entity, 'workflow_transition' => $transition, 'workflow_scheduled_transition' => $transition]);
+  $tkn_rpl_val['message'] = $token_service->replace($message, ['comment' => $entity, 'node' => $entity, 'term' => $entity, 'media' => $entity, 'paragraph' => $entity, 'workflow_transition' => $transition, 'workflow_scheduled_transition' => $transition]);
+  $tkn_rpl_val['subject'] = $token_service->replace($subject, ['comment' => $entity, 'node' => $entity, 'term' => $entity, 'media' => $entity, 'paragraph' => $entity, 'workflow_transition' => $transition, 'workflow_scheduled_transition' => $transition]);
+  return $tkn_rpl_val;
+}
+
+/**
+ * Get all mail adresses.
+ *
+ * Add the role-defined adresses t the user-specified adresses.
+ */
+function _workflow_notifications_collect_mail_ids($roles, $mail_ids) {
 
- function workflow_mail_trigger($state, $result, $entity, $key, $scheduled_transition) {
-  if(!empty($result)) {
-    foreach($result as $row => $v) {
-      $value = WorkflowNotifications::load($row);
-      $arrroles = $value->roles;
-      $tkn_rpl_val = token_replace($value->mail_ids, $value->message['value'], $value->subject, $entity, $scheduled_transition);
-      $arrmailids = get_value_as_array($tkn_rpl_val['mailids']);
-      $to = collect_mail_ids($entity, $arrroles, $arrmailids); 
-      $params['subject'] = $tkn_rpl_val['subject'];                 
-      $params['message'] = $tkn_rpl_val['message'];
-      mail_send($to, $params, $key);
+  if ($roles) {
+    foreach ($roles as $role_id => $role) {
+      if ($role == '0') {
+        continue;
+      }
+
+      // @todo: the selection upon role is not working.
+      $ids = \Drupal::entityQuery('user')
+        ->condition('status', 1)
+        ->condition('roles', $role)
+        ->execute();
+//      $group = $query->orConditionGroup()
+//        ->condition('roles', 'managers')
+//        ->condition('roles', 'administrator');
+//      $ids = $query->condition($group)->execute();
+
+      $user_storage = \Drupal::service('entity_type.manager')->getStorage('user');
+      $ids = $user_storage->getQuery()
+        ->condition('status', 1)
+ // @todo       ->condition('roles', $role, 'IN')
+        ->execute();
+
+      $users = $user_storage->loadMultiple($ids);
+//      $users = \Drupal\user\Entity\User::loadMultiple($ids);
+
+      foreach ($users as $key => $user) {
+        $mail_ids[] = $user->getEmail();
+      }
     }
   }
- }
 
+  $mail_ids = array_unique($mail_ids);
+  return $mail_ids;
+}
 
 /**
- * Implements hook_mail().
- **/
-function workflow_notifications_mail($key, &$message , $params) {
-    $options = array(
-        'langcode' => $message['langcode'],
-    );
-    $from = Drupal::config('system.site')->get('mail');
-    $message['from'] = $from;
-    $message['subject'] = $params['subject'];
-    $message['body'][] = $params['message'];
-    $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
-}
\ No newline at end of file
+ * send mail.
+ */
+function _workflow_notifications_mail_send($to, $params, $key) {
+  $mailManager = \Drupal::service('plugin.manager.mail');
+  $langcode = \Drupal::currentUser()->getPreferredLangcode();
+  $send = true;
+  $module = 'workflow_notifications'; // @todo: use DEFINE CONSTANT.
+  $to = implode(', ', $to);
+  $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
+  if ($result['result'] !== true) {
+    \Drupal::logger('workflow-mail-log')->error("There was a problem sending your message and it was not sent.");
+    drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
+  }
+  else {
+    \Drupal::logger('workflow-mail-log')->notice("Email sent successfully to " . $to);
+    drupal_set_message(t('Email sent successfully.'));
+  }
+}
diff --git a/workflow_notifications.permissions.yml b/workflow_notifications.permissions.yml
deleted file mode 100644
index e59cbdb..0000000
--- a/workflow_notifications.permissions.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-administer workflow notifications:
-  title: Administer workflow notifications
-  description: Administer workflow notifications listing page
-create workflow notifications:
-  title: Create workflow notify
-  title: Create workflow notification mail
diff --git a/workflow_notifications.routing.yml b/workflow_notifications.routing.yml
index 775f5cc..1bdeaa4 100644
--- a/workflow_notifications.routing.yml
+++ b/workflow_notifications.routing.yml
@@ -1,5 +1,5 @@
 entity.workflow_notify.add:
-  path: '/admin/config/workflow/workflow/{workflow_type}/add'
+  path: '/admin/config/workflow/workflow/{workflow_type}/notifications/add'
   defaults:
     _entity_form: 'workflow_notify.add'
     _title: 'Add Workflow Notification'
@@ -9,7 +9,7 @@ entity.workflow_notify.add:
     _entity_create_access: 'workflow_notify'
     
 entity.workflow_notify.edit_form:
-  path: '/mail/{workflow_notify}/edit'
+  path: '/admin/config/workflow/workflow/{workflow_type}/notifications/{workflow_notify}/edit'
   defaults:
     _entity_form: 'workflow_notify.edit'
     _title: 'Edit Workflow Notification'
@@ -22,22 +22,24 @@ entity.workflow_notify.edit_form:
     _entity_access: 'workflow_notify.update'
 
 entity.workflow_notify.delete_form:
-  path: '/mail/{workflow_notify}/delete'
+  path: '/admin/config/workflow/workflow/{workflow_type}/notifications/{workflow_notify}/delete'
   defaults:
     _entity_form: 'workflow_notify.delete'
     _title: 'Delete workflow Notification'
   options:
     _admin_route: TRUE
+    parameters:
+      entity:
+        type: entity:{entity_type}
   requirements:
     _entity_access: 'workflow_notify.delete'
 
 entity.workflow_notify.collection:
-  path: '/admin/config/workflow/workflow/{workflow_type}/mail'
+  path: '/admin/config/workflow/workflow/{workflow_type}/notifications'
   defaults:
     _entity_list: 'workflow_notify'
     _title: 'Manage Workflow Notifications'
   options:
     _admin_route: TRUE
   requirements:
-    _permission: 'administer workflow notifications'
-
+    _permission: 'administer workflow'
diff --git a/workflow_notifications.tokens.inc b/workflow_notifications.tokens.inc
index 6897523..e7e7548 100644
--- a/workflow_notifications.tokens.inc
+++ b/workflow_notifications.tokens.inc
@@ -7,106 +7,117 @@ use Drupal\workflow\Entity\WorkflowState;
  * Implements hook_token_info().
  **/
 
- function workflow_notifications_token_info() {
-     $types['workflow_state'] = [
-        'name' => t('Workflow State'),
-        'description' => t('Token for the workflow state entity'),
-        'needs-data' => 'workflow_state',
-     ];
-     $ws['id'] = [
-        'name' => t('State ID'),
-        'description' => t('Machine name of the state'),
-     ];
-     $ws['label'] = [
-        'name' => t('Label'),
-        'description' => t('State name')
-     ];
-     $ws['wid'] = [
-        'name' => t('workflow ID'),
-        'description' => t('ID of the Workflow'),
-     ];
-     return [
-        'types' => $types,
-        'tokens' => ['workflow_state' => $ws],
-     ];
- }
+function workflow_notifications_token_info() {
+  $types['workflow_state'] = [
+    'name' => t('Workflow State'),
+    'description' => t('Token for the workflow state entity'),
+    'needs-data' => 'workflow_state',
+  ];
+  $ws['id'] = [
+    'name' => t('State ID'),
+    'description' => t('Machine name of the state'),
+  ];
+  $ws['label'] = [
+    'name' => t('Label'),
+    'description' => t('State name'),
+  ];
+  $ws['wid'] = [
+    'name' => t('workflow ID'),
+    'description' => t('ID of the Workflow'),
+  ];
+  return [
+    'types' => $types,
+    'tokens' => ['workflow_state' => $ws],
+  ];
+}
 
 
- /**
+/**
  * Implements hook_tokens().
+ * @param $type
+ * @param $tokens
+ * @param array $data
+ * @param array $options
+ * @param BubbleableMetadata $bubbleable_metadata
+ *
+ * @return array
  */
- function workflow_notifications_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
-    $token_service = \Drupal::token();
-    $url_options = ['absolute' => TRUE];
+function workflow_notifications_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
+  $replacements = [];
+
+  if ($type == 'workflow_state' && !empty($data['workflow_state'])) {
+    $ws = $data['workflow_state'];
+    foreach ($tokens as $name => $original) {
+      switch ($name) {
+        case 'id':
+          $replacements[$original] = $ws->id;
+          break;
+        case 'label':
+          $replacements[$original] = $ws->label;
+          break;
+        case 'wid':
+          $replacements[$original] = $ws->wid;
+          break;
+      }
+    }
+  }
+
+  if (!empty($data['field_property'])) {
     if (isset($options['langcode'])) {
-        $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
-        $langcode = $options['langcode'];
+      $url_options = ['absolute' => TRUE];
+      $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
+      $langcode = $options['langcode'];
     }
     else {
-        $langcode = NULL;
+      $langcode = NULL;
     }
-    $replacements = [];  
-    if($type == 'workflow_state' && !empty($data['workflow_state']))  {
-        $ws = $data['workflow_state'];
-        foreach ($tokens as $name => $original) {
-            switch($name) {
-                case 'id':
-                    $replacements[$original] = $ws->id;
-                break;
-                case 'label':
-                    $replacements[$original] = $ws->label;
-                break;
-                case 'wid':
-                    $replacements[$original] = $ws->wid;
-                break;
-            }
+
+    $token_service = \Drupal::token();
+    foreach ($tokens as $token => $original) {
+      $filtered_tokens = $tokens;
+      $delta = 0;
+      $parts = explode(':', $token);
+      if (is_numeric($parts[0])) {
+        if (count($parts) > 1) {
+          $delta = $parts[0];
+          $property_name = $parts[1];
+          // Pre-filter the tokens to select those with the correct delta.
+          $filtered_tokens = \Drupal::token()->findWithPrefix($tokens, $delta);
+          // Remove the delta to unify between having and not having one.
+          array_shift($parts);
         }
-    }
-    if (!empty($data['field_property'])) {
-        foreach ($tokens as $token => $original) {
-            $filtered_tokens = $tokens;
-            $delta = 0;
-            $parts = explode(':', $token);
-            if (is_numeric($parts[0])) {
-                if (count($parts) > 1) {
-                    $delta = $parts[0];
-                    $property_name = $parts[1];
-                    // Pre-filter the tokens to select those with the correct delta.
-                    $filtered_tokens = \Drupal::token()->findWithPrefix($tokens, $delta);
-                    // Remove the delta to unify between having and not having one.
-                    array_shift($parts);
-                }
-                else {
-                    // Token is fieldname:delta, which is invalid.
-                    continue;
-                }
-            }
-            else {
-                $property_name = $parts[0];
-            }
-            if (isset($data[$data['field_name']][$delta])) {
-                $field_item = $data[$data['field_name']][$delta];
-            }
-            else {
-                // The field has no such delta, abort replacement.
-                continue;
-            }
-            if (isset($field_item->$property_name) && ($field_item->$property_name instanceof WorkflowState)) {
-                // Entity reference field.
-                $entity = $field_item->$property_name;
-                // Obtain the referenced entity with the correct language.
-                $entity = \Drupal::service('entity.repository')->getTranslationFromContext($entity, $langcode);
-                 if (count($parts) > 1) {
-                    $field_tokens = $token_service->findWithPrefix($filtered_tokens, $property_name);
-                    $token_type = \Drupal::service('token.entity_mapper')->getTokenTypeForEntityType($entity->getEntityTypeId(), TRUE);
-                    $replacements += $token_service->generate($token_type, $field_tokens, [$token_type => $entity], $options, $bubbleable_metadata);
-                }
-                else {
-                    $replacements[$original] = $entity->label();
-                }
-            }
+        else {
+          // Token is fieldname:delta, which is invalid.
+          continue;
+        }
+      }
+      else {
+        $property_name = $parts[0];
+      }
+      if (isset($data[$data['field_name']][$delta])) {
+        $field_item = $data[$data['field_name']][$delta];
+      }
+      else {
+        // The field has no such delta, abort replacement.
+        continue;
+      }
+      if (isset($field_item->$property_name) && ($field_item->$property_name instanceof WorkflowState)) {
+        // Entity reference field.
+        $entity = $field_item->$property_name;
+        // Obtain the referenced entity with the correct language.
+
+        $entity = \Drupal::service('entity.repository')->getTranslationFromContext($entity, $langcode);
+        if (count($parts) > 1) {
+          $field_tokens = $token_service->findWithPrefix($filtered_tokens, $property_name);
+          $token_type = \Drupal::service('token.entity_mapper')->getTokenTypeForEntityType($entity->getEntityTypeId(), TRUE);
+          $replacements += $token_service->generate($token_type, $field_tokens, [$token_type => $entity], $options, $bubbleable_metadata);
+        }
+        else {
+          $replacements[$original] = $entity->label();
         }
+      }
     }
-    return $replacements;
+  }
+  return $replacements;
 
- }
\ No newline at end of file
+}
\ No newline at end of file
